Flash Platform is a great tool to create games, either for internet or mobile content. With the introduction of Flash 3D Engines, the ability and success of creating flash games is even bigger. In this tutorial we are going to build up a simple sliding puzzle. Puzzle images are dynamically loaded and sliced so you can easily use your own images if you like. Learn, try and leave a comment showing your results.
Requirements
Prerequisites
- You should be familiar with OOP concepts and AS3
- Basic knowledge about Away3D (primitives, materials, cameras…)
The code (SlidingPuzzle.as)
So let’s see how it is done. First we’ll take a closer look at the main class (SlidingPuzzle.as). To get things working we need to import the proper classes.
package {
import away3d.cameras.HoverCamera3D;
import away3d.containers.View3D;
import com.techlabs.puzzle.ControlPanel;
import com.techlabs.puzzle.PuzzleBoard;
import com.techlabs.puzzle.events.PuzzleEvent;
import com.techlabs.puzzle.helpers.ImageSlicer;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.net.URLRequest;
Next we initialize the variables.
public static var subdivisions:int = 4;
Subdivisions determine how the puzzle board and the image itself are divided into smaller pieces. The default value results in 16 pieces.
public static var padding:int = 2;
Padding defines the gap between puzzle pieces.This gives our game a bit more realistic feel.
public static var size:int = 500;
Size determines the physical dimensions of the puzzle board. The loaded image doesn’t have to be 500x500px but make sure it is not too small either. Bigger is better
.
Slicing the image
The rest of the main class (SlidingPuzzle.as) deals with setting up the view and initializing the needed objects but let’s take a look what happens inside imageLoadComplete() handler.
private function imageLoadComplete(e:Event):void {
_image = _loader.content as Bitmap;
_puzzleImages = _slicer.sliceImage(_image);
_gameBoard.createPuzzle(_puzzleImages);
_view.scene.addChild(_gameBoard);
_controlPanel.setPreview(_image);
}
When the image is loaded we invoke ImageSlicer class’s instance method sliceImage() and pass it the loaded image as a parameter. The sliceImage() function will then slice it accordingly (subdivisions) and return at two dimensional array containing the bitmaps.
public function sliceImage(image:Bitmap):Array {
var imgW:Number = image.width;
var imgH:Number = image.height;
var pieceW:Number = imgW / SlidingPuzzle.cols;
var pieceH:Number = imgH / SlidingPuzzle.rows;
var imageArray:Array = new Array();
var rect:Rectangle;
var temp:Bitmap;
var tempdata:BitmapData;
for(var y:int = 0; y < SlidingPuzzle.rows; y++) {
imageArray[y] = new Array();
for(var x:int = 0; x < SlidingPuzzle.cols; x++) {
tempdata = new BitmapData(pieceW, pieceH, true, 0x00000000);
rect = new Rectangle(x * pieceW, y * pieceH, pieceW, pieceH);
tempdata.copyPixels(image.bitmapData, rect, new Point(0, 0));
temp = new Bitmap(tempdata);
imageArray[y][x] = temp;
}
}
return imageArray;
}
This two dimensional array is used for creating the board. createPuzzle() function takes the array as a parameter and iterates through it. Notice that the last piece is ignored beacause we need that space to be able to move other pieces. So here is what happens in the for loops.
- If we have reached the last piece let’s break out the loop
- New PuzzlePiece is created
- We add some eventhandlers to be able to interact with the piece
- We position the piece
When the loop is finnished the gameboard is centered in the view.
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();
}
Interaction
Well it just wouldn’t be a game without interaction. When user clicks a piece we first check if it is moving already. If it’s not moving we check its neighbours. If one of it’s neighbours is the empty place we move the piece there. checkNeighbours() function returns the direction where to move the piece or -1 if a valid move is not possible.
private function clickHandler(e:PuzzleEvent):void {
if (_moving)
return ;
var direction:int = checkNeighbours(e.piece);
if (direction > 0) {
e.piece.move(direction);
}
}
private function checkNeighbours(piece:PuzzlePiece):int {
var empty:Boolean;
// LEFT
if (piece.x > 0) {
empty = isEmptySpace(piece.x - _pieceWidth - _padding, piece.z);
if (empty)
return PuzzlePiece.LEFT;
}
// RIGHT
if (piece.x < _boardWidth - _pieceWidth - _padding) {
empty = isEmptySpace(piece.x + _pieceWidth + _padding, piece.z);
if (empty)
return PuzzlePiece.RIGHT;
}
// DOWN
if (piece.z < 0) {
empty = isEmptySpace(piece.x, piece.z + _pieceHeight + _padding);
if (empty)
return PuzzlePiece.UP;
}
// 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;
}
And “Game Over”, we have finished our puzzle game. Now it’s time to you test and create your own puzzle games. Leave a comment with your experiments. We are always seeking for the results of our tuts.




