Accessibility

Flash Article

 

Examining the Puzzle Game sample application


Valerio Virgillito

Valerio Virgillito

Adobe

Created:
14 May 2007
User Level:
Intermediate

Originally part of the samples that shipped with Flash Professional 8 under the Bitmap data feature, the Puzzle Game sample application has been updated from ActionScript 2.0 to use the latest features in ActionScript 3.0. This article details the code used in both versions so you can understand how the sample application was migrated from ActionScript 2.0 to ActionScript 3.0.

The Puzzle Game starts with eight randomly positioned puzzle pieces (see Figure 1). Your goal is to try and solve the puzzle by arranging those eight pieces so that they form an image. Once you solve the puzzle, the game starts over with a new puzzle to solve.

Puzzle Game sample application

Figure 1. Puzzle Game sample application

The main feature used is the BitmapData class. After the images are loaded, a BitmapData object is then used to split the image into eight equal parts, which are then used as puzzle pieces.

Here are the main differences between the two versions:

  • The Loader object, new in ActionScript 3.0, is used to load the images
  • Event handlers are used for the images and mouse movements, instead of ActionScript 2.0 listener objects
  • This game illustrates the use of the graphics class to draw the puzzle board
  • The setInterval function has been replaced with the new Timer object in ActionScript 3.0

Requirements

To view this sample application, you need the following software and files:

Flash CS3 Professional

Flash Player 9

Sample files:

Loading the master puzzle image

Look at how the puzzle images are loaded in the sample application. The ActionScript 2.0 code uses a MovieClipLoader object to load a randomly chosen JPEG file. A listener object is created so that a function can be called once the image has loaded.

The same result is achieved in ActionScript 3.0 using two new objects. A Loader object is created and used to load the images. Associated with that Loader object is an URLRequest object. The URLRequest object represents the image URL that you want to load. The benefit of the Loader object is that it already has an event listener to which you can subscribe. So, in this example, you are subscribing to the COMPLETE event, which will be triggered once the Loader has successfully loaded the image.

ActionScript 2.0 code:

// This is our MovieClipLoader object
var imageLoader:MovieClipLoader = new MovieClipLoader();
// Array of possible images from which one gets randomly
    selected.
var imagesArr:Array = new
    Array("http://www.helpexamples.com/flash/images/image1.jpg", ... ;
var listener:Object = new Object();
// The onLoadInit() method is called once the image loads.
listener.onLoadInit = function(imageClip:MovieClip):Void {
// Here: Code that gets called once the image has loaded
}
imageLoader.addListener(listener);

ActionScript 3.0 code:

imageLoader = new Loader();
requestURL = new URLRequest(imagesArr[index]);
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
    onLoadImg);
imageLoader.load(requestURL);
function onLoadImg(evt:Event):void{
// Here: Code that gets called once the image has loaded
}

Creating the puzzle pieces

After the image has loaded, you need to convert it into a BitmapData object. This is so that you can then split this bitmap image into eight equal parts and then draw them individually. These are your puzzle pieces. What you need to note here is the way to actually display those individual puzzle pieces on the Stage.

In ActionScript 2.0, you have to create empty movie clips to which you can attach the created bitmap—and repeat this eight times, once for each puzzle piece. The code looks similar in ActionScript 3.0 but you use the addChild method instead, which adds the specified movie clip to the Stage. The holder movie clip is an empty movie clip that holds all the puzzle pieces. The addChild method already puts the specified movie clip at the highest depth.

ActionScript 2.0 code:

var puzzlePieceClip:MovieClip =
    puzzlePiecesClip.createEmptyMovieClip("puzzlePiece" + index,
    puzzlePiecesClip.getNextHighestDepth());
puzzlePieceClip.attachBitmap(puzzlePieceBmp, 1);

ActionScript 3.0 code:

var puzzlePieceClip:Bitmap = new Bitmap(puzzlePiece);
holder.addChild(puzzlePieceClip);

Creating the puzzle board

Once you create the puzzle pieces and shuffle them, you need to create the puzzle board and create mouse handlers so that you can drag the pieces around. The puzzle board is drawn using the beginFill and lineTo methods in both ActionScript 2.0 and ActionScript 3.0. The only difference is that these methods now reside in the new graphics class in ActionScript 3.0.

