Creating Platform Games (GameMaker)
#1
This article was archived in February 2002
when GameMaker 4 was released.
I probably snagged it at GamingWorld
Yet concepts should still hold.



Creating Platform Games
Copyright 2002 by Mark Overmars
New version based on Game Maker 4.2

Platform games are very common, in particular on devices like the Game Boy. In a platform game you look at the scene from the side. The player normally controls a character that walks around in the world. This world consists of platforms. The player can walk on these platforms, jump or drop from one platform to the other, use ladders or ropes to get to different places, etc. On the platforms there are objects to collect, enemies to avoid or kill (often either by shooting them or by jumping on top of them), switches to press to open passages, etc. Also the player normally requires skill to jump over dangerous areas. In some platform games you see the whole level at once, but in most you see only a part around the character. In such a case, finding your way around becomes an additional challenge.

Creating a good platform game is not trivial, also not with Game Maker. There are three difficult aspects:
  • Creating a natural motion for the character.
  • Creating enough variation in monsters, background, etc.
  • Carefully designing the levels such that they are fun to play and get increasingly difficult.

In this tutorial I will give some advice and tricks about how to create platform games using Game Maker. The tutorial requires that you have version 4.2 of Game Maker or later. The tutorial is accompanied by a number of demo games. These are not full games. They consist of just one level to demonstrate some particular aspect. You can use them as a basis for your own platform games.

The basics
We start with the most simple platform game. You can find it in the file platform_basic.gmd (ATTACHED). In each platform game there are two basic objects: the character controlled by the player, and a block object that is used for the floors (platforms) the player can walk on and the walls that the player cannot pass. We need two sprites: one for the character and one for the block. For the character we use a simple ball. For the block we use a (non-transparent) black square. We create two objects: a solid block object with the block sprite and a character object.

Horizontal motion
We now need to define the motion of the character. The problem is that the character must walk on top of the floors. It must not intersect the floor. If the character jumps or falls off a platform it must land correctly on the next platform. There are a number of different ways in which the character can walk, jump, and fall. Different platform games use different modes. Normally we just use three keys to control the motion. The left arrow key should move the character to the left, the right arrow key should move it to the right, and the up key or the space key makes it jump.
Let us first consider the left and right motion. The first choice to make it whether the player can only change its direction of motion while on a platform or also in the air while jumping or falling. Even though the second option is not natural (it is rather difficult to start moving left while you are falling down) is tends to lead to nicer game play and is actually also easier to implement. The second choice is whether the motion has constant speed or whether it accelerates when you keep the key pressed. We will opt for the first choice. Unfortunately we cannot use the actions to set the direction of motion. The reason is that this would interfere with the vertical motion used for jumping and falling (and later climbing). Instead we simply change the position. We can either use actions or code for this. Using actions we do the following. In the event for the left arrow key we need one action to test whether a position is empty. Give as relative values -4 and 0. (So we test whether the position left of the current one is empty.) The next action, that is executed only is the position is indeed true, lets the character jump relative to position –4, 0. Do the same for the right key event but now using 4 rather than –4. In code we use the following:
{
  if place_free(x-4,y) x -= 4;
}

4 indicates the speed, that you can change if you like.


Jumping
Next we need the vertical motion. This is more difficult. To let the character fall down we can use gravity. But it should stop moving when we hit the floor. Also, you normally want a maximal falling speed, otherwise the character will move too fast. (This is both not very pleasing but it can also cause problems in the implementation.)  To this end we put the following piece of code in the step event of the character. It sets the gravity based on whether there is something below the character (by checking whether the position 1 pixel below the character is free). Also it limits the vertical speed.
{
  // set the gravity
  gravity_direction = 270;
  if place_free(x,y+1)
    gravity = 0.5
  else
    gravity = 0;
  // limit the speed
  if (vspeed > 12) vspeed = 12;
}

Next we have to land. This is more difficult than it might seem. It will happen when the character collides with the block object. In this collision event we should set the vertical motion to 0. But this might leave the character hanging a bit in the air above the ground. (The reason is that the character is placed back to its previous position before the collision.) To this end we want to move the character downwards until it hits a block. We do though need to do this only when two conditions hold: the character is falling down (so vspeed > 0) and there is a block directly below us (so not place_free(x,y+vspeed)). Otherwise there can be (rare) cases where the character suddenly jumps up or down. This is achieved by the following piece of code, which must be placed in the collision event with the block:
{
  if (vspeed > 0 && not place_free(x,y+vspeed)) move_contact(270);
  vspeed = 0;
}

