Full step by step tutorial to make a Flash game like “a blocky Christmas”

As you should know, tomorrow it’s Christmas, and I think you are expecting some Christmas gifts, so let me show you the Christmas gift I am giving to you all.

Did you play Bart Bonte‘s smash hit a blocky Christmas?

It’s one of the best yet simple games I played in the last months, and I am going to show you how to make your own blocky puzzle game following eight easy steps.

But before all, spend some (if not several) minutes to solve the game, the levels are really well designed and I am sure you will enjoy it.

Now, let’s start with the tutorial. Basically, a blocky Christmas is a tile based game, so all we need is an array and some coordinates.

1) Creating and showing of the game field

We are about to build level 5, because it includes everything we need to test all game features, and it’s easy to solve, so you will be able to test it without burning your brain.

The game field is a 19×19 array with walkable areas, walls, the player itself (a 1×1 green block) and some other green blocks you have to move to the goal.

So we are going to define some variables:

tileSize: the size, in pixels, of a tile.

gameField: a two-dimensional array with level walls (1) and walkable tiles (0).

player: a Point variable holding player’s x and y starting position.

playerGoal: a Point variable holding player’s x and y goal position.

blocks: an array of objects representing a block. Every block object contains an array of points defining its shape and the color we will use to render it.

goals: an array of objects containing an array of points defining the goal position of each block. I used an object although it contains only one item (the array) to let you expand the game easily.

The entire game is then rendered by displayGame function which lazily clears and redraws the entire level every time we need it, but it’s ok anyway as rendering the level in a fancy way is beyond the scope of this tutorial.

This is the script:

And this is the result:

We have our level rendered, now it’s time to allow some interaction.

2) Moving the player with arrow keys

From now on, the new blocks of code added, or rewritten, are included between start of new code and end of new code comments, so you can easily see what I am going to add/change to previous scripts.

At this time we need to add a KeyboardEvent listener to check for pressed keys, assign a possible move among up, down, left and right and check if the player can move in such direction. In this case, we update player position and render the level once more.

The function which decides if the player can move is possibleMove and at the moment it only returns true, meaning the player can always move.

I am storing the possible move in a Point variable, using it to save the x and y offsets of the desired player movement, so it will be (0,-1) if the player goes up, (1,0) if the player goes right, and so on.

This is the code:

And this is the result:

Move the player with arrow keys around the screen.

Unfortunately, the player does not move alone, as it’s also a magnet

3) Introducing magnetism

If close to a moveable block, the player also acts as a magnet, so we expect it to pull and push attached blocks as it moves around the screen.

In this step, I am going to see when a block is directly attached to the player and make it follow player movement.

To see if a block is directly attached to the player, the Manhattan distance between the player and one of the block tiles must be one. If you need more information about Manhattan distance, check the post the fastest way to find the distance between two points.

So if we have a block directly attached to the player, we can move it in the same player direction.

This is the code:

and this is the result:

You will be able to push and pull blocks around the screen, but only if you are directly adjacent to them, while in the original game a block attached to the player also becomes magnetic and is able to attach other blocks.

4) Extending magnetism

One of the ways to check for blocks attached to blocks which are attached to the player would be some kind of recursive flood fill algorithm. Check flood fill implementation post for more information about flood fill.

This time I won’t use recursion, so I need to check for all tiles adjacent to each block for another block, which in this case will inherit the magnetism, and to avoid infinite loops (e.g. I am checking A and find B is adjacent, so I am checking B and find A is adjacent so I am checking A…) I need to store visited blocks into an array, this way if a block is not in the array, I can be sure it’s the first time I meet it.

This is the code:

And this is the result:

Now blocks inherit magnetism and the whole game moves all actors correctly, so now we must start to limit player movements.

5) Preventing player to go through walls

The first way we are going to limit player movement, is preventing it to go through walls, that is the player cannot stand over tiles marked with 1.

It’s time to work a bit on checkPlayerMove function:

And this is the result:

Now walls stop the player, but they don’t stop attached blocks.

6) Preventing blocks to go through walls

Preventing blocks to go through walls is not different than preventing the player to go through walls, you just need to check blocks not to overlap walls tile by tile.

This is the code:

And this is the result:

Now blocks cannot overlap walls, but they still can overlap each others

7) Preventing blocks to overlap each others

This is the most difficult thing to do without using recursive functions. Basically if a block can move (because it won’t overlap any wall) but it would push another block which cannot move, the unmovable block should by threated like a solid wall, preventing the first block too to move, which becomes a wall preventing the player to push it.

It sounds complicate but you just need to scan through all blocks, transforming them to walls if they cannot move, and then run the previous routines with the remaining, free blocks.

Don’t forget, at the end of the process, to clear the fake walls you set when dealing with unmoveable blocks.

This is the code:

And this is the result:

Now everything acts just like the original game, we only need to check if the player solved the level

8) Checking for level solution

Checking for level solution is really easy, you just need to see if every block tile overlaps its goal tile, and if player position overlaps goal position, in this case the game ends:

And this is the result:

Now you can play the complete level.

Download the source code of all examples.

I really wish you a blocky Christmas, and a special thanks goes to Bart Bonte for giving me the permission to dissect his game that hard.

  • andrei

    offtopic: this game in casino section – http://www.meltingbrain.com/category/casino/ ))

  • Bongo

    Try this:

    2 Steps Right,

    4 Steps Up,

    1 Step Right,

    3 Steps Down,

    1 Step Left,

    2 Steps Down,

    3 Steps Left,

    3 Steps Up,

    7 Steps Right,

    And one more Step Right, and Look at this.
    The green box below goes right.

    In the original version (Level 5), it’s different.

    Thank you for the code.

  • Emanuele Feronato

    @andrei: thank you, fixed

    @bongo: thank you, going to fix it

  • Hi Emmanuel
    This ,like the rest of your training. it was functional and useful. Thank

  • Charles

    Very good… but keypresses are kinda stuffed. Press anyhitng, and it moves it either left or right…

  • Coudray

    Thanks, it looks great :D