Flash Tutorial Links:
Play Games: HTML5 Tutorials:

How To Make A Platform Game (Part 2)

Now this is starting to look more like Super Mario.

Platform Games

Previously, we looked at a jumping game that works pretty much like the Mario platform games we're very used to. In a full-fledged platform game, a lot of actually goes into the level design. Which monster should we place here to challenge the players. How do we want the players to jump his way to secret levels or obtain hidden items.

If the level design behind the game is lacking, players will inevitably feel bored playing the game.

Here, I'll show you how to create a simple level design, using coins, bricks (platforms) and a vertically moving lift as the three key components of the game. I admit this is definitely not enough, but the techniques you learn here should be able to propel you forward. With the idea of the vertical lift, you can proceed on to do a horizontally moving lift as well.

Some of the key concepts you'll find in this tutorial is how to make the game screen scroll as your character moves, as well as how to implement your design ideas during design time, and not at runtime. So far, we've almost always generated game assets on the fly by some random chance. If you open up the FLA file, you'll see all the bricks or platforms already laid out for you. This design is done at design time.

You need to look at Tutorial 7 before proceeding on, because I will not discuss those concepts that were highlighted earlier on.

Game Scenario

Tooney the little green monster has previously climbed up the Waterfall, and is now ready to collect his shiny coins. These coins are precariously placed on platforms, some moving, and Tooney has to jump his way around to collect them all.

Help Tooney collect as many coins as you can!

Game Details

  1. The player controls the movement of Tooney with the LEFT, RIGHT keys.
  2. Tooney can be made to jump with the SPACEBAR key.
  3. Each coin Tooney collects earns him 10 points.
  4. Do not let Tooney fall off the platforms.

Download the Game Files

The files you need to create this game can be downloaded from here.

Step 1 - Managing your FLA file

In the library, you will see that there are quite a lot of movieclips. What's new are the Coin, VerticalLift and Markers movieclips. The Marker movieclip is a special movieclip, because it's not really a game asset which the player can see. Rather, it's a movieclip used at design time to mark out the start and end point of the scrolling behaviour. More on it later.

library

The Player movieclip is similar to what you saw in Tutorial 7. It has the same hitAreaFloor movieclip in it to mark out the area which will detect if Tooney landed on a brick.

player

For the detailed explanation on this, please check out Tutorial 7 first.

Step 2 - Starting up the game in your GameController.as

Let us see what goes on in the startGame function.

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public function startGame()
{
    playerScore = C.PLAYER_START_SCORE;
            
    gameObjects = new Array();
    bricks = new Array();
    coins = new Array();
    lifts = new Array();
    
    scrollSoFar = 0;
    moveX = 0;
    jump = false;
    
    setUpGame();
    
    //Add player on to stage
    player = new Player(C.PLAYER_START_X, C.PLAYER_START_Y);
    mcGameStage.addChild(player);
    
    //Hide Markers
    mcGameStage.mcStartMarker.visible = false;
    mcGameStage.mcEndMarker.visible = false; 
    
    mcGameStage.addEventListener(Event.ENTER_FRAME,update);
    
    //Handle event when this game is being preloaded
    addEventListener(Event.ADDED_TO_STAGE, gameAddedToStage ); 
    
    //Handle situations when this game is being run directly
    if (stage != null)
    {
        stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP,keyUpHandler);
    }
}

You may observe that we have a lot of arrays here, each one storing a type of game object. What's most interesting here is perhaps gameObjects. It is an array which we'll use to scroll all the objects that should scroll later on. It's going to store a mixture of the bricks, lifts, etc.

We'll look at line 61 in detail shortly. setUpGame is the function which will look at all the game objects you've placed inside the mcGameStage and then sort them out into their proper arrays. More on that later.

Lines 68 and 69 turns the visibility property of the markers off, so that the player will not see it at all. These markers are still useful later when we do the scrolling logic, but the player does no need to see them.

Step 3 - Key Handlers

The key handlers are exactly the same as that in Tutorial 7. The keyboard input to the game will be the LEFT, RIGHT and SPACEBAR keys. Feel free to add in the support for the A and D keys as well if you want.

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
private function keyDownHandler(evt:KeyboardEvent):void
{
    if (evt.keyCode == 37) //LEFT Key 
    {
        moveX = -1;
    }
    else if (evt.keyCode == 39) //RIGHT Key
    {
        moveX = 1;
    }
    
    if (evt.keyCode == 32) //Spacebar
    {
        jump = true;
    }
}

