This is the easiest way to move in GameMaker, with proper collisions, which only takes a few minutes to set up.
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_wall.
One is for the player, and the other for walls that will stop the player.
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 walls, make sure to set its collision mask to “Rectangle with Rotation”:
Step 2: Objects
Now create two objects: obj_player and obj_wall.
Give them the spr_player and spr_wall 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 walls.
You can select obj_wall, and then hold down Alt (or Option on Mac) to paint walls in the room.
I will also be stretching and rotating some of my walls to make a tiny level blockout:
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”.
In this event we only want to create a variable:
my_speed = 4;
I’m creating the variable my_speed to store how fast the player moves. You can change this to make it faster or slower.
Now, add the Step event.
Here, we’ll take input from the keyboard, and move the player:
var _xinput = keyboard_check(vk_right) - keyboard_check(vk_left); var _yinput = keyboard_check(vk_down) - keyboard_check(vk_up); move_and_collide(_xinput * my_speed, _yinput * my_speed, obj_wall);
Here we are doing this:
- We get input from the left, right, up, down arrow keys
- We do some math to get the X direction (1 or -1) and the Y direction (1 or -1)
- That is passed into the move_and_collide() function
- Before being passed in, the X and Y directions are multiplied by my_speed, which we defined in the Create event
Run the game and you have movement!
To WASD keys instead of arrow keys, replace the vk_* etc. constants with:
vk_left -> ord(“A”)
vk_right -> ord(“D”)
vk_up -> ord(“W”)
vk_down -> ord(“S”)
You can also use both arrow keys and WASD at the same time, by joining them with ‘or’ e.g. (keyboard_check(vk_left) or keyboard_check(ord(“A”)).
If you try to move diagonally (e.g. hold both right and down at the same time) and slide along a wall, you’ll notice the player moves faster than it normally would.
You can fix this by setting a limit on how fast the player can move on any axis. This is set in the last two arguments of move_and_collide().
I’ll change my move_and_collide() line/action to this:
move_and_collide(_xinput * my_speed, _yinput * my_speed, obj_wall, 4, 0, 0, my_speed, my_speed);
There are 5 new arguments here:
- The initial three (4, 0, 0) are arguments I don’t want to change, so I’ve passed in their default values as per the manual.
- The last two arguments are the X and Y speed limits of the player. I’ve passed in my_speed for both.
Now, the player won’t move faster when moving diagonally while sliding along walls.
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:
If you’re primarily using tiles for your environment, you can still continue to use objects such as obj_wall for collisions. Just make the object invisible:
Place your wall 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: Fastest Way To Make A Platformer in GameMaker