LearnGML

Lets Make a Game #2: Movement

Armed with new knowledge, lets spice up our barebones game. First, lets get our little green square moving.

Planning

In Gamemaker, the position of an object on the screen is determined by its x and y variables. In Gamemaker x is positive going right and y is positive going down, therefore if you increase an objects x and y it will move towards the bottom right corner of the screen. Therefore to get our player object moving, we need to adjust it’s x and y values when the player presses the appropriate buttons.

Planning out your code before writing it is a critically important and often overlooked step to becoming a better programmer. So, let us figure out a basic idea of what we want to be doing here:

Goal:

  • To implement basic 8 directional movement

Steps:

  • We need to receive player inputs for the four cardinal directions (up, down, left, right)
  • We need to determine which direction the player object should move based on the received inputs
  • We need to update the player object’s position based on that direction and it’s speed.

Programming Time

To achieve the first step, we will be using the keyboard_check function to determine which, if any, of the arrow keys are being pressed.


/// STEP EVENT
x_dir = keyboard_check(vk_right) - keyboard_check(vk_left);
y_dir = keyboard_check(vk_down) - keyboard_check(vk_up);

There is something wrong with this code, can you figure out what? We forgot to initialise out variables before using them! Lets do that in the Create event:


/// CREATE EVENT
x_dir = 0;
y_dir = 0;

Much better. Now, how does this code work? The keyboard_check function returns True if that key is being pressed and False if it isn’t. In GML True is equivalent to 1 and False is equivalent to 0, therefore we can use them in mathemtical expressions. You may remember that the positive x direction in Gamemaker is to the right and the negative x direction if to the left? Therefore, if the player is pressing the right arrow key then we want their x_dir to be positive, and if they are pressing the left arrow key we want it to be negative, and if neither (or both) are pressed we want it to be nothing. The little equation achieves this result, as for example if the player presses the right arrow key but not the left, x_dir becomes equal to 1 - 0, or 1. Try to think through what happens in the other possible scenarios, as well as for y_dir (remember that up is the negative y direction).

Now that we know which x direction and which y direction the player wants the player object to move, lets add some more code to the Step event to determine the final direction that the player object should move (remember to initialise any new variables in the Create event):


if (x_dir != 0 || y_dir != 0)
{
    dir = point_direction(0, 0, x_dir, y_dir);
    x_spd = lengthdir_x(spd, dir);
    y_spd = lengthdir_y(spd, dir);
}

First, this section of code will only run if either x_spd or y_spd are not equal to 0, ie. if the player actually wants to move in any direction. You will learn more about if statements shortly. If this is the case, then the actual direction that the player object will move is calculated using the point_direction function. This will return either one of the four cardinal directions or one of the four diagonals. Then, we use a bit of trigonometry to work out what the specific x speed and y speed values should be. This ensures that when the player moves diagonally they don’t accidentally move faster than they would if they were just moving horizontally or vertically. This trigonometry is done with the lengthdir_x and lengthdir_y functions, which makes things simpler (although you can do the trigonometry manually if you wish). The spd variable is the number of pixels the player object should move each step, it is best to set this to something small like 4 to begin with and experiment later.

Now that we know how much the player object should move along the x axis and y axis, we can finally update the player object’s position at the end of the step event:


x += x_spd;
y += y_spd;

Note that although we are using the += operator, if x_spd or y_spd are negative then x or y will be reduced, as adding a negative number is equivalent to subtracting.

Finally, lets reset x_spd and y_spd so that if the player stops pressing any arrow keys next step the player object will stop moving.


x_spd = 0;
y_spd = 0;

Overall, your player object’s code should look something like this:


/// CREATE EVENT

x_dir = 0;
y_dir = 0;
dir   = 0;
x_spd = 0;
y_spd = 0;
spd   = 4;

 


/// STEP EVENT

/// MOVEMENT

// UPDATE PLAYER INPUT

x_dir = keyboard_check(vk_right) - keyboard_check(vk_left);
y_dir = keyboard_check(vk_down) - keyboard_check(vk_up);

// UPDATE DIRECTION

if (x_dir != 0 || y_dir != 0)
{
    dir = point_direction(0, 0, x_dir, y_dir);
    x_spd = lengthdir_x(spd, dir);
    y_spd = lengthdir_y(spd, dir);
}

// UPDATE POSITION

x += x_spd;
y += y_spd;

// RESET MOVEMENT VARIABLES

x_spd = 0;
y_spd = 0;

Now if you run your game and press the arrow keys, your little green square should move! If it moves correctly, congratulations! If not, make sure to reread the instructions above and check the manual entries for the functions used to make sure you are using them correctly.