package com.techlabs.puzzle {
import away3d.containers.ObjectContainer3D;
import com.techlabs.puzzle.events.PuzzleEvent;
import flash.display.Bitmap;
/**
* ...
* @author Timo Virtanen
*/
public class PuzzleBoard extends ObjectContainer3D {
private var _boardWidth:int;
private var _boardHeight:int;
private var _pieceWidth:Number;
private var _pieceHeight:Number;
private var _padding:int;
private var _moving:Boolean;
private var _pieces:Array = new Array();
public function PuzzleBoard() {
_boardWidth = SlidingPuzzle.size + SlidingPuzzle.padding * SlidingPuzzle.subdivisions;
_boardHeight = SlidingPuzzle.size + SlidingPuzzle.padding * SlidingPuzzle.subdivisions;
_pieceWidth = SlidingPuzzle.size / SlidingPuzzle.subdivisions;
_pieceHeight = SlidingPuzzle.size / SlidingPuzzle.subdivisions;
_padding = SlidingPuzzle.padding;
}
public function createPuzzle(images:Array):void {
clearBoard();
var pieceCount:int = 0;
var lastPiece:int = SlidingPuzzle.subdivisions * SlidingPuzzle.subdivisions;
for(var yp:int = 0; yp < SlidingPuzzle.subdivisions; yp++) {
for(var xp:int = 0; xp < SlidingPuzzle.subdivisions; xp++) {
if (++pieceCount == lastPiece)
break;
var image:Bitmap = images[yp][xp];
var piece:PuzzlePiece = new PuzzlePiece(image, {width:_pieceWidth, height:_pieceHeight, segmentsH:3, segmentsW:3});
piece.addEventListener(PuzzleEvent.CLICK, clickHandler);
piece.addEventListener(PuzzleEvent.MOVE, moveHandler);
piece.addEventListener(PuzzleEvent.READY, moveHandler);
piece.x = xp * _pieceWidth + xp * _padding;
piece.z = -(yp * _pieceHeight + yp * _padding);
addChild(piece);
_pieces.push(piece);
}
}
centerBoard();
}
public function shuffle():void {
var p:PuzzlePiece;
var direction:int;
for(var i:int = 0; i < 200; i++) {
do {
p = _pieces[int(Math.random() * _pieces.length - 1)];
direction = checkNeighbours(p);
} while(direction == -1);
p.move(direction, false);
}
}
private function clickHandler(e:PuzzleEvent):void {
if (_moving)
return ;
var direction:int = checkNeighbours(e.piece);
if (direction > 0) {
e.piece.move(direction);
}
}
private function moveHandler(e:PuzzleEvent):void {
if (e.type == PuzzleEvent.MOVE)
_moving = true;
else if (e.type == PuzzleEvent.READY)
_moving = false;
}
private function checkNeighbours(piece:PuzzlePiece):int {
var empty:Boolean;
if (piece.x > 0) {
empty = isEmptySpace(piece.x - _pieceWidth - _padding, piece.z);
if (empty)
return PuzzlePiece.LEFT;
}
if (piece.x < _boardWidth - _pieceWidth - _padding) {
empty = isEmptySpace(piece.x + _pieceWidth + _padding, piece.z);
if (empty)
return PuzzlePiece.RIGHT;
}
if (piece.z < 0) {
empty = isEmptySpace(piece.x, piece.z + _pieceHeight + _padding);
if (empty)
return PuzzlePiece.UP;
}
if (piece.z > -_boardHeight + _pieceHeight + _padding) {
empty = isEmptySpace(piece.x, piece.z - _pieceHeight - _padding);
if (empty)
return PuzzlePiece.DOWN;
}
return -1;
}
private function isEmptySpace(xp:int, zp:int):Boolean {
for each(var p:PuzzlePiece in _pieces) {
if (p.x == xp) {
if (p.z == zp) {
return false;
}
}
}
return true;
}
private function clearBoard():void {
for each(var p:PuzzlePiece in _pieces) {
p.removeEventListener(PuzzleEvent.CLICK, clickHandler);
p.removeEventListener(PuzzleEvent.MOVE, moveHandler);
p.removeEventListener(PuzzleEvent.READY, moveHandler)
removeChild(p);
}
_pieces = new Array();
}
private function centerBoard():void {
x = -(_boardWidth * .5 - _pieceWidth * .5);
z = _boardHeight * .5 - _pieceHeight * .5;
}
}
}