ActionScript 2.0 code:

puzzleBoardSpaceClip = puzzleBoardClip.createEmptyMovieClip("puzzleBoardSpace"
    + i, i);
puzzleBoardSpaceClip.lineStyle(0);
puzzleBoardSpaceClip.beginFill(0xFFFFFF, 100);
puzzleBoardSpaceClip.lineTo(widthPuzzlePiece, 0);
...

ActionScript 3.0 code:

puzzleBoardSpaceClip = new MovieClip();
puzzleBoardSpaceClip.graphics.lineStyle(0);
puzzleBoardSpaceClip.graphics.beginFill(0xFFFFFF,100);
puzzleBoardSpaceClip.graphics.lineTo(widthPuzzlePiece,0);

Dragging the puzzle pieces

To apply the mouse dragging functionality to the game application, create an onPress function for each of the puzzle pieces movie clips and an onRelase function when the mouse button is released.

In ActionScript 3.0 you use movie clip mouse events to detect if there is a mouse click on that specific puzzle piece. First attach a mouseDown and mouseUp event handler to the main puzzle piece movie clip holder (a movie clip that holds the puzzle pieces) and then use the event.target property to move the appropriate puzzle piece.

ActionScript 2.0 code:

puzzlePieceClip.onPress = function():Void {
    this.startDrag();
    puzzlePieceClip.swapDepths(topDepth);
  };
  puzzlePieceClip.onRelease = function():Void {
...
}

ActionScript 3.0 code:

holder.addEventListener("mouseDown", pieceMove);
holder.addEventListener("mouseUp", pieceMove);
function pieceMove(evt:Event):void{
   if(evt.type == "mouseDown"){
      evt.target.startDrag();
   } else if(evt.type == "mouseUp"){
      evt.target.stopDrag();
...
}

Solving the puzzle

When all the puzzle pieces are in their correct postions, a timer starts. After 50 milliseconds the image slowly dissolves, relevealing the puzzle board underneath, and the game starts over. The timer functionality is achieved using the setInterval function in ActionScript 2.0. The setInterval function takes a function name and an interval as parameters. Once you are done, you can call the clearInterval function to remove the timer.

In ActionScript 3.0 there is now a Timer class that can be used to create a timer. A timer object is created, to which you can attach an event handler that triggers a function at each tick of the timer. You can specify the interval, as in ActionScript 2.0, and the function to be called. Once you're done, you can call the stop() method to stop the timer.

ActionScript 2.0 code:

intervalID = setInterval(puzzleThreshold, 100);
}
function puzzleThreshold():Void {
...}

ActionScript 3.0 code:

var timer:Timer = new Timer(50);
   timer.start();
   timer.addEventListener("timer", puzTrash);
}
function puzTrash(evt:Event):void{
...
}

Examining the Puzzle Game sample application code

Below is the complete code for each version of the Puzzle Game.

ActionScript 2.0 code:

//****************************************************************************
//Copyright (C) 2005 Macromedia, Inc. All Rights Reserved.
//The following is Sample Code and is subject to all
    restrictions on
//such code as contained in the End User License Agreement
    accompanying
//this product.
//****************************************************************************
/*
   To avoid security restrictions, test this document using
    Ctrl+Enter, or upload the SWF file to a server.
   If you test it in a local browser window (F12), make sure
    that this FLA file is in an *already* trusted directory, or set the file to "Access
    local files only" in Publish settings, which will prompt the Global
    Security Settings Manager, where you can select the directory this FLA file is
    in to trust. 
*/
System.security.allowDomain("http://www.helpexamples.com");
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.geom.Point;
// The puzzlePiecesArr array stores references to each of the
    puzzle piece movie clips.
var puzzlePiecesArr:Array;
// Store the top depth of each of the puzzle pieces.
var topDepth:Number;
// The puzzle consists of 8 puzzle pieces.
var totalPuzzlePieces:Number = 8;
// Use a variable to determine how many puzzle pieces are
    correctly in place.
