Create a 3D Sliding Puzzle Game in Flex with ActionScript 3.0 and Away3D

by Timo Virtanen 36

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.


View the DemoDownload 3D Sliding Puzzle Game Source Files


  • You should be familiar with OOP concepts and AS3
  • Basic knowledge about Away3D (primitives, materials, cameras…)

The code (

So let’s see how it is done. First we’ll take a closer look at the main class ( 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.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;


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 ( 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);

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.

  1. If we have reached the last piece let’s break out the loop
  2. New PuzzlePiece is created
  3. We add some eventhandlers to be able to interact with the piece
  4. We position the piece

When the loop is finnished the gameboard is centered in the view.

public function createPuzzle(images:Array):void {

	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)

			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);



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) {

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;

	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.

Comments (36)

  1. very cool tutorial, nice work

  2. very nice tutorial thank you 🙂

  3. freakin AWESOME!!!!

  4. hi very nice one but there is aproblem when i but the subdevision = 3

  5. Sorry for being a newbie. I think I got all the packages etc in place, but how do I execute this when done?



    Thanks for the help.

    – n

  6. hi

    it is very nice.

    i am not know flex.

    can i more slice of picture.

    and show how many move done by user.


  7. Can I use this on my website?

  8. Can I use this on my website…is that ok?

  9. Hi, It’s good for me to learn how to make my own Game through your lesson. Thank you so much.

  10. 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)

    1. Did you (or Timo) solve the issue you described? I’m stuck with a 3×3 grid, [email protected]#n!

  11. 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!

  12. 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.

  13. 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..

  14. how to change button name flash puzzle & flex puzzle???

  15. I tried to compile (created an empty SlidingPuzzle.fla file in same src folder) using CS4 but got this error, line 13
    1017: The definition of base class ObjectContainer3D was not found.

  16. Great job, thank you for sharing.

  17. the excellent example of using the 3D library in AS2.

  18. this game of using the 3D library in AS2.

  19. 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.


  20. P.S. I meant to say a 2D puzzle.

  21. I really like the dynamic slicing code. Thanks for posting!

  22. 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

  23. impressive tutorial!
    Have you considered adding some live ActionScript class diagrams to your code? Please check my address and think about.

  24. Hi

    Its nice tutorial…
    I need to know when user completed the level and then popup will appear its show you completed the level…

    kind regards

  25. pls provide me objectContainer3D class.

    1. objectContainer3D is a container for all your 3D objects. This can be considered to be the same as a DisplayObjectContainer in flex =)

  26. You’re posting great,even so the latter paragraph I get a little bit to don’t understand, can you please deliver an explain?

  27. hi. I had go through this tutorial, its really nice. I have a problem, when i make 6 * 6 puzzle.The shuffle is not working properly.Can u tell me whats the problem and how to solve it….

  28. I have converted it to the flash IDE and now I’m wondering how to make a “game over” after you have finished the puzzle. Not sure where to check for in terms of initial arrays, all i get is $: y:0 x:45 z:34 (whereas “$:” is the object name). any ideas?

    1. I converted to the flash IDE also, and now I need to add some sort of puzzle completion event   – “game over”/”you win”.  Have you had any luck with that part?

  29. Tungak,  how did you port this to Flash Pro?

  30. Anyone alive in here?

  31. Wow, I just discovered that works just fine locally, but the puzzle does not show up in browsers.  Any ideas why this is?

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>