April 17th, 2009 at 3:15 pm
very cool tutorial, nice work
April 28th, 2009 at 2:52 pm
Nice tutorial thanks
April 28th, 2009 at 2:53 pm
Great tutorial thanks
May 8th, 2009 at 9:24 pm
very nice tutorial thank you
May 23rd, 2009 at 6:44 pm
freakin AWESOME!!!!
May 26th, 2009 at 4:26 pm
hi very nice one but there is aproblem when i but the subdevision = 3
June 11th, 2009 at 12:00 am
Sorry for being a newbie. I think I got all the packages etc in place, but how do I execute this when done?
SlidingPuzzle();
?
Thanks for the help.
- n
June 16th, 2009 at 3:17 pm
hi
it is very nice.
i am not know flex.
can i more slice of picture.
and show how many move done by user.
thanks
September 3rd, 2009 at 9:52 pm
Can I use this on my website?
September 3rd, 2009 at 9:53 pm
Can I use this on my website…is that ok?
October 18th, 2009 at 12:05 pm
Hi, It’s good for me to learn how to make my own Game through your lesson. Thank you so much.
November 16th, 2009 at 2:28 am
Timo,
Thank you for the excellent example of using the 3D library in AS3.
I did notice a “bug” in the shuffle routine that I was hoping you could help solve. The variable: SUBDIVISIONS which controls the number of board pieces, works properly with any dimension 2×2, 3×3, 4×4, …(slicer function), but the shuffle function ONLY works for values of 2, 4, 5, and 10. Any other values cause the pieces to stack on top of each other,forcing one to reset the board.
Could you please take a look at the logic and explain why it’s failing and post a quick update?
Thanks again,
-Marco (Dallas, TX)
November 16th, 2009 at 2:42 am
I think that I answered my own question. It seems that the puzzle board size must be an EXACT integer multiple of the variable “subdivisions” or the error that I described in my previous post will occur. When I created a 300×300 image, I could slice it as a 2×2, 3×3, 4×4, 5×5, 6×6, but it would fail again at 7 due to the remainder. So it seems the “bug” was just a missing comment in the documentation.
Thanks again for a great tutorial!
November 20th, 2009 at 12:09 am
This is a great post and its very creative indeed but if only you people would properly give cubefield a shot. Its a great game. Very addicitve and very entertaining to all age groups.
December 3rd, 2009 at 12:02 am
Howdy…
Great work, Hazam is right though.. when you use subdivisions that are a multiple of 3, it doesn’t scramble properly…let me know if you have any idea why this is…trying to figure it out myself..
December 29th, 2009 at 4:20 am
how to change button name flash puzzle & flex puzzle???
January 30th, 2010 at 1:13 am
I tried to compile (created an empty SlidingPuzzle.fla file in same src folder) using CS4 but got this error
PuzzeBoad.as, line 13
1017: The definition of base class ObjectContainer3D was not found.
February 3rd, 2010 at 3:28 pm
Great job, thank you for sharing.
February 19th, 2010 at 1:10 pm
the excellent example of using the 3D library in AS2.
February 19th, 2010 at 1:11 pm
this game of using the 3D library in AS2.
April 2nd, 2010 at 2:09 pm
Heya cool tutorial! qustion, do you know how I can make a simple slider puzzle with the coding in the main flash file (no .as files)?
I want to make a small 4×4 puzzle but cant seem to find any tutorials on it thats in AS3.
Thanks!
April 2nd, 2010 at 2:11 pm
P.S. I meant to say a 2D puzzle.
April 19th, 2010 at 6:05 pm
I really like the dynamic slicing code. Thanks for posting!
July 21st, 2010 at 9:36 am
hi guys please anyone can help me how i can modify this to put my image and why it is giving me eroor when i download the source to my pc.thank u all