Home > SoulHow > SoulHow to Make a Platform Game (Game Maker)

SoulHow to Make a Platform Game (Game Maker)

May 29, 2008

NOTE: Comments are locked. I no longer answer questions about the Game Maker tutorials on this blog; I suggest you take any questions to the Game Maker Community. For more info, view the FAQ page.

Skill Level: Intermediate user (5)

This is the first of the SoulHow Game Maker assistance guides. I’m going to discuss how to make a snazzy platform game engine. We will be using Game Maker Version 7.0, but it…might…work in earlier versions. I don’t know because I don’t feel like checking. If you don’t have the program at all, get it here.

You can build on other features to this example after you enter the basic code given in the guide.   In addition, if you feel like doing something another way, go ahead, because this guide is as much an idea spawner as it is an example. By the way, you’ll need to understand how to use GML. If you don’t, it’s not that hard, so bring up the GM manual and get cracking. In addition, this guide assumes you understand how to do things like creating and drawing sprites, making objects, and other GM basics. You’ll know if you understand them or not; if you don’t, again, just read the GM manual.

Ok, moving right along, let’s open Game Maker and click the “New Game” icon. It’s the little blank page, you know, the same one in every program out there.

Now we have complete blankness, so first we need some sprites. Create three sprites, and draw a character in each one in a different pose. First, standing (named sprPlayerStand), then walking (sprPlayerWalk), then in the air (sprPlayerInAir). I’m going to assume the only animated sprite is the walking one. Make sure all the sprites have precise collision checking off, so it uses a rectangle to check for collisions instead of the sprite, and also make sure their origins are centered (click the “center” button). NOTE: This assumes your player sprites are centered in the middle of the frame. If not, you’re going to have to set the origin to midway between the bounding box values. For example, if the left value is 10 and the right value is 25, set the x origin to midway between those which is 18. Do something similar with the y origin using the top and bottom bounding box values.

The last sprite we need is a temporary block sprite, so make a 16×16 sprite and fill it with black. Turn off transparent so we can see the black color, and close out.

Finally, we get to make some objects! Create two objects and call them objPlayer and objBlock. DON’T make objBlock solid, contrary to what most people would tell you. I have another article on this blog explaining why. Yes, our block sprite looks ugly right now, but that can be fixed by simply turning the blocks invisible and making a tileset to put over the blocks (not covered in this guide, but shouldn’t be too difficult for you to figure out if you don’t already know how)

Now close out of the block object, as we don’t need to do anything with it (the poor thing doesn’t even get any code).

objPlayer needs two pieces of code, though. Let’s start at the create event. We want some variables that tell our player things like how fast to run and how high to jump, along with which way for the object to move. Here’s what I did:

//Set up some variables for certain speeds
walksp=4; //Walking speed (4 pixels per frame)
jumpsp=-14; //Jumping speed (negative because it goes up)
grav=1; //Gravity strength (usually a small value)
//These variables are actually used to move the player
hsp=0; //Horizontal speed
vsp=0; //Vertical speed
ground=1; //Whether the player is on the ground

Next, we move to the step event. We want to use the step event to do lots of things, including moving the player and checking for colliding with the wall. I’ll use comments to explain the code. I finally got the indentations to work, and in addition I’ve color-coded it to make it easier to read and understand.

//Keyboard constants
//We use these so we can just type the variables
//instead of "keyboard_check(*)"

//This one's for variable jump height:
//Now check if the player pressed left or right and move
   hsp=walksp; //Walk right
   image_xscale=1; //Face right
   hsp=-walksp; //Walk left
   image_xscale=-1; //Face left
//Stop moving when no keys are pressed
if (!KEY_RIGHT and !KEY_LEFT) hsp=0;
//Make sure we don't hit a wall
if (place_meeting(x+hsp,y,objBlock))
   //Move until contact with the wall
   if (hsp!=0)
      while (!place_meeting(x+sign(hsp),y,objBlock))
//Because we don't use hspeed, we got to move ourselves
//Now for vertical motion (jumping and falling)
//Is the player in the air?
if (place_meeting(x,y+1,objBlock)) grounded=1;
else grounded=0;
//Jump with the up key when on the ground
if (KEY_JUMP and grounded)
//If we're in air moving up and jump key is released, we remove
//upward motion (so we fall and get variable jump height)
if (KEY_FALL and !grounded and vsp<-1) vsp=-1;
//Fall with gravity
if (!grounded) vsp+=grav;
//Now it's more complicated.
//When hitting the ceiling, vertical speed must stop.
//The if statement says, "if we hit the ceiling and are moving up" 
if (place_meeting(x,y+vsp,objBlock) && vsp<0)
   //We must move up until contact with the ceiling
   while (!place_meeting(x,y+sign(vsp),objBlock)) y+=sign(vsp);
//But if we are moving down and hit the floor, we have to land
if (place_meeting(x,y+vsp,objBlock) and vsp>0)
   //Move so we hit the ground
   var cc;
   cc=vsp+1; //A counter, so we don't get an infinite loop
   //Move down until we hit the floor
   while (!place_meeting(x,y+1,objBlock) and cc>=0) y+=1;
   //Now ground the player
//Again, we're not using vspeed, so we have to move ourselves
//Animation - check what our sprite's state is and set accordingly
if (grounded) //If we're grounded
   if (hsp==0) //Then if we're not moving, change to stand sprite
      image_speed=0; //Don't animate
   else //But if we are moving, change to walk sprite
      //Reset image index if just now switching to walk sprite
      if (sprite_index!=sprPlayerWalk) image_index=0;
      image_speed=0.5; //Change this to whatever works for you
