• 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!

SOLVED: Why doesn't this code prevent reverse direction?

Bentley

Member
I'm trying to make it so the player can't go backwards. Ex: if he's moving east, he can't go west.

Code:
switch (keyboard_key)
{
    case vk_right: target_dir = 0; break;
    case vk_left: target_dir = 180; break;
    case vk_up: target_dir = 90; break;
    case vk_down: target_dir = 270; break;
}

if (snapped) //Player can only change directions when snapped, and that's when target_dir is tested
{
   if (direction - 180 == target_dir) exit;
   direction = target_dir;
}
If the player is moving in direction 0, and sets target_dir to 180, then I can see why the exit doesn't run:

direction (-180) doesn't equal target_dir (180). So I get why the exit doesn't run, which allows the player to reverse direction. But then once the player is moving left, he's not able to move right. So in the second case, -360 doesn't equal 0, yet the exit statement runs, and he's not able to reverse direction. Direction resets? And if so, do I need to use abs(target_dir) so that -180 equals 180 which would prevent backwards movement?

As you can see, I don't have a grasp on this. If anyone can explain it, I'd greatly appreciate it. (Sorry for the rookie question : (
 
S

Sinaz20

Guest
Adding and subtracting to the direction tends to get you out of range... consider direction of -90 is the same direction as 540, but they won't evaluate to true if compared for equality.

Since you are choosing a discrete direction with the switch, you could just get away with setting and limiting what value it can be set to based on the current direction...

Correct me if I'm mistaken... but this is kind of like the motion of the snake in the classic snake game... where you can only really turn 90 degrees from the direction you are moving (pressing the same direction is redundant essentially) and you can never go directly opposite of your current travel direction without first making that 90 degree turn...

In this case, you can simplify from needing the target_dir var.

However, if you use that for something else, then you can keep it, but look at this code below and consider it conceptually and how it might satisfy your needs here:

Code:
switch (keyboard_key)
{
    case vk_right:
        direction = direction == 180 ? direction : 0;
        break;
    case vk_left:
        direction = direction == 0 ? direction: 180;
        break;
    case vk_up:
        direction = direction == 270 ? direction : 90;
        break;
    case vk_down:
        direction = direction == 90 ? direction : 270;
        break;
}
In the above code, I still use your switch, but I have encompassed all the turning mechanic into those ternary operations.

If you are not familiar with how the ternary operation works... it goes like this... variable = condition ? expression if true : expression if false

If the condition before the ? evaluates as true, then evaluate and return the expression before the colon, else evaluate and return the expression after the colon.

To help grok this:

direction = direction == 0 ? direction : 180;

is functionally equivalent to...

if(direction == 0)
direction = direction;
else
direction = 180;

So the code I offered reads,

Switch on keyboard_key.
In the case of vk_right...
If current direction equals 180 (left), set direction to its current value (180) else, set the direction to 0 (right)...
in the case of vk_left...
if current direction equals 0 (right), set direction to its current value (0) else, set the direction to 180 (left)...
etc.

Ternary operations are new to GM:S... they are a great shortcut for simple conditionals, and they evaluate slightly faster than full if/then statement.
 
Last edited by a moderator:

Bentley

Member
Adding and subtracting to the direction tends to get you out of range... consider direction of -90 is the same direction as 540, but they won't evaluate to true if compared for equality.
Ah, that's where I was going wrong. Thanks for the explaining that to me. And yes, I am making a snake game.

In the above code, I still use your switch, but I have encompassed all the turning mechanic into those ternary operations.
I had never heard of ternary operations. Thanks for introducing me to them. You broke down something complex and made it simple, much appreciated. I also like how everything is done in the switch statement and that you got rid of my ugly "target_dir" variable.

Thanks again for thoughtful response.
 
Last edited:

Bentley

Member
if (direction + 180) mod 360 != target_dir {
direction = target_dir;
}

Don't let it go negative, then you can use modulo.
Thanks for the reply Theou. I had to get my head around modulo (or at least I tried). I never use it so it's a bit awkward for me atm, especially when the smaller number is on the left side : ( Thanks for the reply, I appreciate it.
 
Last edited:
Top