var correctPuzzlePieces:Number;
// A BitmapData object stores the image data used for the
    puzzle.
var puzzleBmp:BitmapData;
var intervalID:Number;
var threshold:Number;
// Use an array of possible images from which one gets randomly
    selected.
var imagesArr:Array = new Array("http://www.helpexamples.com/flash/images/image1.jpg",
    "http://www.helpexamples.com/flash/images/image2.jpg", "http://www.helpexamples.com/flash/images/image3.jpg");
var listener:Object = new Object();
// The onLoadInit() method is called once the image loads.
listener.onLoadInit = function(imageClip:MovieClip):Void {
  // Determine the width and height of each puzzle piece. Each
    puzzle consists
  // of four columns and two rows.
  var widthPuzzlePiece:Number = imageClip._width/4;
  var heightPuzzlePiece:Number = imageClip._height/2;
  // Draw the image from the movie clip into a BitmapData
    object.
  puzzleBmp = new BitmapData(imageClip._width,
    imageClip._height);
  puzzleBmp.draw(imageClip, new Matrix());
  var puzzlePieceBmp:BitmapData;
  var x:Number = 0;
  var y:Number = 0;
  // Loop 8 times to make each puzzle piece.
  for(var i:Number = 0; i < 8; i++) {
    // Copy a section of the puzzle image into a new BitmapData
    object. Use the x and y variables, which
    // are updated with each iteration, to determine the
    rectangular region to copy.
    puzzlePieceBmp = new BitmapData(widthPuzzlePiece,
    heightPuzzlePiece);
    puzzlePieceBmp.copyPixels(puzzleBmp, new Rectangle(x, y,
    widthPuzzlePiece, heightPuzzlePiece), new Point(0, 0));
    // Pass the BitmapData object and the puzzle piece index to
    the custom makePuzzlePiece() function
    // to make the movie clip.
    makePuzzlePiece(puzzlePieceBmp, i);
    // Update x and y appropriately so each iteration draws a
    new region of the puzzle.
    x += widthPuzzlePiece;
    if(x >= puzzleBmp.width) {
      x = 0;
      y += heightPuzzlePiece;
    }
  }
  // Make the imageClip instance invisible once the bitmap data
    is copied.
  imageClip._visible = false;
  // Draw the puzzle board.
  makePuzzleBoard(puzzleBmp.width, puzzleBmp.height);
  // Arrange the puzzle pieces randomly.
  arrangePuzzlePieces();
};
var imageLoader:MovieClipLoader = new MovieClipLoader();
imageLoader.addListener(listener);
// Call resetPuzzle() initially.
resetPuzzle();
function resetPuzzle():Void {
  puzzlePiecesArr = new Array();
  // If the movie clip instances were already created
    previously, delete them.
  puzzlePiecesClip.removeMovieClip();
  imageClip.removeMovieClip();
  puzzleBoardClip.removeMovieClip();
  // Create the movie clip instance to hold the puzzle pieces
    and the puzzle board, and to load the image.
  this.createEmptyMovieClip("puzzleBoardClip",
    this.getNextHighestDepth());
  this.createEmptyMovieClip("puzzlePiecesClip",
    this.getNextHighestDepth());
  this.createEmptyMovieClip("imageClip",
    this.getNextHighestDepth());
  // Initialize correctPuzzlePieces to 0 since no puzzle pieces
    are yet in place.
  correctPuzzlePieces = 0;
  // Initialize threshold.
  threshold = 0xFFFF;
  // Select a random index from the imagesArr array, and load
    that image into imageClip.
  var index:Number = Math.floor(Math.random() *
    imagesArr.length);
  imageLoader.loadClip(imagesArr[index], imageClip);
}
function makePuzzlePiece(puzzlePieceBmp:BitmapData,
    index:Number):Void {
  // Make a new puzzle piece movie clip using the specified index
    as the last character in the
  // instance name. The index in the instance name is used to
    check if the puzzle piece is placed
  // in the correct space since the spaces have instance names
    with corresponding indices.
  var puzzlePieceClip:MovieClip = puzzlePiecesClip.createEmptyMovieClip("puzzlePiece"
    + index, puzzlePiecesClip.getNextHighestDepth());
  // Display the bitmap in the puzzle piece.
  puzzlePieceClip.attachBitmap(puzzlePieceBmp, 1);
  // With each puzzle piece update topDepth. Once the 8th puzzle
    piece is made, topDepth will have
  // the value of the top depth within puzzlePieceClip.
  topDepth = puzzlePieceClip.getDepth();
  // When the puzzle piece is pressed it starts dragging, and it
    uses swapDepth() to place the
  // clip above the others.
  puzzlePieceClip.onPress = function():Void {
    this.startDrag();
    puzzlePieceClip.swapDepths(topDepth);
  };
  puzzlePieceClip.onRelease = function():Void {
    // Stop dragging the clip when released.
    this.stopDrag();
    // Get the index of the puzzle piece as well as the index of
    the puzzle space over which the
    // puzzle piece was dropped (via the _droptarget property.)
    var puzzlePieceIndex:Number =
    this._name.substring(this._name.length - 1);
    var puzzleBoardSpaceIndex:Number =
    this._droptarget.substring(this._droptarget.length - 1);
    // If the indices are equal that means the puzzle piece was
    placed in the correct space.
    if(puzzlePieceIndex == puzzleBoardSpaceIndex) {
      var puzzlePieceSpaceClip:MovieClip = eval(this._droptarget);
      // Get the coordinates of the puzzle space movie clip, and
    convert them to the corresponding
      // global coordinates. Since puzzlePiecesClip aligns with
    the global coordinate space (it's
      // (0,0) coordinate is placed at the global (0,0)) it's
    not necessary to convert from global
      // to the local coordinates of puzzlePiecesClip, though
    technically you could do so. Once the
      // coordinates are converted to the corresponding global
    coordinates, move the puzzle piece to
      // those coordinates to "snap" the piece to the
    space.
      var coordinate:Object = {x: puzzlePieceSpaceClip._x, y:
    puzzlePieceSpaceClip._y};
      puzzleBoardClip.localToGlobal(coordinate);
      this._x = coordinate.x;
      this._y = coordinate.y;
      // Increment the number of puzzle pieces correctly placed.
      correctPuzzlePieces++;
      // If the number of correctly-placed pieces equals the
    total, then the puzzle is solved.
      // In that case, call the custom puzzleSolved() function.
      if(correctPuzzlePieces == totalPuzzlePieces) {
        puzzleSolved();
      }
    }
  };
  puzzlePiecesArr.push(puzzlePieceClip);
}
function arrangePuzzlePieces():Void {
  // Determine the dimensions of the puzzle pieces.
  var widthPuzzlePiece:Number = puzzlePiecesArr[0]._width;
  var heightPuzzlePiece:Number = puzzlePiecesArr[0]._height;
  // Define an array of locations for the puzzle pieces such
    that they will appear in a 2 by 4
  // grid on the left.
  var locationsArr:Array = new Array();
  locationsArr.push({x: 10, y: 10});
  locationsArr.push({x: 10 + widthPuzzlePiece + 5, y: 10});
  locationsArr.push({x: 10, y: 10 + heightPuzzlePiece + 5});
  locationsArr.push({x: 10 + widthPuzzlePiece + 5, y: 10 +
    heightPuzzlePiece + 5});
  locationsArr.push({x: 10, y: 10 + (heightPuzzlePiece + 5) *
    2});
  locationsArr.push({x: 10 + widthPuzzlePiece + 5, y: 10 +
    (heightPuzzlePiece + 5) * 2});
  locationsArr.push({x: 10, y: 10 + (heightPuzzlePiece + 5) *
    3});
  locationsArr.push({x: 10 + widthPuzzlePiece + 5, y: 10 +
    (heightPuzzlePiece + 5) * 3});
  var puzzlePieceClip:MovieClip;
  var index:Number = 0;
  var coordinates:Object;
  // Loop through each of the elements of locationsArr and
    puzzlePiecesArr. For each
  // element in puzzlePiecesArr, assign it the coordinates of
    one of the randomly-selected
  // elements from locationsArr.
  while(locationsArr.length > 0) {
    puzzlePieceClip = puzzlePiecesArr[index++];
    // Use the splice() method to select and remove an element
    from locationsArr. That way
    // the same coordinates are not used twice.
    coordinates = locationsArr.splice(Math.floor(Math.random() *
    locationsArr.length), 1)[0];
    puzzlePieceClip._x = coordinates.x;
    puzzlePieceClip._y = coordinates.y;
  }
}
function makePuzzleBoard(width:Number, height:Number):Void {
  // Determine the dimensions of each puzzle piece.
  var widthPuzzlePiece:Number = width/4;
  var heightPuzzlePiece:Number = height/2;
  var puzzleBoardSpaceClip:MovieClip;
  var x:Number = 0;
  var y:Number = 0;
  // Loop 8 times - once for each puzzle piece space. For each
    iteration, make a new movie clip
  // within puzzleBoardClip, and draw a rectangle within it.
    Note that each puzzle board space
  // movie clip has an instance name with an index that corresponds
    to the index of the puzzle
  // piece that can be correctly placed within the space.
  for(var i:Number = 0; i < 8; i++) {
    puzzleBoardSpaceClip = puzzleBoardClip.createEmptyMovieClip("puzzleBoardSpace"
    + i, i);
    puzzleBoardSpaceClip.lineStyle(0);
    puzzleBoardSpaceClip.beginFill(0xFFFFFF, 100);
    puzzleBoardSpaceClip.lineTo(widthPuzzlePiece, 0);
    puzzleBoardSpaceClip.lineTo(widthPuzzlePiece,
    heightPuzzlePiece);
    puzzleBoardSpaceClip.lineTo(0, heightPuzzlePiece);
    puzzleBoardSpaceClip.lineTo(0, 0);
    puzzleBoardSpaceClip.endFill();
    puzzleBoardSpaceClip._x = x;
    puzzleBoardSpaceClip._y = y;
    x += widthPuzzlePiece;
    if(x >= width) {
      x = 0;
      y += heightPuzzlePiece;
    }
  }
  // Move the puzzle board to the right side of the stage.
  puzzleBoardClip._x = 350;
  puzzleBoardClip._y = 200 - puzzleBoardClip._height/2;
}
// When the puzzle is solved, set the puzzlePiecesClip object as
    invisible, attach the puzzle bitmap
// to the puzzle board, and set an interval by which the
    threshold of the bitmap is continually updated
// to make an interesting fade effect.
function puzzleSolved():Void {
  puzzlePiecesClip._visible = false;
  puzzleBoardClip.attachBitmap(puzzleBmp,
    puzzleBoardClip.getNextHighestDepth());
  intervalID = setInterval(puzzleThreshold, 100);
}
function puzzleThreshold():Void {
  // Once the threshold is greater than 0xFFFFFF then clear the
    interval, and reset the puzzle.
  if(threshold > 0xFFFFFF) {
    threshold = 0xFFFFFF;
    clearInterval(intervalID);
    resetPuzzle();
  }
  // Use the threshold() method to make an interesting fade
    effect. With each call to puzzleThreshold()
  // the threshold variable is updated until it reaches
    0xFFFFFF. The effect is that the image dissolves
  // to white. Note that some bitwise operations are used to
    combine 0xFF000000 with the threshold
  // variable. That's because the threshold() method requires a
    threshold specified as 0xAARRGGBB. However,
  // the images have 100 alpha, so the AA portion is always
    0xFF000000.
  puzzleBmp.threshold(puzzleBmp, new Rectangle(0, 0,
    puzzleBmp.width, puzzleBmp.height), new Point(0, 0), "<=",
    0xFF000000 | threshold);
  threshold *= 1.2;
}

ActionScript 3.0 code:

var puzzlePiecesArr:Array;
var puzzlePiecesFound:Array;
var topDepth:Number;
var totalPuzzlePieces:Number;
var correctPuzzlePieces:Number;
var puzzleBmp:BitmapData;
var intervalID:Number;
var threshold:Number;
var imagesArr:Array;
var imageLoader:Loader;
var requestURL:URLRequest;  
var puzzleBoardClip:MovieClip;
var holder:MovieClip;
init();
function init(){
   puzzleBoardClip = new MovieClip();
   addChild(puzzleBoardClip);
   totalPuzzlePieces = 8;
   imagesArr = new Array("http://www.helpexamples.com/flash/images/image1.jpg",
    "http://www.helpexamples.com/flash/images/image2.jpg", "http://www.helpexamples.com/flash/images/image3.jpg");
   //imagesArr = new Array("image1.jpg", "image2.jpg",
    "image3.jpg");
   puzzlePiecesArr = new Array();
   puzzlePiecesFound = new Array();
   correctPuzzlePieces = 0;
   threshold = 0xFFFF;
   /* Create the image Loader */
   imageLoader = new Loader();
   imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
    onLoadImg);
   /* Create the URL Request */
   var index:Number = Math.floor(Math.random() *
    imagesArr.length);
   requestURL = new URLRequest(imagesArr[index]);
   // Load the image
   imageLoader.load(requestURL);
   // Setup a holdery mc to hold the puzzle pieces
   holder = new MovieClip();
   addChild(holder);
}
function onLoadImg(evt:Event):void{
   // Determine the width and height of each puzzle piece.
   // Each puzzle consists of 4 columns and 2 rows.
   var widthPuzzlePiece:Number = imageLoader.width / 4;
   var heightPuzzlePiece:Number = imageLoader.height / 2;
   // Draw the image from the movie clip into a BitmapData Obj.
   puzzleBmp = new BitmapData(imageLoader.width,
    imageLoader.height);
   puzzleBmp.draw(imageLoader, new Matrix());
   var puzzlePieceBmp:BitmapData;
   var x:Number = 0;
   var y:Number = 0;
   // Loop 8 times to make each piece
   for (var i:Number = 0; i < 8; i++)
   {
      puzzlePieceBmp = new BitmapData(widthPuzzlePiece,
    heightPuzzlePiece);
      puzzlePieceBmp.copyPixels(puzzleBmp, new
    Rectangle(x,y,widthPuzzlePiece,heightPuzzlePiece), new Point(0,0));
      makePuzzlePiece(puzzlePieceBmp, i);
      x += widthPuzzlePiece;
      if(x >= puzzleBmp.width)
      {
         x = 0;
         y += heightPuzzlePiece;
      }
   }
   makePuzzleBoard(puzzleBmp.width, puzzleBmp.height);
   arrangePuzzlePieces();
}
function makePuzzlePiece(puzzlePiece:BitmapData, index:int){
   var puzzlePieceClip:Bitmap = new Bitmap(puzzlePiece);
   var tmp2:MovieClip = new MovieClip();
   tmp2.addChild(puzzlePieceClip);
   tmp2.name = String(index)    // Added for Strict Mode
   holder.addChild(tmp2);
   holder.addEventListener("mouseDown", pieceMove);
   holder.addEventListener("mouseUp", pieceMove);
   puzzlePiecesArr.push(tmp2);
   // This is used to check if the same piece has been placed
   puzzlePiecesFound.push(tmp2.name);
}
function pieceMove(evt:Event):void{
   if(evt.type == "mouseDown"){
      evt.target.startDrag();
   } else if(evt.type == "mouseUp"){
      evt.target.stopDrag();
      var puzzlePieceIndex:Number = evt.target.name;
      // ADDED VV 4.3. Check if droppped inside of the grid
      if(evt.target.dropTarget){
         var puzzleBoardSpaceIndex:Number =
    evt.target.dropTarget.name;
      }
      if(puzzlePieceIndex == puzzleBoardSpaceIndex)
      {
         var coordinate:Point = new
    Point(evt.target.dropTarget.x, evt.target.dropTarget.y);
         var coordinateGlobal:Point = new Point();
         coordinateGlobal =
    puzzleBoardClip.localToGlobal(coordinate);
         evt.target.x = coordinateGlobal.x;
         evt.target.y = coordinateGlobal.y;
         if(puzzlePiecesFound.length != 0)
         {
            for(var i:int = 0;i < puzzlePiecesFound.length;
    i++)
            {
               if(puzzlePiecesFound[i] == puzzlePieceIndex)
               {
                  puzzlePiecesFound[i] = "Correct";
                  correctPuzzlePieces++;
               }
            }
         }
         if(correctPuzzlePieces == totalPuzzlePieces)
         {
            puzzleSolved();
         }
      }
   }
}
function arrangePuzzlePieces():void
{
   var widthPuzzlePiece:Number = puzzlePiecesArr[0].width;
   var heightPuzzlePiece:Number = puzzlePiecesArr[0].height;
   var locationArr:Array = new Array();
   locationArr.push({x:10, y:10});
   locationArr.push({x:10 + widthPuzzlePiece + 5, y: 10});
   locationArr.push({x:10, y:10 + heightPuzzlePiece + 5});
   locationArr.push({x:10 + widthPuzzlePiece + 5, y:10 +
    heightPuzzlePiece + 5});
   locationArr.push({x:10, y:10 + (heightPuzzlePiece + 5) * 2});
   locationArr.push({x:10 + widthPuzzlePiece + 5, y:10 +
    (heightPuzzlePiece + 5) * 2});
   locationArr.push({x:10, y:10 + (heightPuzzlePiece + 5) * 3});
   locationArr.push({x:10 + widthPuzzlePiece + 5, y:10 +
    (heightPuzzlePiece + 5) * 3});
   var index:Number = 0;
   var coordinates:Object;
   while(locationArr.length > 0)
   {
      coordinates = locationArr.splice(Math.floor(Math.random()
    * locationArr.length), 1)[0];
      puzzlePiecesArr[index].x = coordinates.x;
      puzzlePiecesArr[index].y = coordinates.y;
      index++;
   }
}
function makePuzzleBoard(width:Number, height:Number):void{
   var widthPuzzlePiece:Number = width / 4;
   var heightPuzzlePiece:Number = height / 2;
   var puzzleBoardSpaceClip:MovieClip;
   var x:Number = 0;
   var y:Number = 0;
   for(var i:Number = 0; i < 8; i++)
   {
      puzzleBoardSpaceClip = new MovieClip();
      puzzleBoardSpaceClip.graphics.lineStyle(0);
      puzzleBoardSpaceClip.graphics.beginFill(0xFFFFFF,100);
      puzzleBoardSpaceClip.graphics.lineTo(widthPuzzlePiece,0);
      puzzleBoardSpaceClip.graphics.lineTo(widthPuzzlePiece,heightPuzzlePiece);
      puzzleBoardSpaceClip.graphics.lineTo(0,heightPuzzlePiece);
      puzzleBoardSpaceClip.graphics.lineTo(0,0);
      puzzleBoardSpaceClip.graphics.endFill();
      puzzleBoardSpaceClip.x = x;
      puzzleBoardSpaceClip.y = y;
      x += widthPuzzlePiece;
      if(x >= width)
      {
         x = 0;
         y += heightPuzzlePiece;
      }
      puzzleBoardSpaceClip.name = String(i);   // Added for
    Strict Mode
      puzzleBoardClip.addChild(puzzleBoardSpaceClip);
   }
   puzzleBoardClip.x = 350;
   puzzleBoardClip.y = 200 - puzzleBoardClip.height/2;
}
function puzzleSolved():void{
   holder.visible = false;
   var tmp:Bitmap = new Bitmap(puzzleBmp);
   puzzleBoardClip.addChild(tmp);
   var timer:Timer = new Timer(50);
   timer.start();
   timer.addEventListener("timer", puzTrash);
}
function puzTrash(evt:Event):void{
   if(threshold > 0xFFFFFF)
   {
      threshold = 0xFFFFFF;
      evt.target.stop();
      init();
   }
   puzzleBmp.threshold(puzzleBmp, new Rectangle(0,0,
    puzzleBmp.width, puzzleBmp.height), new Point(0,0), "<=",
    0xFF000000 | threshold);
   threshold *= 1.2;
}

About the author

Valerio Virgillito has worked at Adobe Systems since 2005 and is currently a Flash authoring QE. Valerio loves writing ActionScript code and building cool applications using Flash. He also enjoys having a good time with his friends and fiancée, Kelly, and traveling.