有人问到RubiksCube怎么加互动材质的问题,抽空做了一下,需要注意的地方写在注释里了。
查看示例 | 下载(需要类库的去我之前那篇里面找)

跳转后查看详细代码。

package demo.papervision3d
{
	import gs.TweenLite;
	import gs.easing.Elastic;
 
	import com.kvc.extend.papervision3d.RubiksCube;
 
	import org.papervision3d.core.math.Quaternion;
	import org.papervision3d.events.InteractiveScene3DEvent;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.view.BasicView;
 
	import flash.display.Bitmap;
	import flash.display.StageQuality;
	import flash.events.*;
 
	/**
	 * @author Kevin Cao
	 */
	[SWF(width="1000", height="600", backgroundColor="#cccccc", frameRate="30")]
	public class RubiksCubeDemo2 extends BasicView
	{
 
		private var rubiksCube : RubiksCube;
 
		[Embed(source="../../../assets/front.jpg")]
		private var FrontAsset : Class;
 
		[Embed(source="../../../assets/back.jpg")]
		private var BackAsset : Class;
 
		[Embed(source="../../../assets/left.jpg")]
		private var LeftAsset : Class;
 
		[Embed(source="../../../assets/right.jpg")]
		private var RightAsset : Class;
 
		[Embed(source="../../../assets/top.jpg")]
		private var TopAsset : Class;
 
		[Embed(source="../../../assets/bottom.jpg")]
		private var BottomAsset : Class;
 
		private var isDown : Boolean = false;
 
		private var _x : Number;
		private var _y : Number;
 
		private var _vx : Number = 0;
		private var _vy : Number = 0;
 
		public function RubiksCubeDemo2()
		{
			init();
		}
 
		protected function init() : void
		{
			// viewport's interactive set to true.
			viewport.interactive = true;
 
			camera.z = -1500;
			camera.focus = 200;
			camera.zoom = 2;
 
			var frontMat : BitmapMaterial = new BitmapMaterial((new FrontAsset() as Bitmap).bitmapData);
			var backtMat : BitmapMaterial = new BitmapMaterial((new BackAsset() as Bitmap).bitmapData);
			var leftMat : BitmapMaterial = new BitmapMaterial((new LeftAsset() as Bitmap).bitmapData);
			var rightMat : BitmapMaterial = new BitmapMaterial((new RightAsset() as Bitmap).bitmapData);
			var topMat : BitmapMaterial = new BitmapMaterial((new TopAsset() as Bitmap).bitmapData);
			var bottomMat : BitmapMaterial = new BitmapMaterial((new BottomAsset() as Bitmap).bitmapData);
 
			// material's interactive set to true.
			frontMat.interactive = backtMat.interactive = leftMat.interactive = rightMat.interactive = topMat.interactive = bottomMat.interactive = true;
 
			rubiksCube = new RubiksCube(RubiksCube.createMaterialListArray(frontMat, backtMat, leftMat, rightMat, topMat, bottomMat));
 
			// IMPORTANT: add event listener to each child cube rather than rubikscube object itself.
			for(var i : uint = 0;i < 26; i++)
			{
				rubiksCube.getChildByName("cube" + (i + 1)).addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, clickHandler);
			}
 
			scene.addChild(rubiksCube);
 
			startRendering();
 
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
 
			stage.quality = StageQuality.LOW;
		}
 
		override protected function onRenderTick(evt : Event = null) : void
		{
			if(!isDown)
			{
				if(_vx != 0 || _vy != 0)
				{
					_vx *= .9;
					_vy *= .9;
					if(Math.abs(_vx) < .5)
					{
						_vx = 0;
					}
					if(Math.abs(_vy) < .5)
					{
						_vy = 0;
					}
					var q : Quaternion = Quaternion.createFromEuler(-_vx, 0, -_vy, true);
					rubiksCube.transform.calculateMultiply3x3(q.matrix, rubiksCube.transform);
				}
			}
 
			super.onRenderTick();
		}
 
		private function keyUpHandler(evt : KeyboardEvent) : void
		{
			var command : String = String.fromCharCode(evt.charCode);
			switch(command)
			{
				//default command
				case "l":
				case "r":
				case "u":
				case "d":
				case "f":
				case "b":
					if(evt.ctrlKey && evt.altKey)
					{
						// reverse
						rubiksCube.singleRotate(command + "'");
					} else {
						rubiksCube.singleRotate(command);
					}
					break;
 
				//combo command
				case "1":
					rubiksCube.comboRotate("l-u-b'-d-r'", 2);
					break;
				case "2":
					rubiksCube.comboRotate("r-d'-b-u'-l'", 2);
					break;
			}
		}
 
		private function downHandler(event : MouseEvent) : void
		{
			_x = mouseX;
			_y = mouseY;
			isDown = true;
			stage.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
		}
 
		private function upHandler(event : MouseEvent) : void
		{
			isDown = false;
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
		}
 
		private function moveHandler(event : MouseEvent) : void
		{
			_vx = (mouseX - _x) * .4;
			_vy = (mouseY - _y) * .4;
			_x = mouseX;
			_y = mouseY;
 
			var q : Quaternion = Quaternion.createFromEuler(-_vx, 0, -_vy, true);
			rubiksCube.transform.calculateMultiply3x3(q.matrix, rubiksCube.transform);
		}
 
		private function clickHandler(event : InteractiveScene3DEvent) : void
		{
			var cube : DisplayObject3D = event.target as DisplayObject3D;
 
			// tricky: make scale and rotation value get updated from transform matrix.
			cube.yaw(0);
 
			var s : Number = cube.scale == 1 ? 0.8 : 1;
			TweenLite.to(cube, 0.3, {scale:s, ease:Elastic.easeOut});
		}
	}
}

« »