3D Cube DFS Maze
/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6VBd
*/
// forked from greentec's 3D DFS Maze
package {
import away3d.cameras.Camera3D;
import away3d.containers.Scene3D;
import away3d.containers.View3D;
import away3d.controllers.HoverController;
import away3d.debug.AwayStats;
import away3d.entities.Mesh;
import away3d.lights.DirectionalLight;
import away3d.materials.ColorMaterial;
import away3d.materials.lightpickers.StaticLightPicker;
import away3d.primitives.CubeGeometry;
import flash.display.*;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
public class FlashTest extends Sprite {
public var view:View3D;
public var scene:Scene3D;
public var camera:Camera3D;
public var awayStats:AwayStats;
public var cameraController:HoverController;
public var light:DirectionalLight;
public var lightPicker:StaticLightPicker;
//navigation variables
private var move:Boolean = false;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var lastMouseX:Number;
private var lastMouseY:Number;
public var rowNum:int = 15;
public var colNum:int = 15;
public var depthNum:int = 15;
public var wallArray:Vector.<Vector.<Vector.<Mesh>>> = new Vector.<Vector.<Vector.<Mesh>>>(rowNum);
public var wallData:Vector.<Vector.<Vector.<Cube>>> = new Vector.<Vector.<Vector.<Cube>>>(int(rowNum / 2) + 1);
public var nowX:int;
public var nowY:int;
public var nowZ:int;
public var stack:Array = [];
public var cursor:Mesh;
//private var source:BitmapData = new BitmapData(465, 465, false, 0x000000);
public function FlashTest() {
// write as3 code here..
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Wonderfl.disable_capture();
//addChild(new Bitmap(source));
initEngine();
initLight();
initObject();
initListener();
wallData[0][0][0].isOpened = true;
wallArray[0][0][0].visible = false;
nowX = 0;
nowY = 0;
nowZ = 0;
stack.push(new Point3D(0, 0, 0));
}
private function dfs(row:int, col:int, depth:int):void
{
var wall:Cube;
wall = wallData[row][col][depth];
var path:String = "";
var i:int;
var onePath:String;
for (i = 0; i < wall.neighbor.length; i += 1)
{
onePath = wall.neighbor.substr(i, 1);
switch (onePath)
{
case "W":
if (wallData[wall._x - 1][wall._y][wall._z].isOpened == false)
{
path += onePath;
}
break;
case "E":
if (wallData[wall._x + 1][wall._y][wall._z].isOpened == false)
{
path += onePath;
}
break;
case "N":
if (wallData[wall._x][wall._y - 1][wall._z].isOpened == false)
{
path += onePath;
}
break;
case "S":
if (wallData[wall._x][wall._y + 1][wall._z].isOpened == false)
{
path += onePath;
}
break;
case "U":
if (wallData[wall._x][wall._y][wall._z - 1].isOpened == false)
{
path += onePath;
}
break;
case "D":
if (wallData[wall._x][wall._y][wall._z + 1].isOpened == false)
{
path += onePath;
}
break;
}
}
if (path == "")
{
stack.pop();
}
//while (path != "")
{
var randIndex:int;
randIndex = Math.random() * path.length;
var randDirection:String;
randDirection = path.substr(randIndex, 1);
path = path.replace(randDirection, '');
//trace(row, col, depth, randDirection);
switch (randDirection)
{
case "W":
if (wallData[row - 1][col][depth].isOpened == false)
{
wallData[row - 1][col][depth].isOpened = true;
wallArray[(row - 1) * 2][col * 2][depth * 2].visible = false;
wallArray[(row - 1) * 2 + 1][col * 2][depth * 2].visible = false;
//dfs(row - 1, col);
nowX = row - 1;
nowY = col;
nowZ = depth;
stack.push(new Point3D(nowX, nowY, nowZ));
}
break;
case "E":
if (wallData[row + 1][col][depth].isOpened == false)
{
wallData[row + 1][col][depth].isOpened = true;
wallArray[(row + 1) * 2][col * 2][depth * 2].visible = false;
wallArray[(row + 1) * 2 - 1][col * 2][depth * 2].visible = false;
//dfs(row - 1, col);
nowX = row + 1;
nowY = col;
nowZ = depth;
stack.push(new Point3D(nowX, nowY, nowZ));
}
break;
case "N":
if (wallData[row][col - 1][depth].isOpened == false)
{
wallData[row][col - 1][depth].isOpened = true;
wallArray[row * 2][(col - 1) * 2][depth * 2].visible = false;
wallArray[row * 2][(col - 1) * 2 + 1][depth * 2].visible = false;
//dfs(row - 1, col);
nowX = row;
nowY = col - 1;
nowZ = depth;
stack.push(new Point3D(nowX, nowY, nowZ));
}
break;
case "S":
if (wallData[row][col + 1][depth].isOpened == false)
{
wallData[row][col + 1][depth].isOpened = true;
wallArray[row * 2][(col + 1) * 2][depth * 2].visible = false;
wallArray[row * 2][(col + 1) * 2 - 1][depth * 2].visible = false;
//dfs(row - 1, col);
nowX = row;
nowY = col + 1;
nowZ = depth;
stack.push(new Point3D(nowX, nowY, nowZ));
}
break;
case "U":
if (wallData[row][col][depth - 1].isOpened == false)
{
wallData[row][col][depth - 1].isOpened = true;
wallArray[row * 2][col * 2][(depth - 1) * 2].visible = false;
wallArray[row * 2][col * 2][(depth - 1) * 2 + 1].visible = false;
//dfs(row - 1, col);
nowX = row;
nowY = col;
nowZ = depth - 1;
stack.push(new Point3D(nowX, nowY, nowZ));
}
break;
case "D":
if (wallData[row][col][depth + 1].isOpened == false)
{
wallData[row][col][depth + 1].isOpened = true;
wallArray[row * 2][col * 2][(depth + 1) * 2].visible = false;
wallArray[row * 2][col * 2][(depth + 1) * 2 - 1].visible = false;
//dfs(row - 1, col);
nowX = row;
nowY = col;
nowZ = depth + 1;
stack.push(new Point3D(nowX, nowY, nowZ));
}
break;
}
}
}
private function initEngine():void
{
view = new View3D();
view.antiAlias = 4;
scene = view.scene;
camera = view.camera;
camera.lens.far = 5000;
cameraController = new HoverController(camera);
cameraController.distance = 500;
cameraController.panAngle = -135;
cameraController.tiltAngle = -20;
//cameraController.maxTiltAngle = 90;
//cameraController.minTiltAngle = 10;
awayStats = new AwayStats(view);
}
private function initLight():void
{
light = new DirectionalLight( 0.5, -1, 1);
light.color = 0xffffff;
light.ambient = 1;
scene.addChild(light);
lightPicker = new StaticLightPicker([light]);
}
private function initObject():void
{
var i:int;
var j:int;
var k:int;
var blockWidth:int = 20;
var cube:Mesh;
var cubeGeometry:CubeGeometry = new CubeGeometry(blockWidth, blockWidth, blockWidth, 1, 1, 1, false);
var wallMaterial:ColorMaterial = new ColorMaterial(0x333333);
var floorMaterial:ColorMaterial = new ColorMaterial(0xcccccc);
wallMaterial.lightPicker = lightPicker;
wallMaterial.specular = 0.5;
wallMaterial.ambient = 0.3;
floorMaterial.ambient = 0.1;
//wallArray = [];
for (i = 0; i < rowNum; i += 1)
{
wallArray[i] = new Vector.<Vector.<Mesh>>(colNum);
for (j = 0; j < colNum; j += 1)
{
wallArray[i][j] = new Vector.<Mesh>(depthNum);
for (k = 0; k < depthNum; k += 1)
{
if (i > 0 && i < rowNum - 1 &&
j > 0 && j < colNum - 1 &&
k > 0 && k < depthNum - 1)
{
continue;
}
//make wall
cube = new Mesh(cubeGeometry, wallMaterial);
cube.x = (i - int(rowNum / 2)) * blockWidth;
cube.y = (j - int(colNum / 2)) * blockWidth;
cube.z = (k - int(depthNum / 2)) * blockWidth;
scene.addChild(cube);
wallArray[i][j][k] = cube;
}
}
}
//make floor
cube = new Mesh(new CubeGeometry((rowNum - 2) * blockWidth, (depthNum - 2) * blockWidth, (colNum - 2) * blockWidth, 1, 1, 1, false), floorMaterial);
scene.addChild(cube);
//wallData = [];
var wall:Cube;
for (i = 0; i < int(rowNum / 2) + 1; i += 1)
{
wallData[i] = new Vector.<Vector.<Cube>>(int(colNum / 2) + 1);
for (j = 0; j < int(colNum / 2) + 1; j += 1)
{
wallData[i][j] = new Vector.<Cube>(int(depthNum / 2) + 1);
for (k = 0; k < int(depthNum / 2) + 1; k += 1)
{
if (isCorrectWall(i, j, k) == false)
{
continue;
}
wall = new Cube(i, j, k);
if (i > 0 && isCorrectWall(i - 1, j, k) == true)
{
wall.neighbor += "W";
}
if (i < int(rowNum / 2) && isCorrectWall(i + 1, j, k) == true)
{
wall.neighbor += "E";
}
if (j > 0 && isCorrectWall(i, j - 1, k) == true)
{
wall.neighbor += "N";
}
if (j < int(colNum / 2) && isCorrectWall(i, j + 1, k) == true)
{
wall.neighbor += "S";
}
if (k > 0 && isCorrectWall(i, j, k - 1) == true)
{
wall.neighbor += "U";
}
if (k < int(depthNum / 2) && isCorrectWall(i, j, k + 1) == true)
{
wall.neighbor += "D";
}
wallData[i][j][k] = wall;
//trace(i, j, k, wall.neighbor);
}
}
}
cursor = new Mesh(cubeGeometry, new ColorMaterial(0x00ffff));
scene.addChild(cursor);
}
private function isCorrectWall(i:int, j:int, k:int):Boolean
{
if (i > 0 && i < int(rowNum / 2) &&
j > 0 && j < int(colNum / 2) &&
k > 0 && k < int(depthNum / 2))
{
return false;
}
return true;
}
private function initListener():void
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(Event.RESIZE, resizeHandler);
addEventListener(Event.ENTER_FRAME, render);
addChild(view);
addChild(awayStats);
}
private function render(e:Event):void
{
if (move)
{
cameraController.panAngle = 0.3 * (stage.mouseX - lastMouseX) + lastPanAngle;
cameraController.tiltAngle = 0.3 * (stage.mouseY - lastMouseY) + lastTiltAngle;
}
view.render();
//view.renderer.queueSnapshot(source);
if (stack.length != 0)
{
var row:int = stack[stack.length - 1]._x;
var col:int = stack[stack.length - 1]._y;
var depth:int = stack[stack.length - 1]._z;
cursor.x = wallArray[row * 2][col * 2][depth * 2].x;
cursor.y = wallArray[row * 2][col * 2][depth * 2].y;
cursor.z = wallArray[row * 2][col * 2][depth * 2].z;
dfs(row, col, depth);
}
}
private function onMouseDown(e:MouseEvent):void
{
lastPanAngle = cameraController.panAngle;
lastTiltAngle = cameraController.tiltAngle;
lastMouseX = stage.mouseX;
lastMouseY = stage.mouseY;
move = true;
}
private function onMouseUp(e:MouseEvent):void
{
move = false;
}
private function resizeHandler(e:Event):void
{
view.width = stage.stageWidth;
view.height = stage.stageHeight;
}
}
}
Class
{
/**
* ...
* @author ypc
*/
class Cube
{
public var neighbor:String;
public var _x:int;
public var _y:int;
public var _z:int;
public var isOpened:Boolean = false;
public function Cube(_x:int, _y:int, _z:int, neighbor:String = "")
{
this.neighbor = neighbor;
this._x = _x;
this._y = _y;
this._z = _z;
}
}
}
Class
{
/**
* ...
* @author ypc
*/
class Point3D
{
public var _x:int;
public var _y:int;
public var _z:int;
public function Point3D(_x:int = 0, _y:int = 0, _z:int = 0)
{
this._x = _x;
this._y = _y;
this._z = _z;
}
}
}