Finally we have to let the character jump when the up arrow key is pressed. But this must only happen when the character is currently on the floor. This can be achieved by the following code.
{
  if (not place_free(x,y+1)) vspeed = -10;
}

You might have to play a bit with the vale of 10 for the vertical speed and the value of 0.5 for the friction to get the motion you want.
Now the basis for the platform game is ready. Design a level with some floors and walls, constructed from block and a character is in, and you can move the character around. Note that most of the code above can also be done using actions. Only the move_contact() function is not available as an action.


Better graphics
The basic platform game we created in the previous section works but looks rather bad. There are two aspects we want to change: the way the player looks, and the way the background looks. The adapted game can be found in the file platform_graphics.gmd (ATTACHED).


The character images
Let's start with the character graphics. We will use two different (non-animated) sprites: one for the character facing to the left and one for the character facing to the right. The easiest now is to place in the event for the left arrow key an action to change the sprite to the one facing left. Similar, in the right arrow key you switch to the one with the character facing right. You probably don't want to use precise collision checking for the two sprites. This avoid that the sprite get stuck halfway down the edge of the platform. Finally, you better make sure that the bounding boxes of the sprites are the same. Otherwise, switching from left to right might cause problems in rare situations. (You can always use manual bounding boxes for this.)
In more advanced games you will probably want to use animated sprites. In this case you also need a sprite for the character when it is not moving. Also you might want to add sprites for the character jumping, falling, shooting, etc. In this case you will have to change the sprite at various places in the events. In particular, in the no key event you probably want to set the sprite to the no moving one. Alternatively, you can draw the correct sprite in the drawing event based on the situation. For example, you can check whether xprevious<x to find out whether the character has moved to the right.


The platforms and walls
Secondly we want to improve the background and the platforms. Here we use a standard technique. 
Rather than using objects for all the different wall and floor elements, we use so-called tiles. Tiles are pieces of background images that are drawn at particular places in the room. They do not have associated events nor do they create collision. The good part is that they are fast and use little memory. So you can create large rooms without the need for large images.
To add tiles to your rooms you first need a background image that contains the tiles. Tiles in a background image preferably have a fixed size and have a little (1-pixel) border between them such that they can easily be separated. A number of tile sets are provided with Game Maker but you can find many more on the web. For our simple platform game we made our own, small one. We added it as a transparent background resource named background_tiles.
Now, when creating a room, you can click on the Tiles tab page. You can select the tile set (that is, the appropriate background resource) and you might have to indicate the tile width, height, and separator size. Now you can draw tiles by clicking on the appropriate tile and next placing them in the room, like you would do for objects. The right mouse button deletes tiles. Use your imagination to create challenging rooms. (Note that you can also place foreground tiles. These will always lie in front of the moving characters. We will not use them here but they are great for giving a better 3D effect.)
We will draw all the nice platforms and walls on the background image. For this we use the option to create a tiled background. (See chapter 15 of the documentation.) You can use a second background to give the platforms again a nice background. In this case don't forget to make the background with the platforms transparent.
There is a problem left though. As indicated above, tiles are just nice graphics. They do not generate events or collisions. So the character would fall straight through them. To avoid this we still need the block objects we had before. We place the block objects at the appropriate places on top of the walls and platforms you did create with the tiles on the background. Now by making the block objects invisible you will not see the black blocks but the beautiful tiles. But the block objects are actually there, so the character cannot pass through the walls and will land on the platforms. There might be one problem here. The 16x16 block objects might be too large to cover the background nicely. So we want to make a few other block objects of size 16x8 and 8x16. Again we make them solid. To avoid having to specify collision events with these as well, in the Advanced tab of the objects set the parent to the block object. In this way they will be treated the same as the bigger block.


Threats and treats
Just jumping around from platform to platform is rather boring. You definitely need some more challenges and goals. In this section we treat a number of these. Check out the game platform_monsters.gmd (ATTACHED) for the result.


Monsters
Let us first add some monsters. We will make two monsters, one that moves left and right on a platform and the other that flies left and right in the sky. Jumping on top of it can squash the first one; the second one should be avoided at all times.

Let's start with the monster that moves on the platforms. We need two sprites for it, one with the monster facing left and the other with the monster facing right. Now we create the monster object. In the creation event we let it move to the right with a particular speed. Whenever it hits a wall it reverses its horizontal speed. To draw the correct sprite we put the following code in the drawing event:

