Document Sample
CODES Powered By Docstoc
					So let’s see how it is done. First we’ll take   doesn’t have to be 500x500px but make
a closer look at the main class                 sure it is not too small either. Bigger is
( To get things working       better .
we need to import the proper classes.           The      rest     of    the    main     class
package {                                       ( deals with setting up
                                                the view and initializing the needed
        import                                  objects but let’s take a look what happens
away3d.cameras.HoverCamera3D;                   inside imageLoadComplete() handler.
        import                                  private function
away3d.containers.View3D;                       imageLoadComplete(e:Event):void {
                                                           _image = _loader.content as
        import                                  Bitmap;
com.techlabs.puzzle.ControlPanel;                          _puzzleImages =
        import                                  _slicer.sliceImage(_image);
com.techlabs.puzzle.PuzzleBoard;                           _gameBoard.createPuzzle(_puzzl
        import                                  eImages);;                    _view.scene.addChild(_gameBoa
        import                                  rd);
com.techlabs.puzzle.helpers.ImageSlicer;                   _controlPanel.setPreview(_image
          import flash.display.Bitmap;          }
          import flash.display.Loader;          When the image is loaded we invoke
          import flash.display.Sprite;          ImageSlicer class’s instance method
          import flash.display.StageAlign;      sliceImage() and pass it the loaded image
          import                                as a parameter. The sliceImage() function
flash.display.StageQuality;                     will then slice it accordingly (subdivisions)
          import                                and return at two dimensional array
flash.display.StageScaleMode;                   containing the bitmaps.
                                                public function
           import;           sliceImage(image:Bitmap):Array {
           import;                    var imgW:Number =
Next we initialize the variables.               image.width;
           public static var subdivisions:int              var imgH:Number =
= 4;                                            image.height;
Subdivisions determine how the puzzle
board and the image itself are divided into              var pieceW:Number = imgW /
smaller pieces. The default value results in    SlidingPuzzle.cols;
16 pieces.                                               var pieceH:Number = imgH /
           public static var padding:int = 2;   SlidingPuzzle.rows;
Padding defines the gap between puzzle
pieces.This gives our game a bit more                      var imageArray:Array = new
realistic feel.                                 Array();
           public static var size:int = 500;
Size determines the physical dimensions                    var rect:Rectangle;
of the puzzle board. The loaded image                      var temp:Bitmap;
              var tempdata:BitmapData;
                                                            var pieceCount:int = 0;
              for(var y:int = 0; y <                        var lastPiece:int =
     SlidingPuzzle.rows; y++) {                    SlidingPuzzle.subdivisions *
                        imageArray[y] = new        SlidingPuzzle.subdivisions;
                        for(var x:int = 0; x <              for(var yp:int = 0; yp <
     SlidingPuzzle.cols; x++) {                    SlidingPuzzle.subdivisions; yp++) {
                                 tempdata =                          for(var xp:int = 0; xp <
     new BitmapData(pieceW, pieceH, true,          SlidingPuzzle.subdivisions; xp++) {
     0x00000000);                                                              if
                                 rect = new        (++pieceCount == lastPiece)
     Rectangle(x * pieceW, y * pieceH,
     pieceW, pieceH);                                       break;

              tempdata.copyPixels(image.bitm                                 var
     apData, rect, new Point(0, 0));               image:Bitmap = images[yp][xp];
                                temp = new                                   var
     Bitmap(tempdata);                             piece:PuzzlePiece = new
                                                   PuzzlePiece(image, {width:_pieceWidth,
                                                   height:_pieceHeight, segmentsH:3,
              imageArray[y][x] = temp;             segmentsW:3});
              }                                            piece.addEventListener(PuzzleEv
                                                   ent.CLICK, clickHandler);
               return imageArray;
     This two dimensional array is used for               piece.addEventListener(PuzzleEv
     creating the board. createPuzzle() function   ent.MOVE, moveHandler);
     takes the array as a parameter and
     iterates through it. Notice that the last             piece.addEventListener(PuzzleEv
     piece is ignored beacause we need that        ent.READY, moveHandler);
     space to be able to move other pieces. So
     here is what happens in the for loops.                                  piece.x = xp *
1.   If we have reached the last piece let’s       _pieceWidth + xp * _padding;
     break out the loop                                                      piece.z = -(yp
2.   New PuzzlePiece is created                    * _pieceHeight + yp * _padding);
3.   We add some eventhandlers to be able to
     interact with the piece
4.   We position the piece                                  addChild(piece);
     When the loop is finnished the gameboard
     is centered in the view.                               _pieces.push(piece);
     public function                                                 }
     createPuzzle(images:Array):void {                      }
               clearBoard();                                centerBoard();
Well it just wouldn’t be a game without                  // DOWN
interaction. When user clicks a piece we                 if (piece.z < 0) {
first check if it is moving already. If it’s                       empty =
not moving we check its neighbours. If          isEmptySpace(piece.x, piece.z +
one of it’s neighbours is the empty place       _pieceHeight + _padding);
we      move         the      piece    there.                      if (empty)
checkNeighbours() function returns the                                      return
direction where to move the piece or -1 if      PuzzlePiece.UP;
a valid move is not possible.                            }
private function
clickHandler(e:PuzzleEvent):void {                       // UP
          if (_moving)                                   if (piece.z > -_boardHeight +
                     return ;                   _pieceHeight + _padding) {
          var direction:int =                                      empty =
checkNeighbours(e.piece);                       isEmptySpace(piece.x, piece.z -
          if (direction > 0) {                  _pieceHeight - _padding);
                     e.piece.move(direction);                      if (empty)
          }                                                                 return
}                                               PuzzlePiece.DOWN;
private function
checkNeighbours(piece:PuzzlePiece):int {                 return -1;
          var empty:Boolean;                    }

         // LEFT                                private function isEmptySpace(xp:int,
         if (piece.x > 0) {                     zp:int):Boolean {
                   empty =                                for each(var p:PuzzlePiece in
isEmptySpace(piece.x - _pieceWidth -            _pieces) {
_padding, piece.z);                                                if (p.x == xp) {
                   if (empty)                                                if (p.z == zp)
                            return              {
PuzzlePiece.LEFT;                                                                      return
         }                                      false;
         // RIGHT                                                  }
         if (piece.x < _boardWidth -                      }
_pieceWidth - _padding) {                                 return true;
                   empty =                      }
isEmptySpace(piece.x + _pieceWidth +
_padding, piece.z);
                   if (empty)