Flash 3d Sokoban Prototype With Alternativa3d Textured Version

Flash 3d Sokoban Prototype With Alternativa3d Textured Version

Emanuele Feronato added textures and some environment to Sokoban game prototype made with Flare3D.

I reproduced this prototype on Alternativa3D engine. And here you can find it:

Generally this port is bit different from Emanuele’s version. I can’t find information about feature like SkyBox in Alternativa3D, so this feature coded manually. Another difference is camera behavior. Emanuele binds camera to object and during rotations player object stand still and only camera fly around by its orbit. In Alternativa3d version object rotates too, this allow us to face player object it to it’s current direction. Camera is not binded to the object directly it is binded to object container and we can manipulate with player object in container, add animations, rotations etc. But both variants are good I think.


Here is source code:

package  { 	import alternativa.Alternativa3D; 	import alternativa.engine3d.containers.*; 	import alternativa.engine3d.controllers.*; 	import alternativa.engine3d.core.Camera3D; 	import alternativa.engine3d.core.Clipping; 	import alternativa.engine3d.core.Debug; 	import alternativa.engine3d.core.MipMapping; 	import alternativa.engine3d.core.MouseEvent3D; 	import alternativa.engine3d.core.Object3D; 	import alternativa.engine3d.core.Object3DContainer; 	import alternativa.engine3d.core.Sorting; 	import alternativa.engine3d.core.View; 	import alternativa.engine3d.materials.FillMaterial; 	import alternativa.engine3d.materials.TextureMaterial; 	import alternativa.engine3d.objects.Sprite3D; 	import alternativa.engine3d.primitives.Box; 	import alternativa.engine3d.primitives.Plane; 	import alternativa.engine3d.primitives.Sphere; 	 	import flash.display.BitmapData; 	import flash.display.BlendMode; 	import flash.display.Sprite; 	import flash.display.StageAlign; 	import flash.display.StageQuality; 	import flash.display.StageScaleMode; 	import flash.events.Event; 	import flash.events.KeyboardEvent; 	import flash.filters.GlowFilter; 	import flash.geom.ColorTransform; 	import flash.geom.Vector3D; 	import flash.sampler.NewObjectSample; 	import flash.system.Capabilities; 	import flash.ui.Keyboard; 		 	[SWF(backgroundColor="#000000", frameRate="100", width="640", height="480")] 	public class alternativa3dSokoban extends Sprite  	{ 		private const CUBESIZE:Number=10; 		//embeding textures images 		[Embed(source="resource/crateTextureImg.jpg")] static private const crateTextureImg:Class; 		[Embed(source="resource/floorTextureImg.png")] static private const floorTextureImg:Class; 		[Embed(source="resource/crateTopTextureImg.jpg")] static private const crateTopTextureImg:Class; 		[Embed(source="resource/crateTopGoalTextureImg.jpg")] static private const crateTopGoalTextureImg:Class; 		[Embed(source="resource/wallTextureImg.png")] static private const wallTextureImg:Class; 		[Embed(source="resource/goalTextureImg.jpg")] static private const goalTextureImg:Class; 		[Embed(source="resource/playerTextureImg.jpg")] static private const playerTextureImg:Class; 		[Embed(source="resource/backBitmapImg.jpg")] static private const backTextureImg:Class; 		[Embed(source="resource/backBottomBitmapImg.jpg")] static private const backBottomTextureImg:Class;  		// sokobal demo level and player position 		private var levels:Array=[[1,1,1,1,0,0,0,0],[1,0,0,1,1,1,1,1],[1,0,2,0,0,3,0,1],[1,0,3,0,0,2,4,1],[1,1,1,0,0,1,1,1],[0,0,1,1,1,1,0,0]]; 		private var playerCol:uint; 		private var playerRow:uint; 		private var playerRotation:Number=0; 		private var playerAngle:Number=0; 		private var playerMovement:Number=0; 		private var dRow:int; 		private var dCol:int; 		 		// alternativa3d  engine variables 		private var camera:Camera3D; 		private var controller:SimpleObjectController; 		private var container:ConflictContainer;			 		private var frame:Sprite = new Sprite(); 		public var player:Sphere;// Sphere primitive representing the player 		public var cplayer:SimpleObjectController; //controller for player object 		public var conplayer:Object3DContainer; //container for player 		private var movingCrate:Box;// cube primitive representing the moving crate		 			 		// textures		 		private var crateTexture:TextureMaterial = new TextureMaterial(new crateTextureImg().bitmapData); 		private var floorTexture:TextureMaterial = new TextureMaterial(new floorTextureImg().bitmapData); 		private var crateTopTexture:TextureMaterial = new TextureMaterial(new crateTopTextureImg().bitmapData); 		private var crateTopGoalTexture:TextureMaterial = new TextureMaterial(new crateTopGoalTextureImg().bitmapData); 		private var wallTexture:TextureMaterial = new TextureMaterial(new wallTextureImg().bitmapData); 		private var goalTexture:TextureMaterial = new TextureMaterial(new goalTextureImg().bitmapData); 		private var playerTexture:TextureMaterial = new TextureMaterial(new playerTextureImg().bitmapData); 		// SkyBox textures 		private var backTexture:TextureMaterial = new TextureMaterial(new backTextureImg().bitmapData); 		private var backBottomTexture:TextureMaterial = new TextureMaterial(new backBottomTextureImg().bitmapData); 						 		public function alternativa3dSokoban()  		{			 			stage.scaleMode = StageScaleMode.NO_SCALE; 			stage.align = StageAlign.TOP_LEFT; 			stage.quality = StageQuality.BEST; 			 			// Camera 			camera = new Camera3D(); 			camera.view = new View(640, 480); 			addChild(camera.view); 						 			// Camera controller 			controller = new SimpleObjectController(stage, camera, 200, 3); 			 			// Root object 			container = new ConflictContainer(); 			container.resolveByAABB = true; 			container.resolveByOOBB = true; 			 			//Player controller 			conplayer = new Object3DContainer(); 			cplayer = new SimpleObjectController(stage, player, 3); 			 //i am not shure about SkyBox in Alternativa and will prepare it manually 			var backBottom:Plane = new Plane(200*CUBESIZE/2,200*CUBESIZE/2); 			backBottom.setMaterialToAllFaces(backBottomTexture); 			backBottom.x = 0; 			backBottom.y = -100*CUBESIZE/2; 			backBottom.z = 0; 			backBottom.rotationX = 90*Math.PI/180; 			container.addChild(backBottom); 			 			var backLeft:Plane = new Plane(200*CUBESIZE/2,200*CUBESIZE/2); 			backLeft.setMaterialToAllFaces(backTexture); 			backLeft.x = 0; 			backLeft.y = 0; 			backLeft.z = 100*CUBESIZE/2; 			container.addChild(backLeft);  			var backRight:Plane = new Plane(200*CUBESIZE/2,200*CUBESIZE/2); 			backRight.setMaterialToAllFaces(backTexture); 			backRight.x = 0; 			backRight.y = 0; 			backRight.z = -100*CUBESIZE/2; 			container.addChild(backRight);  			var backFront:Plane = new Plane(200*CUBESIZE/2,200*CUBESIZE/2); 			backFront.setMaterialToAllFaces(backTexture); 			backFront.x = -100*CUBESIZE/2; 			backFront.y = 0; 			backFront.z = 0; 			backFront.rotationY = 90*Math.PI/180; 			container.addChild(backFront);  			var backBack:Plane = new Plane(200*CUBESIZE/2,200*CUBESIZE/2); 			backBack.setMaterialToAllFaces(backTexture); 			backBack.x = 100*CUBESIZE/2; 			backBack.y = 0; 			backBack.z = 0; 			backBack.rotationY = 90*Math.PI/180; 			container.addChild(backBack); // end SkyBox 			 			var box:Box; 			/* 			[[1,1,1,1,0,0,0,0], 			 [1,0,0,1,1,1,1,1], 			 [1,0,2,0,0,3,0,1], 			 [1,0,3,0,0,2,4,1], 			 [1,1,1,0,0,1,1,1], 			 [0,0,1,1,1,1,0,0]]; 			*/ 			// level construction 			for (var i:uint=0; i<6; i++)  			{ 				for (var j:uint=0; j<8; j++)  				{ 					switch (levels[i][j])  					{ 						case 0 : 							box = new Box(CUBESIZE,CUBESIZE/2,CUBESIZE,1,1); 							box.setMaterialToAllFaces(floorTexture); 							box.x = CUBESIZE*j; 							box.y = 0; 							box.z = CUBESIZE*i; 							container.addChild(box); 							break; 						case 1 : 							box = new Box(CUBESIZE,CUBESIZE/2,CUBESIZE,1); 							box.setMaterialToAllFaces(floorTexture); 							box.x = CUBESIZE*j; 							box.y = 0; 							box.z = CUBESIZE*i; 							container.addChild(box); 							 							box = new Box(CUBESIZE,CUBESIZE,CUBESIZE,1); 							box.setMaterialToAllFaces(wallTexture); 							box.x = CUBESIZE*j; 							box.y = CUBESIZE*3/4; 							box.z = CUBESIZE*i; 							container.addChild(box); 							break; 						case 2 : 							box = new Box(CUBESIZE,CUBESIZE/2,CUBESIZE,1); 							box.setMaterialToAllFaces(goalTexture); 							box.x = CUBESIZE*j; 							box.y = 0; 							box.z = CUBESIZE*i; 							container.addChild(box); 							break; 						case 3 : 							box = new Box(CUBESIZE,CUBESIZE/2,CUBESIZE,1); 							box.setMaterialToAllFaces(floorTexture); 							box.x = CUBESIZE*j; 							box.y = 0; 							box.z = CUBESIZE*i; 							container.addChild(box); 							box = new Box(CUBESIZE,CUBESIZE,CUBESIZE,1); 							box.name = "crate_"+i+"_"+j; 							box.setMaterialToAllFaces(crateTexture); 							box.x = CUBESIZE*j; 							box.y = CUBESIZE*3/4; 							box.z = CUBESIZE*i; 							box.rotationX -= 90*Math.PI/180; 							// top of the crate 							box.faces[4].material=crateTopTexture; 							box.faces[5].material=crateTopTexture;  							container.addChild(box); 							break; 						case 4 : 							box = new Box(CUBESIZE,CUBESIZE/2,CUBESIZE,1); 							box.setMaterialToAllFaces(floorTexture); 							box.x = CUBESIZE*j; 							box.y = 0; 							box.z = CUBESIZE*i; 							container.addChild(box); 														 							player = new Sphere(CUBESIZE/2,16,16,false,playerTexture);  							conplayer.addChild(player); 							conplayer.visible = true; 							conplayer.x = CUBESIZE*j; 							conplayer.y = CUBESIZE*3/4; 							conplayer.z = CUBESIZE*i; 							conplayer.rotationX -= 90*Math.PI/180; 							container.addChild(conplayer); 							playerCol=j; 							playerRow=i; 							break; 					} 				} 			}  			// Adding camera 			container.addChild(camera); 			 			// View frame 			addChild(frame);												 			onResize();		 			stage.addEventListener(Event.ENTER_FRAME, updateEvent);			 			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDwn);		 			stage.addEventListener(Event.RESIZE, onResize); 		}  		private function onKeyDwn(e:KeyboardEvent):void  		{ 			if (playerRotation==0&&playerMovement==0)  			{ 				switch (e.keyCode)  				{ 					case Keyboard.LEFT : 						playerRotation=+9; 						playerAngle+=90; 						break; 					case Keyboard.RIGHT : 						playerRotation=-9; 						playerAngle-=90; 						break; 					case Keyboard.UP : 						movingCrate=null; 						playerAngle=Math.round(conplayer.rotationY*180/Math.PI)%360; 						if (playerAngle<0)  						{ 							playerAngle+=360; 						} 						// we have to determine the difference between current row and column 						// and the new row and column according to player heading 						switch (playerAngle)  						{ 							case 0 : 								dRow=0; 								dCol=-1; 								break; 							case 90 : 								//dRow=-1; 								dRow=1; 								dCol=0; 								break; 							case 180 : 								dRow=0; 								dCol=1; 								break; 							case 270 : 								//dRow=1; 								dRow=-1; 								dCol=0; 								break; 						} 						if (levels[playerRow+dRow][playerCol+dCol]==0||levels[playerRow+dRow][playerCol+dCol]==2)  						{ 							// the player can move 							playerMovement=-CUBESIZE/10; 						}  						else  						{ 							if (levels[playerRow+dRow][playerCol+dCol]==3||levels[playerRow+dRow][playerCol+dCol]==5) { 								if (levels[playerRow+2*dRow][playerCol+2*dCol]==0||levels[playerRow+2*dRow][playerCol+2*dCol]==2) { 									// the player can move and can push a crate 									movingCrate=container.getChildByName("crate_"+(playerRow+dRow)+"_"+(playerCol+dCol))as Box; 									playerMovement=-CUBESIZE/10; 								} 							} 						} 						break;  				} 			} 		}   		public function updateEvent(e:Event):void  		{		 				if (playerRotation)  				{ 					conplayer.rotationY+=playerRotation*Math.PI/180; 					 					if (Math.abs(Math.round(conplayer.rotationY*180/Math.PI))%90==0) 					{ 						playerRotation=0; 					} 				} 				 				if (playerMovement)  				{					 					switch (playerAngle)  					{ 					case 0 : 						conplayer.x += playerMovement; 						player.rotationY -= 18*Math.PI/180; 					break; 					case 90 : 						conplayer.z += -playerMovement; 						player.rotationY -= 18*Math.PI/180; 					break; 					case 180 : 						conplayer.x += -playerMovement; 						player.rotationY -= 18*Math.PI/180; 						break; 					case 270 : 						conplayer.z += playerMovement; 						player.rotationY -= 18*Math.PI/180; 						break; 					} 					 					if (movingCrate)  					{ 						switch (playerAngle)  						{ 							case 0 : 								movingCrate.x += playerMovement; 								break; 							case 90 : 								movingCrate.z += -playerMovement; 								break; 							case 180 : 								movingCrate.x += -playerMovement; 								break; 							case 270 : 								movingCrate.z += playerMovement; 								break; 						} 					}  					// we need this to know if the player stopped on the destination tile 					if ((playerAngle%180==0&&(Math.round(conplayer.x*10)/10)%CUBESIZE==0)||(playerAngle%180!=0&&(Math.round(conplayer.z*10)/10)%CUBESIZE==0))  					{ 						playerMovement=0; 						levels[playerRow+dRow][playerCol+dCol]+=4; 						levels[playerRow][playerCol]-=4; 						if (movingCrate) { 							levels[playerRow+2*dRow][playerCol+2*dCol]+=3; 							if (levels[playerRow+2*dRow][playerCol+2*dCol]==5) { 								// changing materials on the fly 								movingCrate.setMaterialToAllFaces(crateTexture); 								// top of the crate on goal 								movingCrate.faces[4].material=crateTopGoalTexture; 								movingCrate.faces[5].material=crateTopGoalTexture;								  							} 							else  							{ 								//movingCrate.setMaterialToAllFaces(crateMaterial); 								movingCrate.setMaterialToAllFaces(crateTexture); 								// top of the crate 								movingCrate.faces[4].material=crateTopTexture; 								movingCrate.faces[5].material=crateTopTexture;								 							} 							levels[playerRow+dRow][playerCol+dCol]-=3; 							movingCrate.name="crate_"+(playerRow+2*dRow)+"_"+(playerCol+2*dCol); 						} 						playerCol+=dCol; 						playerRow+=dRow; 					} 				}  				onEnterFrame(); 		}			  		public function correct_camera_angles():void 		{ 			//set camera position 			var r:Number = 10*CUBESIZE/3;			 			var a:Number = -conplayer.rotationY; 			var cx:Number = conplayer.x+Math.cos(a)*r; 			var cz:Number = conplayer.z+Math.sin(a)*r; 			var cy:Number = conplayer.y+r;			 			controller.setObjectPosXYZ(cx,cy,cz); 			 			//look at player box 			controller.lookAtXYZ(conplayer.x,conplayer.y,conplayer.z); 			 			//correct camera angles			 				var cprotY:Number; 				 				cprotY=Math.round(conplayer.rotationY*180/Math.PI)%360;			 				if (cprotY<0)  				{ 					cprotY+=360; 				} 				if (cprotY>180) 				{ 					camera.rotationX = camera.rotationX + (90*Math.PI/180)*Math.sin((cprotY%180)*Math.PI/180); 				}										 				camera.rotationY = camera.rotationY+90*Math.PI/180-conplayer.rotationY; 		} 		 		public function onEnterFrame(e:Event = null):void  		{ 			controller.update(); 			correct_camera_angles(); 			cplayer.update(); 			camera.render();		 		} 		  		public function onResize(e:Event = null):void  		{ 			//here you can add border size for view 			var pd:Number = 0; 			camera.view.width = stage.stageWidth - pd*2; 			camera.view.height = stage.stageHeight - pd*2; 			camera.view.x = pd; 			camera.view.y = pd; 			 			frame.graphics.clear(); 			frame.graphics.beginFill(0x000000, 0); 			frame.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); 			//frame.graphics.lineStyle(0, 0x7F7F7F); 			frame.graphics.drawRect(pd, pd, camera.view.width, camera.view.height); 			frame.graphics.endFill(); 		} 	} }

Here you can download sources.

你可能感兴趣的:(Flash 3d Sokoban Prototype With Alternativa3d Textured Version)