Talking about Sokoban game, 3D, Actionscript 3, Flash and Game development.
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.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.