jump is just a boolean variable. We set it to be true when the player hits the spacebar.

Step 4 - setUpGame

The game objects that we placed inside mcGameStage needs to be properly analysed and understood by the Game Controller. Otherwise, the player will not be able to interact with them. Hence, once the game is called to start, we call the function setUpGame to sort things out.

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
private function setUpGame()
{
    //Loop through all items on stage
    for (var i=0; i< mcGameStage.numChildren; i++)
    {
        var currObject = mcGameStage.getChildAt(i);
        
        //Identify the bricks
        if (currObject is Brick)
        {
            bricks.push(currObject);
            gameObjects.push(currObject);
        }
        else if (currObject is Coin)
        {
            coins.push(currObject);
            gameObjects.push(currObject);
        }
        else if (currObject is VerticalLift)
        {
            lifts.push(currObject);
            gameObjects.push(currObject);
        }
    }
}

numChildren in line 123 stores the total number of child objects inside mcGameStage. When we drag all those movieclips into mcGameStage, they are all considered the children of mcGameStage. So what this for loop does is to loop through all the children.

In line 128, we see this new syntax, currObject is Brick. Although we can tell that it REALLY IS a Brick object, but it is known to Flash only as a DisplayObject, basically. What this "is" syntax does is to check if the currObject is of class Brick. It returns true if it is, false if otherwise.

If it is a Brick, we push it into the array bricks, as well as the array gameObjects.

We do the same for coins, and vertical lifts. After we are done with this function setUpGame, our arrays are already properly storing the respective game objects. The array gameObjects will store all the game objects that should scroll when the player moves.

Step 5 - Game Loop - User Input

The codes to handle the user input are exactly the same as that in Tutorial 7. There isn't any new code to make the movement here work. Please head over to Tutorial 7 if you need help.

Step 6 - Game Loop - Game Logic

We will only highlight the code that is unique in this tutorial from the previous. You can see that there is a new game mechanic here, that is the vertical lifts. At the start of the game logic, we update the lifts.

164
165
166
167
168
169
170
171
//******************
//Handle Game Logic
//******************
//Update lifts
for (var i=lifts.length - 1; i >= 0; i--)
{
    lifts[i].update();
}

Let's take a look at what goes on in the VerticalLift class.

20
21
22
23
24
25
26
27
28
public function update()
{
    this.y += this.dirY * C.VERTICAL_LIFT_SPEED;
    if ((this.y <= this.startPosY - C.VERTICAL_LIFT_MAX_DISTANCE) ||
        (this.y >= this.startPosY + C.VERTICAL_LIFT_MAX_DISTANCE))
    {
        this.dirY *= -1;
    }
}

The variable dirY indicates which direction the lift is going to move towards. We mulitply it by the speed of the lift, denoted by C.VERTICAL_LIFT_SPEED, and modify the y position accordingly. Lines 23 to 27 checks if the lift has reached it's maximum distance that it should travel, and if so, flip the direction around by multiplying dirY by -1.

You do not have to worry how to make the player move if the player is standing on the lift. Remember that there is a property in the Player class which is standingOn, and that denotes the platform the player is on. During the player's update, his location will be updated to the platform's coordinates accordingly.

Now let us go back to the game logic in the game loop.

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//Update Player
player.update();
    
//Check for collisions
if (player.isInAir() && player.isFalling())
{	
    for (var i=bricks.length - 1; i >= 0; i--)
    {
        if (player.hitAreaFloor.hitTestObject(bricks[i]))
            {
                //Player landed on the brick
                player.hitFloor(bricks[i]);
            }
    }
	
    for (var i=lifts.length - 1; i >= 0; i--)
    {
        if (player.hitAreaFloor.hitTestObject(lifts[i]))
        {
            //Player landed on the lift
            player.hitFloor(lifts[i]);
        }
    }
}

The code here is exactly the same as previous, but we added the check for collisions between the player and the lifts now from line 188 to line 195.

The code isn't very different though. But because the player can now land on either the Brick, or the Lift, we amended the hitFloor function in the Player class slightly. Instead of locking in whether it is a Brick or a Lift, we use the * to denote any possible class.

