Install Circle Chain on your iPhone for free and get the source code!! 645 downloads to go - last updated: April 21, 2012

Flash 3D Sokoban prototype with Flare3D

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (12 votes, average: 4.75 out of 5)
Loading ... Loading ...
Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 10 comments

  1. GN

    on February 5, 2011 at 2:17 pm

    Nice …. I was looking into Flash 3D engines myself. As always you’re one step ahead of me. Thanks!

  2. Hendy Siswanto

    on February 5, 2011 at 3:22 pm

    Wow .. i’ts amazing , thanks for the info emanuele ..

  3. Tweets that mention Flash 3D Sokoban prototype with Flare3D - Emanuele Feronato -- Topsy.com

    on February 5, 2011 at 4:23 pm

    [...] This post was mentioned on Twitter by Tim, mbroadcast. mbroadcast said: Flash 3D Sokoban prototype with Flare3D: You know I love Sokoban game. This is a prototype of a Flash 3D Sokoban… http://bit.ly/hj1I0Y [...]

  4. Vlad

    on February 5, 2011 at 5:14 pm

    If you hold right or left arrow near a wall and then suddenly stop turning and press the up arrow you start going through walls and boxes.
    Even so, the tutorial is great. Thanks.

  5. vega

    on February 6, 2011 at 2:06 pm

    It does look good – cant wait for those tutorials.

    At least for me the floor looks bugged tho.
    After you turn left or right (based on the start view) the floor gets “jaggy”. Looks kinda strange.

  6. TOdorus

    on February 6, 2011 at 6:44 pm

    Emanuele why did you chose for a tile- and turnbased game to test 3D engines with? Isn’t part of what makes a third party 3D engine interesting, that it will also handle collision detection and physics and still keep framerates reasonable? Are you only interested in testing the pipeline and ease of use?

  7. Emanuele Feronato

    on February 6, 2011 at 8:55 pm

    You’re right, all these topics will be covered, but I am starting from the bare bones.

  8. Vlad

    on February 9, 2011 at 11:17 am

    Emanuele, I’ve been working with PaperVision 3d for quite some time now.

    My questions as a person experience with 3d flash development are :

    1. Does this engine support internal ( embedded in the final .swf ) 3d models ? or will you need external 3d models ?

    2. What is the limit of polygons and/or vertices on the screen that it can have before going slow ?

  9. Cool Stuff with the Flash Platform – 2/10/11 | Finding Out About

    on March 6, 2011 at 10:04 pm

    [...] two tutorials and demos comparing 3D flash engines for building a Sokoban game prototype. The first is done with Flare3D and the second with [...]

  10. gopi

    on May 16, 2012 at 3:37 pm

    SOME TINE THE M9OVINING BOX GO TO THE PINK AREA AND MOVES WELL