{
  if (hspeed > 0)
    draw_sprite(sprite_monsterr,-1,x,y)
  else
    draw_sprite(sprite_monsterl,-1,x,y);
}
Based on the value of the variable hspeed (that indicates the horizontal speed) we draw the correct sprite.
To avoid monsters from falling off platforms, we introduce another object, which we call a marker. This marker will be an invisible red block. Whenever a monster touches it, it reverses its orientation.
When the character hits a monster the monster or the character should die. To find out what must happen, in the collision event of the character with the monster we perform the following test:
vspeed > 0 && y < other.y+8
If the result is true, the character is moving downwards and hitting the top part of the monster. This means the monster must be destroyed. (In the example we turn the monster into a dead monster, which destroys itself after a while. This gives a nicer graphical effect.) In this simple platform game, dying for the character corresponds to restarting the level, which can be achieved by some simple actions.
The flying monster is even easier. We proceed in exactly the same way. Only, in the collision event of the character with the flying monster, no test needs to be performed.
You might want to add some more monsters, e.g. with different speeds, to make things harder. You can also make a monster or rock that falls down or moves up and down. Just use your own imagination.


Pits
Most platform games require careful timing of jump to avoid falling into pits. Falling into a pit normally kills the character. To this end, we add a new object, called death. This object is a red block that again is not visible. You can place it at the bottom of the pit. (In the background image you can put some spikes there.) In the collision event of the character with the death object it should play a sound, wait a while, and restart the room. You can also make pits that go down infinitely. In this case you want to add similar actions in the outside event (in the other events) of the character, maybe including a test the y > room_height to make sure the character fell down, rather than jumped up outside the playing field.