145
146
147
148
149
150
public function hitFloor(platform:*)
{
    this.inAir = false;
    this.standingOn = platform;
    this.y = platform.y;
}

The next part in the update function of the GameController checks for collision of the player and the coins, which is trivial. We do the usual updating of the player's score and remove the coins.

Step 7 - Player's update Function

There are some major changes in the update function of the player which are worth highlighting. Remember that this game is now scrollable, meaning that when the player moves, the window will scroll accordingly. We will only look at scrolling in the x direction, and not in the y direction.

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public function update()
{
    //Move Horizontally
    if (this.speedX < 0)
    {
        //Check if player should move
        if (MovieClip(root).playerShouldMoveLeft())
        {
            this.x += this.speedX;
        }
        else
        {
            MovieClip(root).scrollGameObjects(-this.speedX);
        }
    }
    else if (this.speedX > 0)
    {
        //Check if player should move
        if (MovieClip(root).playerShouldMoveRight())
        {
            this.x += this.speedX;
        }
        else
        {
            MovieClip(root).scrollGameObjects(-this.speedX);
        }
    }

You can see that in the new code, the movement in the x direction is no longer a straightforward modification based on speedX. This is actually related to relative velocity (argh... more Physics?!?)

To make the player perceive that the game character Tooney is moving to the right when the player hits the RIGHT key, we can simply just move Tooney's x position by a positive value. But, consider the fact that we can also move everything else in the x direction by a negative value. The illusion still remains that we see the player move to the right.

In line 35, we make a check back to the GameController to see if the player should be moving, or if the game objects should be moving. This is where the markers come in handy. Let's jump back to the GameController now.

233
234
235
236
237
public function playerShouldMoveLeft():Boolean
{
    return ((mcGameStage.mcStartMarker.x >= 0) ||
            (mcGameStage.mcEndMarker.x - player.x <= C.SCROLL_BOUND));
}

Examine the code above that determines if it is the player who should be moving, as opposed to the fact that the game objects should be scrolling.

scrollDiagram

This diagram above tries to illustrate who should scroll. Basically if the player is moving towards the end of the screen where the mcStartMarker or the mcEndMarker is already at the edge, then the player should be moving physically. Otherwise, where he has moved away from the markers enough, all the game objects stored in the gameObjects array will scroll instead to create this illusion of motion.

The markers move as well when the other gameObjects scroll. Their whole purpose in this game is to denote the front and back of the entire game level.

This is probably the hardest part to understand in this tutorial. Do take some time and examine the codes in detail.

The Game

And here you have it ... the working game! There are actually a lot more interesting mechanics we can add to the platform game, such as adding horizontally moving platforms, platforms that disappear when you land on them, monsters for you to step on, etc.

Download the Game Files

The files you need to create this game can be downloaded from here.

How To Play

Objective: Collect all the coins without letting Tooney fall off the platforms.

Controls: Press LEFT and RIGHT keys to move Tooney. Press SPACEBAR to jump.


Content on this page requires a newer version of Adobe Flash Player.

Get Adobe Flash player


Flash Resources
Preloader FPS Display Sounds & Music
Keycodes Name Generator
Game Development Resources
Sprite Sheets


Posted by Joseph

on 2014-04-18 14:32:57

@Cassandra, I suspect your update function might be running twice, hence the dramatic increase in update.

Can you add in a check between you add an event listener for update whether it already exists? Only add it if it doesn't exist.


Posted by Joseph

on 2014-04-18 14:31:31

Rachel, you can see how to add background scrolling in http://www.makeflashgames.com/tutorials/tut4.php

If you want some parts of the background scroll at different speeds, just assign a different scrolling speed to them.


Posted by Cassandra

on 2014-04-18 02:01:48

Ok, so I've fixed everything BUT when the game is finished and I hit play again, which takes you right back to the first level, the speed jumps up dramatically. I believe this is because in the update function there is nothing for the speed itself. Any ideas on how to fix this?


Posted by Jarrett R

on 2014-04-16 16:44:44

Hi there am just wondering if it is possible to get your permission to use this platform game for my school project. Would greatly appreciate it. If you could send a short email to me that would be great thank you.


Posted by Rachel

on 2014-04-15 13:34:29

Say we want to add clouds that scroll at a different speed than the rest of the background. Could you explain how to add something like this to the code?


Posted by Rafael Costa

on 2014-04-05 10:29:12

Thank you. You helped me in my work with flash.


Posted by Joseph

on 2014-03-31 22:01:46

@Cassandra: Hey, try debugging your game with CTRL+SHIFT+ENTER.
That will bring you to the exact line where the error occurred.


Posted by Joseph

on 2014-03-31 22:00:25

Thanks Ezekiel, I actually replied you in my other post. =)

