GameMaker: Studio

GameMaker: Studio

Not enough ratings
4 way and 8 way movement made easy
By The Winter Bud
create 4 way movement and 8 way movement using simple logic.
   
Award
Favorite
Favorited
Unfavorite
Logic - building blocks of magic
WARNING: explanation is longer than code for a deeper concept to a basic problem
if you are just looking for the code without explanation you can find the full script at the bottom of the page.


In this guide I will explain how we can use logic to make an object move in a 4 way direction without diagonals. By using logical assignment and comparison we can reduce the amount of
if( keyboard_check() ) calls. Most of the work is done by simple logical comparison that happens in the blink of an eye.


In a 4 way movement system we have
4 keys(up, down, left, right)
2 movement planes(horizontal and vertical)

and we want to take those keys and planes and turn them into something that can give us an outcome of 1 key press or not and move in the direction of that key

A little bit about logic:
When we use logic, we only focus on whether something is true or false. It's easy to see if one thing is true, we just check like this:
if(something==true){ // we win!! }
With 2 variables we introduce relationships. Logic allows us to compare how one variable relates to another.
Let's take for instance:
You are looking at two cars.
I can ask you a relationship question like:
  • Are both cars blue?
  • Is either car a sports car?
  • Is only one of the cars an American made car?
These are 3 ways to see how 2 variables relate to each other
  • AND( && ) - both variable are true
  • OR( || ) - one and/or the other is true
  • XOR( ^^ ) - one or the other is true but not both

A little about truth tables
Truth Tables give us a visual representation of the outcome of 2 variables by their relationship to each other. Below are all the outcomes of the two variables and their relationships to each other using the AND, OR, and XOR relationships"
The AND(&&) condition -> if(var1 && var2) then // we win!
var1 - var2 - outcome
---------------------
true - true - true
true - false - false
false - true - false
false - false - false
Always false but one case - both must be true
The OR(||) condition -> if(var1 || var2) then // we win!
var1 - var2 - outcome
---------------------
true - true - true
true - false - true
false - true - true
false - false - false
Always true but one case - both must be false
The XOR(^^) condition -> if(var1 ^^ var2) then // we win!
var1 - var2 - outcome
---------------------
true - true - false
true - false - true
false - true - true
false - false - false
true if different, false if same
With these abilities to compare the relationships between things we can make a simple thing of a simple mechanic.
4 Way & 8 Way movement made simple
Variables
These variables are all local to the script except move_speed variable which needs to be declared and initialized in the create event.
  • left_key: true if left arrow key is press, false if left arrow key is not pressed
  • right_key: true if right arrow key is press, false if right arrow key is not pressed
  • up_key: true if up arrow key is press, false if up arrow key is not pressed
  • down_key: true if down arrow key is press, false if down arrow key is not pressed
  • horz_key: true if the left key or the right key is true, false if neither key or both keys are pressed
  • vert_key: true if the up key or the down key is true, false if neither key or both keys are pressed
  • moving: true if the horz key or the vert key is true, false if neither key or both keys are pressed
  • move_speed: a real number greater than zero
    note: this is the only one not a boolean and could be initialized in teh create event

Let's Code
The first thing we do is assign true or false to the left, right, up, and down keys.
right_key=keyboard_check(vk_right); // repeat for the 4 other keys

You can compound the assignment if you have more than 1 key that represents movement such as the right arrow key and the 'd' key can move to the right.
right_key=(keyboard_check(vk_right) || keyboard_check(ord("D")); // either the right arrow or D key or both doesn't matter

After we have all the keys we can compare the horizontal keys with an XOR relationship.(remember that XOR means either one is true but not both)
horz_key=left_key^^right_key; // you can press the left or the right key but both will fail vert_key=up_key^^down_key; // you can press the up or down key but press both will fail

Now if you wanted just 8 way movement you are done and just need to update x/y but we'll continue with the tutorial.

If we now compare the vert_key with the horz_key with the same relationship we'll be testing whether a horizontal key or vertical key is being pressed but not both.
moving=vert_key^^horz_key; // you can move sideway or up and down but NOT diagnally // for 8 way movement // moving=vert_key||horz_key; // here we see if either one is pressed even both

All that is left is to apply the values of the key variables if moving equals true
if(moving==true){ hspeed=move_speed*(right_key-left_key); vspeed=move_speed*(down_key-up_key); }

If you would rather just add to x and y and not use hspeed and vspeed you can do it like this:
if(moving==true){ x+=move_speed*(right_key-left_key); y+=move_speed*(down_key-up_key); }

Full Code (with remarks)
in the step event you can put it all together
// let's make all those variables local to the script var left_key,right_key,up_key,down_key,horz_move,vert_move,moving,move_speed; move_speed=4; //NOTE: you can move this line to the create event left_key=keyboard_check(vk_left) || keyboard_check(ord("A")); right_key=keyboard_check(vk_right) || keyboard_check(ord("D")); up_key=keyboard_check(vk_up) || keyboard_check(ord("W")); down_key=keyboard_check(vk_down) || keyboard_check(ord("S")); horz_move=left_key^^right_key; // if left or right but not both vert_move=up_key^^down_key; // if up or down but not both moving=horz_move^^vert_move; // if horz or vert but not both // NOTE: moving=horz_move||vert_move; // this is the line for 8way // guaranteeing we have 4 way movement if(moving){ x+=move_speed*(right_key-left_key); y+=move_speed*(down_key-up_key); }
Just the Code
Here is the code for those who do not wish to read how it works and just want to plug it in

var left_key,right_key,up_key,down_key,horz_move,vert_move,moving,move_speed; move_speed=4; left_key=keyboard_check(vk_left) || keyboard_check(ord("A")); right_key=keyboard_check(vk_right) || keyboard_check(ord("D")); up_key=keyboard_check(vk_up) || keyboard_check(ord("W")); down_key=keyboard_check(vk_down) || keyboard_check(ord("S")); horz_move=left_key^^right_key; vert_move=up_key^^down_key; moving=horz_move^^vert_move; if(moving){ x+=move_speed*(right_key-left_key); y+=move_speed*(down_key-up_key); }
4 Comments
Mabel1618 25 Nov, 2023 @ 12:39pm 
vriska?
The Winter Bud  [author] 9 Nov, 2016 @ 4:11am 
collision detection is unique to the application. place_meeting(), place_free(), collision_whaterver(), and other detection conditions work best when applied locally to game.
The basic concept is the same though.
// pseudo code
[code]
if moving
if not a collision where I'm going
move there
else
dont move there. maybe do something else
[/code]

To push a thing it's similar except you would check for teh collision detection on the thing being pushed instead of the player.

RonjaLin 7 Nov, 2016 @ 4:04am 
The next step would be collision detection or pushing things around, I guess.
RonjaLin 7 Nov, 2016 @ 3:52am 
Zelda clones made easy. :-)