else //If we're not grounded, change to in air sprite
   image_speed=0; //Don't animate

The funny thing about this code is that the player never actually touches a wall. This generally makes for smoother gameplay. Note also that the reason the sprites are centered is because we use the image_xscale variable to control which direction the player is facing.

Well that’s all for now. Try out your newly created engine, and see how it runs. Put blocks wherever you want, and have the character jump on them. Copy this guide for now, but I encourage you to scan it and figure out just how it works so you can build on to it and change it to suit your preferences. Remember, the most important thing when using any sort of tutorial is to always make sure you understand why some bits of code work, instead of just knowing that they work.

If you enjoyed this article, please consider checking out the rest of the blog.

If you have a technical question, such as “How do I do this” or “this is not working right” (relative to something with your Game Maker game after reading this tutorial), please head over to the Game Maker Community and ask there.  I can’t answer any such questions in this blog and the members at the GMC will be more than capable to help you. See this blog’s FAQ page for more info.

To discuss this article in particular, you can view it on the Game Maker Community.

  1. Danny
    October 30, 2009 at 8:43 am

    you also reply to your comments really fast… i like that dont have to wait 5 days to get a question answered

  2. Danny
    October 30, 2009 at 8:42 am

    ok ill try that ty very much on all of your tuts!!!

  3. soulred12
    October 29, 2009 at 10:16 pm

    My last piece of advice is to make sure your block objects aren’t solid. If they’re solid, they’re going to cause problems.

    And I’m sorry, but I can’t look at your file because I don’t offer that kind of support for my tutorials anymore. See question 2 of the FAQ for more info. Besides, you’ll get much better support on the Game Maker Community (where many different users will look at your file), which is why I suggested posting there.

  4. soulred12
    October 29, 2009 at 6:55 pm

    Try starting your character out in the air. If the character starts out stuck in the ground or ceiling, you’re going to have problems. Other than that, I can only suggest reading my article on debugging (you can get there from the “tutorials” tab) or bringing the question to the Game Maker Community (link is at the bottom of the article) with a copy of your game.

    Unfortunately nobody else is reporting an error like the one you’re reporting, so it must be an issue with your file in particular. That could mean an odd level design, oddly-shaped sprites, or something similar…so if you post your file on the Game Maker Community along with the details of your problem you’ll likely get the help you need.

    • October 29, 2009 at 9:30 pm

      i do always start him out in the air… is there anyway that i could attach my .gmk file here in this forum or somewhere where you could get to it and let me know what im doin wrong? thank you very much

    • Danny
      October 29, 2009 at 9:46 pm

      i commented out this line of code …//We must move up until contact with the ceiling
      while (!place_meeting(x,y+sign(vsp),objBlock)) y+=sign(vsp);
      vsp=0… and it seems like the game runs its just that the player floats in the air

  5. October 29, 2009 at 3:06 pm


    Thank you i love all your tutorials (i learned gml with your tutorial) but theres one prob for me when i use this code. I copy and paste all of this code exactly make all the sprites centered and uncheck precide collision checkin i made sure tha the origin of the sprites is indeed in the middle of the player but one problem… i start the game i see my person on the floor in the jumping sprite and when i touch a button or something the game goes unresponsive and goes like a transparent grey and i have to use ctrl+alt+delete thing to close the game. I dont have any other code than this code and im usng game maker 7 pro

    thank you

  6. October 28, 2009 at 5:27 pm

    WOW! really coo, tutorial, this is definetly something I will use
    to improve my collisions. No more ground penetration disabling my movement.

    Thank You!

  7. Travis
    July 14, 2009 at 9:40 pm

    So, this guide is awesome, thought I found it on the Game Maker forums. I was even able to implement Double Jumping without any prior knowledge of GML (I’ve had Game Maker 7 Pro for about..2 days now). With that said, I am having trouble (This is slighty off topic to be honest, so feel free to ignore my comment) getting blocks to move up and down/back and forth on their own. IE: Crossing a gap on an automated block, getting it to goto a certain Y or X value and returning to it’s origin only to repeat the process. I had it working in another engine that used Solids, but I refuse to go back to that method. Any help would be greatly appreciated it. Aside from that, this is quite the great engine. Thanks!

  8. soulred12
    June 20, 2009 at 11:44 pm

    Hey guys,

    I usually don’t respond to questions here but since these ones aren’t overcomplicated I thought I’d go ahead and write back. ^_^

    @3dTestPattern: I don’t tend to experience this, but I can only guess that it’s something to do with the way your sprites’ bounding boxes are lined up with the sprite’s origin. If your sprite(s) either doesn’t (do not) take up the entire frame, or if they’re not centered and symmetrical, a perfectly centered origin probably won’t work.

    In this case, take a look at the bounding box numbers for the sprites, and for each origin, change the x value to halfway between the boundary’s “left” and “right” values. For example, if the bounding box’s left is 6 and right is 18, set the sprite origin’s x coordinate to 12. It might also be a good idea to check to make sure the bounding boxes are the same size (width and height) for each related sprite (such as each pose/action for the player); that may require setting the bounding box coordinates manually.

    @Cayce: The sign() function basically returns value/abs(value), which gives 1 if the value is positive, and -1 if the value is negative. Therefore, if you input sign(5) you get 1 and sign(-3) you get -1. sign(0) equals 0.

    Thanks for the compliments and I hope this helped you guys.

    • Cayce
      July 11, 2009 at 11:32 am

      Okay, that makes more sense. Gracias! :1

Comment pages
  1. No trackbacks yet.
Comments are closed.
%d bloggers like this: