GameMaker: Studio

GameMaker: Studio

8 Directional Movement with Enemy object help
I'm looking to have my enemy object moving randomly in 8 directions with it facing & moving in the same direction. I'm using the enemy object as a target so my goal is to hit it, thus why I need it to move randomly.

My Step Event is:

switch (direction div 90
{
case 0: sprite_index=sprite_Thunder_Viking_Running_Right; break; //Change these sprite names to the ones in your game!!!
case 45: sprite_index=sprite_Thunder_Viking_Running_Up_Right; break;
case 90: sprite_index=sprite_Thunder_Viking_Running_Up; break;
case 135: sprite_index=sprite_Thunder_Viking_Running_Up_Left; break;
case 180: sprite_index=sprite_Thunder_Viking_Running_Left; break;
case 225: sprite_index=sprite_Thunder_Viking_Running_Down_Left; break;
case 270: sprite_index=sprite_Thunder_Viking_Running_Down; break;
case 315: sprite_index=sprite_Thunder_Viking_Running_Down_Right; break;
}


I'm guessing that the Case is the degrees it should be moving in but, it isn't facing in the direction it should be moving in. Can someone assist?
< >
Показані коментарі 15 із 5
You have...
switch (direction div 90
...but then you check numbers like 45 and upwards. That's not going to work, as, provided that "direction" is from 0 up to and not including 360, "direction div 90" will always be 0, 1, 2, or 3.


You should instead do something like...
switch (((((direction + 22.5) % 360) + 360) % 360) div 45)
In case that confuses you, let's break it down:

"direction + 22.5" is to offset the whole check by 22.5 degrees, so that it can move slightly off-centre but still get the proper sprite applied. (So that anywhere from -22.5 to +22.5 degrees becomes 0 later, instead of anywhere from 0 to +45 degrees.)
"... % 360" means that any value above 360 is reduced by 360, so that 460 or 820 both become 100 and stuff like that.
"... + 360" adds 360 to it. The first "%" doesn't turn negative values into positive values (e.g. -460 and -820 become -100, not +260), so we must do so ourselves.
"... % 360" again wraps it down under 360. Doing "%, +, %" with the same number will result in negative values being wrapped around into positive ones (so that -100 becomes +260).
"... div 45" then divides it by 45, rounded down. As we've made the value be between 0 and 360, this results in an integer value from 0 to and including 8.

All of the parentheses are to ensure a proper order of events, taking the entire previous calculation into account rather than just one number of it or such.

You should then add these cases after that switch:
{ case 0: case 8: sprite_index=sprite_Thunder_Viking_Running_Right; break; //Change these sprite names to the ones in your game!!! case 1: sprite_index=sprite_Thunder_Viking_Running_Up_Right; break; case 2: sprite_index=sprite_Thunder_Viking_Running_Up; break; case 3: sprite_index=sprite_Thunder_Viking_Running_Up_Left; break; case 4: sprite_index=sprite_Thunder_Viking_Running_Left; break; case 5: sprite_index=sprite_Thunder_Viking_Running_Down_Left; break; case 6: sprite_index=sprite_Thunder_Viking_Running_Down; break; case 7: sprite_index=sprite_Thunder_Viking_Running_Down_Right; break; }


There may well be a more efficient way to do this, but this is the best way that I know of, I'm afraid.
Автор останньої редакції: Zappy; 13 січ. 2020 о 4:12
switch (direction) { case 0: sprite_index=sprite_Thunder_Viking_Running_Right; break; case 45: sprite_index=sprite_Thunder_Viking_Running_Up_Right; break; case 90: sprite_index=sprite_Thunder_Viking_Running_Up; break; case 135: sprite_index=sprite_Thunder_Viking_Running_Up_Left; break; case 180: sprite_index=sprite_Thunder_Viking_Running_Left; break; case 225: sprite_index=sprite_Thunder_Viking_Running_Down_Left; break; case 270: sprite_index=sprite_Thunder_Viking_Running_Down; break; case 315: sprite_index=sprite_Thunder_Viking_Running_Down_Right; break; }
switch (direction div 45) { case 0: sprite_index=sprite_Thunder_Viking_Running_Right; break; case 1: sprite_index=sprite_Thunder_Viking_Running_Up_Right; break; case 2: sprite_index=sprite_Thunder_Viking_Running_Up; break; case 3: sprite_index=sprite_Thunder_Viking_Running_Up_Left; break; case 4: sprite_index=sprite_Thunder_Viking_Running_Left; break; case 5: sprite_index=sprite_Thunder_Viking_Running_Down_Left; break; case 6: sprite_index=sprite_Thunder_Viking_Running_Down; break; case 7: sprite_index=sprite_Thunder_Viking_Running_Down_Right; break; }
Either one should give you a simple solution

EDIT: if the direction value is not one of the main cardinal values you'll have to reduce it to match
direction=floor(direction div 45) * 45; // this will guarantee that direction is one of the 8 cardinal directions.

EDIT #2: I like Zappy's idea of offsetting the direction a little so that the sprite lines up more with what you visually want.
Автор останньої редакції: The Winter Bud; 15 січ. 2020 о 14:26
Thanks! I will try both options.

Update: I just tried the code below and it only worked when my player was running Right, Left, Down, Up. The other 4 directions didn't work.

switch (direction)
{
case 0: sprite_index = sprite_RB_Run_Right; break;
case 45: sprite_index = sprite_RB_Run_Up_Right; break;
case 90: sprite_index = sprite_RB_Run_Up; break;
case 135: sprite_index = sprite_RB_Run_Up_Left; break;
case 180: sprite_index = sprite_RB_Run_Left; break;
case 225: sprite_index = sprite_RB_Run_Down_Left; break;
case 270: sprite_index = sprite_RB_Run_Down; break;
case 315: sprite_index = sprite_RB_Run_Down_Right; break;
}


I also tried the code below as well and the only facing position my player did was face right.


switch (((((direction + 22.5) % 360) + 360) % 360) div 45)
{
case 0: case 8: sprite_index=sprite_Thunder_Viking_Running_Right; break; //Change these sprite names to the ones in your game!!!
case 1: sprite_index=sprite_Thunder_Viking_Running_Up_Right; break;
case 2: sprite_index=sprite_Thunder_Viking_Running_Up; break;
case 3: sprite_index=sprite_Thunder_Viking_Running_Up_Left; break;
case 4: sprite_index=sprite_Thunder_Viking_Running_Left; break;
case 5: sprite_index=sprite_Thunder_Viking_Running_Down_Left; break;
case 6: sprite_index=sprite_Thunder_Viking_Running_Down; break;
case 7: sprite_index=sprite_Thunder_Viking_Running_Down_Right; break;
}



It might not be working because my player is following a path for it's movement. Do you think that would be a cause for the problem?
Автор останньої редакції: RAREMIND ARTWORKS; 29 квіт. 2020 о 21:09
I just tried the code below and it only worked when my player was running Right, Left, Down, Up. The other 4 directions didn't work.
try changing the switch statement to
switch((direction div 45) * 45) /* (div) is an integer division where the whole value truncates the decimal value. So the value of (direction div 45) will be between 0 and 8. Multiplying that value by 45 will guarantee one of the 8 values. You could change the case statement values to 0-8 where you can then remove the * 45 part of the equation. (like in my 2nd example above) */
since the object is following a path it might help to isolate the direction value to one of the 8 cardinal directions.
EDIT:
the main issue with just asking if direction equals a value is you are asking the direction if it is a specific value without any leeway. By doing integer division on the direction you are giving direction a little leeway and its more like asking if direction is with in 45 degrees of any of the directions you supplied.

So for instance. By doing integer division:
the first case statement would be asking
is direction between 0 and 45.
the second case statement is asking
is direction between 46 and 90
and so on
Автор останньої редакції: The Winter Bud; 30 квіт. 2020 о 12:26
Understood. It worked!! Thanks
< >
Показані коментарі 15 із 5
На сторінку: 1530 50