Collecting points
Most platform games have some mechanism in which the player can collect points. Normally you have to pick up certain objects or catch certain things. In our example the player can collect mushrooms. So we make a mushroom object. To give a bit of variation, the mushroom sprite contains 10 different mushrooms. The mushroom object picks one at random upon creation. To this end we set the variable image_single to random(10). In the collision event of the character with the mushroom object we play a sound, destroy the other object and add 10 to the score.
In some platform games, collecting things has a more important function than just raising your score. For example, you might get an extra life when you collect enough objects. Also there might be objects that restore your health (assuming monsters don't kill you but simply weaken you), make you move faster, jump higher, etc.

Next level
Of course there should be a way to finish a level, such that the player can move on to the next level. To this end, we create a levelexit object. When the character gets there you are moved to the next level. In the example this is done rather simple. We only added a test whether room==room_last. if this test is true we are at the last level so we can no longer move to the next one. Instead the highscore list is shown and the game is restarted.
You might choose to make the levelexit only appear when for example all mushrooms have been collected. To this end, in the creation event of the levelexit object, it is move to a position –100,-100 (so off the screen). Now in the step event of the levelexit we check whether the number of mushroom objects is equal to 0 and, if so, move the levelexit object back to its starting position.


More motions
Our current platform game has just some limited motion possibilities. The character can move left and right, and it can jump. To make things more interesting, let us add some possibilities. The result can be found in the game platform_motions.gmd (ATTACHED) .


Ramps
It is nice if the player can walk up sloping ramps (down goes automatically because of the falling). To this end, we have to replace the code in the left arrow key event. We put there the following:

{
  for (i=0; i<= 8; i +=1)
  {
    if place_free(x-4,y-i) { x -= 4; y -= i; exit; }
  }
}

This might be a bit difficult to understand. What the code does is try all choices for i from 0 to 8. For each of those it checks whether position x-4,y-i is empty. If so, it moves the character there and exits the code. So the program first tries whether we can move just to the left. If not it tries to move one pixel up. If that does not work, it tries two pixels up, etc. (We go on till 8 to also allow walking up a sort of stairway.) Similar code must be put in the right arrow key event. That is all.

Ladders
People always want ladders in platform game along which the character can move from one platform to the other. This requires a bit of work. A ladder will be represented by a thin vertical block that is invisible (the real ladder or vine or whatever that is used for climbing is drawn using tiles) and not solid. When the character is not in contact with a ladder motion should be as before. But when it is in contact with the ladder things must go different. First of all, the character should not fall down. So in the step event we have to make a change to this effect and add the following code at the end:
  // check for a ladder
  if place_meeting(x,y,ladder)
    { gravity = 0; vspeed = 0; }

The second thing that needs to change are the actions for the up key. When the character is at a ladder, the up arrow key should move it up, rather than jump. So the new code becomes:
{
  if place_meeting(x,y,ladder)
  {
    if place_free(x,y-3) y -= 3;
  }
  else if (not place_free(x,y+1)) vspeed = -10;
}

Also, the down arrow key should slowly move the character down the ladder, using a similar piece of code. Finally, you might want to create a separate sprite for the climbing character and, in the step event, change the sprite when in contact with a ladder.

Using a view
Up to now we always showed the entire room. For many platform games this is not what you want. Instead you want to see only a part of the room, around the character you are controlling. Fortunately this is extremely simple to achieve in Game Maker. When designing the room, click on the Views tab. Click on the checkbox Enable the use of Views to start using views. Select the first view and check the box Visible when room starts to make sure this view can be seen. Give it a width of 300 and a height of 200 (or something else that you like). (As we are going to let the view follow the character there is no need the specify the left and top position of the view in the room. Also, because we use just one view, we don't have to specify the x and y position of the view on the screen.) As the object to follow we choose at the bottom the character. The view will now automatically move to keep the character in focus. We don’t want the character to get too close to the border. To this end we set the Hbor and Vbor values to 64. There will now always be a 64 pixel area visible around the character. Finally, to get a smooth view motion we set the maximal view speed to 4. (This also gives a very nice effect at the start because the character comes slowly into view.) Having the view is nice but it makes the window in which things happen rather small. To avoid this, in the Game Options we set the scaling to 200 percent. Clearly you can play with these values to get the effect you want.


What next?
The sections above should have given you a number of the basics of making platform games. Now it is your turn. You will have to use these techniques and some more ideas of yourself to create a real nice platform game. Remember that the most crucial part of platform games is the levels. Start making levels one by one. Play them until you are happy with them. Every so often, introduce some new game play aspect. Here are some ideas that you can use:
  • different monsters, e.g. bouncing balls and monsters that shoot
  • the ability of the player to shoot monsters (maybe only after a gun is found)
  • keys that you need to find in order to open doors
  • mines that you can place somewhere and that go off when a monster (or yourself) steps on them
  • water to swim in (this will completely change the motions; no gravity anymore, or a mild upwards gravity until you reach the surface, limited time before you run out of air, air bubbles to grab, etc.)
  • walls and floors you can destroy, e.g. by shooting them or jumping on them with force
  • trampolines that make you jump higher
  • platforms that appear and disappear
  • one-way streets
  • moving platforms (this is not easy!)


Good luck.


Attached Files Thumbnail(s)
   

.zip   Platform Examples.zip (Size: 160.49 KB / Downloads: 13)
Up is down, left is right and sideways is straight ahead. - Cord "Circle of Iron", 1978 (written by Bruce Lee and James Coburn... really...)

[Image: QrnbKlx.jpg]
[Image: sGz1ErF.png]    [Image: liM4ikn.png]    [Image: fdzKgZA.png]    [Image: sj0H81z.png]
[Image: QL7oRau.png]    [Image: uSqjY09.png]    [Image: GAA3qE9.png]    [Image: 2Hmnx1G.png]    [Image: BwtNdKw.png%5B]
  Above are clickable links
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
   Smile Game Builder: Octopath Traveler Series by Jacob - DrassRay of Drattzy Games! JayRay 0 2,438 01-14-2023, 08:31 PM
Last Post: JayRay
   Horror in games DerVVulfman 0 4,238 05-17-2011, 05:23 AM
Last Post: DerVVulfman
   Creating a Proper Game Doc United Washcloth Express 2 7,622 02-22-2010, 11:33 PM
Last Post: Ace
   Creating a perfect storm MagitekElite 0 4,284 02-17-2010, 07:07 AM
Last Post: MagitekElite
   Creating Your Own Scripting System DerVVulfman 3 8,383 10-12-2009, 03:37 PM
Last Post: Alpha-Mad
   Creating a Custom Window by RPG Advocate DerVVulfman 0 4,378 03-11-2009, 06:49 PM
Last Post: DerVVulfman
   Languages in Games III Stevester 0 3,815 02-23-2009, 11:55 PM
Last Post: Stevester
   Languages in Games II Stevester 0 3,960 02-23-2009, 11:53 PM
Last Post: Stevester
   Languages in Games Stevester 0 3,745 02-23-2009, 11:52 PM
Last Post: Stevester
   Creating Believable Characters ccoa 0 4,719 12-06-2008, 05:13 PM
Last Post: ccoa



Users browsing this thread: 1 Guest(s)