Thanks for helping out as well!


Posted by Ezekiel

on 2014-03-30 06:23:33

I figured out the error for your downloaded game file.

In GameController.as file,

line 179, 188, and 199, should not have "var" written in the code. (since var i was already written in the scope)

After fixing that one more problem has a raised which was the scoring that wasn't working.

That because the font wasn't embedded.
just selected the font on the stage and go into the property. In the property tab, hit the embed button and then check the numberals box. Click OK.

The font will now be in the library which has fixed all the problems.

hope this helps. :D


Posted by Cassandra

on 2014-03-28 05:18:39

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at GameController/update()

can NOT figure out what is causing this, but it's making the speed wayyy amped up after level1 and not allowing the level transitions to work on level2


Posted by Cassandra

on 2014-03-27 12:59:02

That did help, very much!! Thank you!!


Posted by Joseph

on 2014-03-23 16:00:10

Cassandra, check out the File Download page. I added another file which contains a 2 stage version of the game.

Player transits over to the 2nd stage after collecting all the coins in the first stage.

Hope it helps you.


Posted by Cassandra

on 2014-03-17 11:27:05

I am trying to set up more levels to this, and while i have figured out how to create a secondary coin that was transfer between levels i am having a bit of trouble setting up the next level! I duplicated the player to player2, specific to stage2, but i cant figure out what to change as far as player2 class and private function startStage2 or what should be included. Help please!


Posted by Joseph

on 2014-02-09 22:49:10

@Kai: Hi Kai, I'm not too sure why that happened. Can you try copying out the downloaded file to another place, say the desktop, before opening? Not too sure if you're having rights problem to open from your downloaded folder.

Sorry, can't really help on this.


Posted by Kai

on 2014-01-12 03:54:31

I've downloaded the gamefiles through Chrome and have been trying to open them with Adobe, but there's always an error when attempting to open the files.
It really does just say that there's an error and my access is denied.

Is there any other way to run the game?


Posted by Joseph

on 2013-11-17 22:06:33

@Georgia: To place another object in the game stage and make it move, there are multiple ways to do it. If you're thinking of something like an enemy, then you would need to follow how the other things such as lifts, coins were done, i.e. create a new array called enemies, and during setupGame function, push it into the array accordingly.

A simple enemy would be one where maybe you can just check for hitTest between the player and it, and kill the player when they touch. A Super Mario style of enemy requires a bit more explanation that I can provide here I'm afraid. =/


Posted by Georgia

on 2013-11-14 08:19:00

Hey great tutorial! WOuld you be able to tell me how I would put an enemy in the game and when I place another object in the gamestage, it moves with the character, it doesn't stay put!! Please help i'm desperate and I need this for an assignment!


Posted by Joseph

on 2013-10-04 18:31:55

up and down should be doable with the same idea. Switch your x to y.


Posted by rhen

on 2013-09-29 16:05:38

hi.. your game here is scrollable (left and right)
how about up and down.. please help..


Posted by Joseph

on 2012-12-20 00:02:26

I would strongly advise you to learn AS3 instead of AS2.
Basically, AS3 is the newer version of Actionscript, and many many new libraries are already written only for AS3.

Although Flash is still very much backwards compatible, in terms of using all the new libraries that other people in the community are writing, apis for FB, etc, they are very much in AS3 already.

So, in short, move ahead with times and use AS3!


Posted by Leila

on 2012-11-22 07:53:02

Hi :3
I love all your tutorials~ They are really easy tou understand and I have only started to use Flash so I found them all really interesting. I have a project coming up in which I have to create my own game with a scoring system like a platform game but I noticed you work in Actionscript 3 ....whereas my teacher prefers us to work in actionscript 2 :<. I do not really know the difference between the two so umm..do you mind explaning it to me ? can you use the scripting in actionscript 3 in actionscript 2 ? I hope to hear from you soon and keep up all the amazing work :3 !


