Flash 3D Sokoban prototype with Flare3D

Read all posts about "" game

You know I love Sokoban game. This is a prototype of a Flash 3D Sokoban made with Flare3D.

Flare3D is a real time 3D engine for Flash and Flex optimized for games and animations.

My plan is to create this simple prototype with various Flash 3D engines, then compare them with ease of use, performances and results. The one I’ll find the most interesting will be used for a series of tutorials, but meanwhile you can look at the commented code.

If you want more information about the creation of a Sokoban game, you can check my 2KB Flash Sokoban game and its jQuery version.

This is the code I created only with the help of online examples and official docs:

package {
	// required flash classes
	import flash.display.Sprite;
	import flash.events.Event;
	// required flare3d classes
	import flare.basic.*;
	import flare.materials.*;
	import flare.primitives.*;
	import flare.system.*;
	import flare.utils.*;
	import flare.core.*;
	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;
		// flare3d variables
		private var scene:Scene3D;// scene3D is the canvas of the flare3d environment
		private var player:Cube;// cube primitive representing the player
		private var movingCrate:Cube;// cube primitive representing the moving crate
		// some materials
		private var wallMaterial:ShadedColorMaterial=new ShadedColorMaterial("",0x000000,0x880088);
		private var crateMaterial:ShadedColorMaterial=new ShadedColorMaterial("",0x000000,0xff0000);
		private var playerMaterial:ShadedColorMaterial=new ShadedColorMaterial("",0x000000,0x0000ff);
		private var floorMaterial:ShadedColorMaterial=new ShadedColorMaterial("",0x000000,0x888888);
		private var goalMaterial:ShadedColorMaterial=new ShadedColorMaterial("",0x000000,0x00ff00);
		public function Main() {
			// scene setup
			scene=new Viewer3D(this,"",0,0);
			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("",3,1,3,1,floorMaterial);
							cube.setPosition(3*j,2,3*i);
							scene.addChild(cube);
							break;
						case 1 :
							cube=new Cube("",3,1,3,1,floorMaterial);
							cube.setPosition(3*j,2,3*i);
							scene.addChild(cube);
							cube=new Cube("",3,3,3,1,wallMaterial);
							cube.setPosition(3*j,4,3*i);
							scene.addChild(cube);
							break;
						case 2 :
							cube=new Cube("",3,1,3,1,goalMaterial);
							cube.setPosition(3*j,2,3*i);
							scene.addChild(cube);
							break;
						case 3 :
							cube=new Cube("",3,1,3,1,floorMaterial);
							cube.setPosition(3*j,2,3*i);
							scene.addChild(cube);
							cube=new Cube("crate_"+i+"_"+j,3,3,3,1,crateMaterial);
							cube.setPosition(3*j,4,3*i);
							scene.addChild(cube);
							break;
						case 4 :
							cube=new Cube("",3,1,3,1,floorMaterial);
							cube.setPosition(3*j,2,3*i);
							scene.addChild(cube);
							player=new Cube("",3,3,3,1,playerMaterial);
							player.setPosition(3*j,4,3*i);
							scene.addChild(player);
							playerCol=j;
							playerRow=i;
							break;
					}
				}
			}
			// listener to handle the 3D engine
			scene.addEventListener(Scene3D.UPDATE_EVENT,updateEvent);
		}
		private function updateEvent(e:Event):void {
			var currentRotation:Number=0;
			var dCol:int;
			var dRow:int;
			// 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 (playerRotation==0&&playerMovement==0) {
				// look how does flare3D listens for key pressed
				if (Input3D.keyDown(Input3D.RIGHT)) {
					playerRotation=5;
					playerAngle+=90;
				}
				if (Input3D.keyDown(Input3D.LEFT)) {
					playerRotation=-5;
					playerAngle-=90;
				}
				if (Input3D.keyDown(Input3D.UP)) {
					movingCrate=null;
					if (levels[playerRow+dRow][playerCol+dCol]==0||levels[playerRow+dRow][playerCol+dCol]==2) {
						// the player can move
						playerMovement=-0.25;
					} 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=scene.getChildByName("crate_"+(playerRow+dRow)+"_"+(playerCol+dCol))as Cube;
								playerMovement=-0.25;
							}
						}
					}
				}
				if (playerAngle<0) {
					playerAngle+=360;
				}
				if (playerAngle==360) {
					playerAngle=0;
				}
			} else {
				if (playerRotation) {
					// this is how flare3D rotates an object
					player.rotateY(playerRotation);
					if (Math.abs(Math.round(player.getRotation().y))%90==0) {
						playerRotation=0;
					}
				}
				if (playerMovement) {
					// this is how flare3D moves an object
					player.translateX(playerMovement);
					if (movingCrate) {
						switch (playerAngle) {
							case 0 :
								movingCrate.translateX(playerMovement);
								break;
							case 90 :
								movingCrate.translateZ(-playerMovement);
								break;
							case 180 :
								movingCrate.translateX(-playerMovement);
								break;
							case 270 :
								movingCrate.translateZ(playerMovement);
								break;
						}
					}
					// we need this to know if the player stopped on the destination tile
					if ((playerAngle%180==0&&(Math.round(player.getPosition().x*10)/10)%3==0)||(playerAngle%180!=0&&(Math.round(player.getPosition().z*10)/10)%3==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.setMaterial(goalMaterial);
							}
							else {
								movingCrate.setMaterial(crateMaterial);
							}
							levels[playerRow+dRow][playerCol+dCol]-=3;
							movingCrate.name="crate_"+(playerRow+2*dRow)+"_"+(playerCol+2*dCol);
						}
						playerCol+=dCol;
						playerRow+=dRow;
					}
				}
			}
			// camera management. this is awesome
			Pivot3DUtils.setPositionWithReference(scene.camera,9,18,0,player,0.1);
			Pivot3DUtils.lookAtWithReference(scene.camera,-6,-9,0,player);
		}
	}
}

And this is the result:

rotate the player with LEFT and RIGHT arrow keys, and move it with UP. Download the source code, swc file included.

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