• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML Making movement code better

B

Ban1_1

Guest
I need help with this code so that I don't have to write x += hspd and y += vspd underneath the code every time I want to make the object move. Any help will be appreciated

///Variables
hspd = 0;
vspd = 0;
spd = 10;

///MOVEMENTS
right_key = keyboard_check(ord("D"));
left_key = keyboard_check(ord("A"));
up_key = keyboard_check(ord("W"));
down_key = keyboard_check(ord("S"));

//RIGHT & LEFT
if (right_key) {
hspd = spd;
} else {
if (!right_key)
hspd = 0;
}
x += hspd

if (left_key) {
hspd = -spd
} else {
if (!left_key)
hspd = 0
}
x += hspd

//UP & DOWN
if (up_key) {
vspd = -spd;
} else {
if (!up_key)
vspd = 0;
}
y += vspd

if (down_key) {
vspd = spd;
} else {
if (!down_key)
vspd = 0;
}
y += vspd
 

Paskaler

Member
Code:
/*
GameMaker doesn't have a boolean type(true/false)
so we can 'abuse' that to treat the return values of the keyboard_check
functions as numbers:
If D is pressed and A is not pressed keyboard_check(ord("D")) returns 1 and
keyboard_check(ord("A")) returns 0. 1 - 0 = 1 which means the horizontal movement will
be in the positive direction
*/
var delta_x = keyboard_check(ord("D")) - keyboard_check(ord("A"));
var delta_y = keyboard_check(ord("S")) - keyboard_check(ord("W"));

/*
Multiplying the variables like this pretty
much replaces your if-else statements:
spd will always be the speed at which you want to move
and delta_* variables will always be -1, 0 or 1
*/
x += spd * delta_x;
y += spd * delta_y;

/*
The problem with the 2 lines above, as well as your own
code is that the object will move faster when holding W and D or
S and D, that is if it's going in a diagonal direction

This should fix it:
*/
var move_dir = point_direction(0, 0, delta_x, delta_y);
x += lengthdir_x(spd, move_dir);
y += lengthdir_y(spd, move_dir);
You should also read up on different scopes a variable can exist in. I think your left_key, right_key, etc. should've been in local scope.
There are 3 scopes:
  • Global
  • Instance
  • Local
You declare a variable global by prefixing it with global.
Code:
global.playerScore = 0;
A global variable is accesible from everywhere and is a good place to store data not relevant to any particular instance or something that is used by a couple or more systems that might not be relevant to each other. Global variables live from the moment they're declared until the game ends.
An instance variable is declared the same way you've been declaring your variables in the code you've posted. It will be assigned to that instance and it will exist as long as the instance it was declared in exists. Here's a few different ways of declaring instance variables:
Code:
healthPoints = 10;

var some_instance = instance_find(obj_object_index, 0);
with some_instance {
    healthPoints = 10;
}
some_instance.healthPoints = 10;
Local variables are declared by using var before the variable name and are destroyed after the code block in which they're declared ends. Whenever you don't need a variable after a certain code block(event, script, room creation code, etc.) you should make it into a local variable and avoid wasting memory:
Code:
/// Step Event
var complex_math = 2 + 2;

/// Draw Event
draw_text(0, 0, string(complex_math)); // This would give you an error of an undecleared variable.
This wall of text is not very relevant to your question, but it might help out a little bit, plus I want to store it for future. :)
 
Last edited:
W

Woochi

Guest
Code:
/// Step Event
var complex_math = 2 + 2;

/// Draw Event
draw_text(0, 0, string(complex_math)); // This would give you an error of an undecleared variable.
That wont do, im afraid. The local var is lost at the end of the step event if thats where its declared. In the draw event that var complex_math wont exist anymore, unless it was declared without the "var" keyword in the step event
 
B

Ban1_1

Guest
I've used the code that you have shown me and it's working fine but when I am not holding down any of the WASD keys, the object keeps moving towards the right at a slower speed unless I hold down D which then matches the 'spd' variables speed which I've set to 6.
 

Bentley

Member
I need help with this code so that I don't have to write x += hspd and y += vspd underneath the code every time I want to make the object move
You could write "x += hspd" and "y += vspd" once, at the bottom.
 
Last edited:

Paskaler

Member
I've used the code that you have shown me and it's working fine but when I am not holding down any of the WASD keys, the object keeps moving towards the right at a slower speed unless I hold down D which then matches the 'spd' variables speed which I've set to 6.
Try this:
Code:
if delta_x != 0 or delta_y != 0 {   
    var move_dir = point_direction(0, 0, delta_x, delta_y);
    x += lengthdir_x(spd, move_dir);
    y += lengthdir_y(spd, move_dir);
}
It should apply the movement only if atleast one of the keys has been pressed.
 
Top