Posted by victor

on 2012-11-17 12:20:32

it will be great if you have a enemy tutorial for this


Posted by Joseph

on 2011-08-05 23:01:50

Hi Def,

For multiple stages, I recommend you look at my tower defence codes to see how I partition the timeline into different sections. I'd recommend that way.


Posted by Joseph

on 2011-08-05 23:00:44

CJ >> To add a wall, you probably can add in a wall movieclip into your game stage. (inside the setup game function, you probably need to add in another wall array)

Before the player moves each time, store its old x and y positions into variables.

Inside the game loop, add in an additional check to see if the player hitTest any wall. If so, reset the player back to its old x and y position.

Haven't thought through this carefully, but I think it should work.


Posted by Christopher Cummins

on 2011-07-08 14:21:04

Hello Mr. Tan,

Please let me compliment you on your tutorials; in my opinion these are easily some of the best AS3 games tutes freely available on the net. I am trying to implement vertical scrolling in your platform engine and can't seem to make it work. I've added top and bottom markers to the map and created some new functions like "playerShouldMoveY()" and "scrollGameObjectsY()" which are similar to your horizontal functions. However, I just can't seem to make things work correctly. Any insight into vertical scrolling would be appreciated. Thanks!


Posted by Def.

on 2011-06-20 16:51:20

Hi Daniel, thank you so much for your tutorials :) They helped me a lot. I would like to know how to make different levels for this kind of platform game. Should I create levels inside the mcGameStage movieclip? Or I should create brand new movieclip inside which I put the mcGameStage? I appreciate your help on this, sorry for my bad english, thanks a lot. :))


Posted by C.J.

on 2011-06-13 06:58:46

I want to thank you for such an insightful tutorial. I am trying to make a wall the player has to jump over but, since i made a level similar to Mario, my player just walks from the one x coordinate to the next. I guess I have to make the character code look for elevations in the y-axis as the player walks across the floor level. Can you help me figure out how to add this to my code? Am I on the right path at least in concept? Thanks in advance.


Posted by Joseph

on 2010-09-16 00:01:34

Hi Daniel, thanks for dropping by! I think I know what the problem is, and it seems that it has got to do with the external js file that needs to accompany these swf files. Those tutorials that need keyboard input somehow don't work sometimes. The catcher tutorial doesn't need keyboard inputs, so it is fine.

Actually, there was a bit of problem yesterday (or the day before), possibly the time when you visited. But I fixed it (or I thought I did) already.

As of now, it works, at least for me, over my browser. If it doesn't for you, mind letting me know which browser you're using?

The other thing is, if you were to download the entire set of files, and run the swf by yourself, it should work actually. The codes in the tutorial should work fine.

I'm currently working on the Tower Defence tutorial, updating it bits and pieces as I go along, you should be able to find it under Advanced Tutorials now to see the progress so far.


Posted by Daniel

on 2010-09-14 11:04:30

I really appreciate the tutorials :) they're helping me in creating my flash game. I'm wondering though- it seems someone before me had this problem too but the games don't work for me on this website. The Catcher Tutorial game worked but besides that one none of them have been working.

Anyway I really appreciate the tutorials and hope your next set comes out soon :)


Posted by Joseph

on 2010-08-05 20:22:30

Hi Tommie, nice of you to drop by.
I'm preparing a next series of tutorials, probably by end of next month. :) Stay tuned!

Good suggestion on the date, thanks!


Posted by Tommie

on 2010-07-28 06:42:05

Nice!
I just ran through your serie of tutorials and got a few ideas out of it! Too bad it ends just about where my current knowledge extends :<

I like the constants-file and a few other things that will be implemented in my workflow and await further tutorials with great excitement!

Maybe a more advanced side-scroller with some sort of map system for bigger levels? Would love to see how you'd handle that on a novice-programmer level.

Also, you should specify the date in which the tutorials were created. Helps alot when googling through tons of tutorials, some stretching back ages in time.


Flash Tutorial Links:
Play Games: HTML5 Tutorials:
gaming tools download on app store now!
Home | About Us | Contact Us
Powered by Make Flash Games. All Rights Reserved.
By Joseph Tan