This is the fastest way to make basic platformer movement in GameMaker (yes, it supports slopes!).
This will be the end result:
We’ll get there in 3 easy steps. You can also follow along the video:
How to create an asset?
Scroll down to Step 1 if you already know how.
If you haven’t used GameMaker before, you should know how to create assets.
GameMaker has the “Asset Browser” on the right, which lists all your assets.
At the top you have a (+) button – click on this and a menu will open:
Here, double click on the type of asset you want to create – in this tutorial we will use sprites and objects.
After an asset is made, it will show up in your Asset Browser, where you can rename it and double click to edit it.
Step 1: Sprites
Create a new project, and create two sprites: spr_player and spr_ground.
One is for the player, and the other for ground that the player will stand on.
You can use “Edit Image” to draw them within GameMaker, or use “Import” to import PNG files – download mine here.
If you plan to rotate your ground, make sure to set its collision mask to “Rectangle with Rotation”:
Step 2: Objects
Now create two objects: obj_player and obj_ground.
Give them the spr_player and spr_ground sprites, respectively.
Before coding anything, let’s put these in the room.
In your Asset Browser, open the “Rooms” group and double click on Room1.
Drag obj_player into the room, and also place some ground instances to make a level.
You can select obj_ground, and then hold down Alt (or Option on Mac) to paint it in the room.
I will also be stretching and rotating some of my ground instances to make slopes:
For my wall sprites, I’m using Nine Slice so the pattern repeats instead of stretching.
Step 3: Player
Let’s program the player to move. Double click on obj_player in your Asset Browser.
In your Object Editor, see the “Events” window – here, press “Add Event”:
Add the Create event.
You may be asked to choose between GML Code and GML Visual. You can select either as this tutorial shows both.Make sure to enable “Don’t ask again for this project”.
Create Event
In this event we’ll create four variables:
move_speed = 4;
jump_speed = 16;
move_x = 0;
move_y = 0;
move_speed and jump_speed store how fast the player walks and jumps, respectively.
move_x and move_y store how much the player should move horizontally and vertically – they will be re-calculated every frame.
For running calculations every frame of the game, let’s add the Step event.
Step Event
We’ll add code into this event in two parts.
In the first part, let’s take input for walking, and control jumping and falling:
move_x = keyboard_check(vk_right) - keyboard_check(vk_left);
move_x *= move_speed;
if (place_meeting(x, y+2, obj_ground))
{
move_y = 0;
if (keyboard_check(vk_space)) move_y = -jump_speed;
}
else if (move_y < 10) move_y += 1;
Here’s how this handles horizontal movement:
- It gets horizontal input from the right and left arrow keys, in a way that right gets 1, and left gets -1
- It multiplies those values with the move_speed
For vertical movement, i.e. jumping and falling, it does this:
- It checks if there is ground below the player (by checking +2 pixels below it)
- If there is ground, it sets move_y to 0 to reset the fall speed
- Then it checks if space is pressed, and in that case, sets move_y to negative jump_speed so the player shoots up into the air
- The final block runs if the player is not standing on ground, as it’s an else
- It checks if move_y is below 10, and increases it – this is gravity
- It checks if move_y is below 10, and increases it – this is gravity
This won’t make the player move yet, for that we need to call move_and_collide().
In the same event, at the bottom (outside of any conditions) add this:
move_and_collide(move_x, move_y, obj_ground);
if (move_x != 0) image_xscale = sign(move_x);
This moves the player using our move_x and move_y values, and avoids obj_ground.
If move_x is not 0, meaning the player is walking, it sets the image_xscale to its sign (1 or -1). This means the sprite will flip to face left/right depending on where it’s walking.
Run the game, and you have a basic platformer!
Moving Down Slopes
Let’s fix moving down slopes:
For this, we’re gonna add code just before checking for the jump input, here:
We’ll check if there’s no ground where the player is going to move, but then we’ll check a few more pixels below, in case there is ground, just a bit lower than usual. This is how we’ll check for a downward slope.
Let’s add this:
if (!place_meeting(x+move_x, y+2, obj_ground) && place_meeting(x+move_x, y+10, obj_ground))
{
move_y = abs(move_x);
move_x = 0;
}
When it finds a downward slope, it transfers the horizontal speed (move_x) into downward speed (move_y) – we know it’s downward as we use abs() to convert negative values to positive.
Then we set move_x to 0 so there is no horizontal movement.
This will cause the player to only move downward, hit the slope, and slide along it.
Limiting Movement
It can be useful to limit the player’s movement, to avoid it getting faster when hitting ground above or below you – this is due to its vertical velocity being directed towards its walking speed.
This can be avoided by specifying maximum speeds in move_and_collide(), which are the final two arguments of that function:
move_and_collide(move_x, move_y, obj_ground, 4, 0, 0, move_speed, -1);
The first three new arguments (4, 0, 0) are optional, and we’re only specifying the default values so we can get to the last two arguments.
The last two arguments are the maximum amount that the player can move on the X and Y axes. I’m only passing move_speed for the X limit, so it doesn’t move faster than our defined walking speed.
For the Y limit, I’m passing in -1, so the Y speed is not limited.
With this, you no longer get the issue shown in the GIF above.
Shape Collisions
This function supports collisions for sprites of any shape – e.g. ellipse, diamond and precise shapes:
Using an ellipse shape for my player
Using a precise shape for this diagonal wall
Throw these shapes into the game and they will work perfectly:
Invisible Objects
If you’re primarily using tiles for your environment, you can still continue to use objects such as obj_ground for collisions. Just make the object invisible:
Place your ground instances in your room to cover your tiles. These will continue to work in the game, but won’t be visible to the player.
Read the move_and_collide() manual page for more info.
Also see: Easy Movement And Collisions in GameMaker
Happy GameMaking!