Flash 3D Sokoban prototype with Away3D

Read all posts about "" game

As promised, after the Flash 3D Sokoban prototype with Flare3D, here comes the Away3D version.

The code needs to be optimized and above all I want to make Away3D and Flare3D codes as similar as possible so I will be able to compare them and show you the differences.

This is the Away3D source code:

package {
	// required flash classes
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.geom.Vector3D;
	// required awayed classes
	import away3d.containers.*;
	import away3d.primitives.*;
	import away3d.cameras.*;
	import away3d.core.render.*;
	import away3d.materials.*;
	public class Main extends Sprite {
		// 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;
		// away3d variables
		private var view:View3D;// View3D represent the canvas
		private var theCamera:SpringCam;// custom camera to manage 1st or 3rd person camera
		private var player:Cube;// the player
		private var movingCrate:Cube;// the crate which will be pushed
		// some materials
		private var floorMaterial:WireColorMaterial=new WireColorMaterial(0x888888,{wireColor:0x484848});
		private var wallMaterial:WireColorMaterial=new WireColorMaterial(0x880088,{wireColor:0x480048});
		private var goalMaterial:WireColorMaterial=new WireColorMaterial(0x00ff00,{wireColor:0x00bb00});
		private var crateMaterial:WireColorMaterial=new WireColorMaterial(0xff0000,{wireColor:0xbb0000});
		private var playerMaterial:WireColorMaterial=new WireColorMaterial(0x0000ff,{wireColor:0x0000bb});
		function Main() {
			// scene setup
			view=new View3D({x:320,y:240});
			addChild(view);
			theCamera= new SpringCam();
			view.camera=theCamera;
			var cube=Cube;
			// level construction
			for (var i:uint=0; i<6; i++) {
				for (var j:uint=0; j<8; j++) {
					switch (levels[i][j]) {
						case 0 :
							cube=new Cube({material:floorMaterial,depth:50,width:50,height:10,x:50*i,y:-25,z:50*j});
							view.scene.addChild(cube);
							break;
						case 1 :
							cube=new Cube({material:floorMaterial,depth:50,width:50,height:10,x:50*i,y:-25,z:50*j});
							view.scene.addChild(cube);
							cube=new Cube({material:wallMaterial,depth:50,width:50,height:50,x:50*i,y:0,z:50*j});
							view.scene.addChild(cube);
							break;
						case 2 :
							cube=new Cube({material:goalMaterial,depth:50,width:50,height:10,x:50*i,y:-25,z:50*j});
							view.scene.addChild(cube);
							break;
						case 3 :
							cube=new Cube({material:floorMaterial,depth:50,width:50,height:10,x:50*i,y:-25,z:50*j});
							view.scene.addChild(cube);
							cube=new Cube({material:crateMaterial,depth:50,width:50,height:50,x:50*i,y:0,z:50*j});
							cube.name="crate_"+i+"_"+j;
							view.scene.addChild(cube);
							break;
						case 4 :
							cube=new Cube({material:floorMaterial,depth:50,width:50,height:10,x:50*i,y:-25,z:50*j});
							view.scene.addChild(cube);
							player=new Cube({material:playerMaterial,depth:50,width:50,height:50,x:50*i,y:0,z:50*j});
							view.scene.addChild(player);
							playerCol=j;
							playerRow=i;
							theCamera.target=player;
							theCamera.positionOffset=new Vector3D(0,500,150);
							theCamera.lookOffset=new Vector3D(0,0,-100);
							theCamera.damping=20;
							break;
					}
				}
			}
			// listeners
			addEventListener(Event.ENTER_FRAME,onEnterFrm);
			stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDwn);
		}
		private function onKeyDwn(e:KeyboardEvent):void {
			if (playerRotation==0&&playerMovement==0) {
				switch (e.keyCode) {
					case 37 :
						playerRotation=-9;
						break;
					case 38 :
						var playerAngle:Number=Math.round(player.rotationY)%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;
								dCol=0;
								break;
							case 180 :
								dRow=0;
								dCol=1;
								break;
							case 270 :
								dRow=1;
								dCol=0;
								break;
						}
						if (levels[playerRow+dRow][playerCol+dCol]==0||levels[playerRow+dRow][playerCol+dCol]==2) {
							// the player can move
							playerMovement=-5;
						} 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=view.scene.getChildByName("crate_"+(playerRow+dRow)+"_"+(playerCol+dCol))as Cube;
									playerMovement=-5;
								}
							}
						}
						break;
					case 39 :
						playerRotation=9;
						break;
				}
			}
		}
		private function onEnterFrm(e:Event):void {
			var playerAngle:Number;
			if (playerRotation) {
				// this is how away3d rotates an object
				player.rotationY+=playerRotation;
				playerAngle=Math.round(player.rotationY);
				if (playerAngle%90==0) {
					playerRotation=0;
				}
			}
			if (playerMovement) {
				// this is how away3d moves an object
				player.moveForward(playerMovement);
				if (movingCrate) {
					playerAngle=Math.round(player.rotationY)%360;
					if (playerAngle<0) {
						playerAngle+=360;
					}
					switch (playerAngle) {
						case 0 :
							movingCrate.moveForward(playerMovement);
							break;
						case 90 :
							movingCrate.moveRight(playerMovement);
							break;
						case 180 :
							movingCrate.moveBackward(playerMovement);
							break;
						case 270 :
							movingCrate.moveLeft(playerMovement);
							break;
					}
				}
				// we need this to know if the player stopped on the destination tile
				if (Math.round(player.rotationY)%180==0) {
					if (Math.round(player.z)%50==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.material=goalMaterial;
							} else {
								movingCrate.material=crateMaterial;
							}
							levels[playerRow+dRow][playerCol+dCol]-=3;
							movingCrate.name="crate_"+(playerRow+2*dRow)+"_"+(playerCol+2*dCol);
							movingCrate=null;
						}
						playerRow+=dRow;
						playerCol+=dCol;
					}
				} else {
					if (Math.round(player.x)%50==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) {
								movingCrate.material=goalMaterial;
							} else {
								movingCrate.material=crateMaterial;
							}
							levels[playerRow+dRow][playerCol+dCol]-=3;
							movingCrate.name="crate_"+(playerRow+2*dRow)+"_"+(playerCol+2*dCol);
							movingCrate=null;
						}
						playerRow+=dRow;
						playerCol+=dCol;
					}
				}
			}
			// camera management
			theCamera.view;
			view.render();

		}
	}
}

and this is the result:

rotate the player with LEFT and RIGHT arrow keys, and move it with UP.

Download the source code.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers