GML Visual Random Enemy Movement For A Maze Game

I am trying to make random enemy movement work for my maze game but can't find any tutorials on how to do it. I am trying to make it work so the enemies move in random directions but can not choose backwards or where there is a wall. Below is a response I had gotten but I don't know how to add the actual movement into this. I know its checking a bunch of stuff but how do I add movement to it? I am using DnD and GMS2. Thank you!

"because there is not a do until loop in drag in drop your best bet is each time you wish to move to do the following

set a variable called dchoosen to false
repeat 20 times
start block
test variable dchoosen false
check collision 64 0 wall relative not
test chance 4
start block
set variable x 64 relative
set variable dchosen true
end block
test variable dchoosen false
check collision -64 0 wall relative not
test chance 4
start block
set variable x -64 relative
set variable dchosen true
end block
test variable dchoosen=false
check collision 0 64 wall relative not
test chance 4
start block
set variable y 64 relative
set variable dchosen=true
end block
test variable dchoosen=false
check collision 0 -64 wall relative not
test chance 4
start block
set variable y -64 relative
set variable dchosen=true
end block
endblock

this is actually much easer and fasteer to do in code than block but that should work"
 

TheouAegis

Member
So a Pac-Man clone?

Where the code "set x" or "set y" is where the movement is. That's more in line with an old roguelike, like Angband. You are better off setting hspeed or vspeed instead of manually adjusting x and y.

How big are the walls in your game? Your walls are essentially aligned to a grid, right? How big is that grid?
 
Last edited:

TheouAegis

Member
Yeah that's the foundation I am going for. Like I said someone sent me the above system to put into my enemy AI but I don't know how to use that check system with movement. Once it checks all that stuff how do I determine movement?
I was editing my post. Go back and answer the last question. Lol
 
So a Pac-Man clone?

Where the code "set x" or "set y" is where the movement is. That's more in line with an old roguelike, like Angband. You are better off setting hspeed or vspeed instead of manually adjusting x and y.

How big are the walls in your game? Your walls are essentially aligned to a grid, right? How big is that grid?
my grid is 64, 64
 

TheouAegis

Member
At least you can create temporary variables in GMS2's DnD. lol

The following code assumes your enemy's sprite origin is CENTERED. I will also assume the size of your enemy sprite is 64x64 like the walls. It...shouldn't matter too much if it's not, though. This code also uses the built-in movement variables "direction". Set speed to how fast you want the enemy to move. Try to keep it at 0.5, 1, 1.5, 2, 4, or 8. If you want fractional speeds, you'll need to find my post on using fractional speeds with grid-aligned movement.

When a line is indented, it means it belongs to the right of the action above it, since Studio2's DnD supposedly doesn't use "blocks" per se.

In your step event:
If Expression ( ( x - 32 ) + ( y - 32) ) mod 64 is equal to 0
This will check if the enemy is in the middle of a grid cell
Put the rest of this code inside the chain of actions for the
true condition (default is to the right)

Declare Temporary Variable paths[3] with value !position_meeting(x, y+64, wall) and direction != 90
click the + sign 5 times to add 5 more variables
+ paths[2] with value !position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value !position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value !position_meeting(x + 64, y, wall) and direction != 180
The ! means we set each of these variables to 1 if position_meeting() is FALSE (meaning no walls blocking) and the enemy is not going the opposite way
+ targetH with value player.x - x replace "player" with your player object's name
+
targetV with value player.y - y
If Expression abs(targetH) < abs(targetY) check if the player is closer horizontally than vertically
If Variable paths[ 1 - sign(targetH) ] is equal to 1
Assign Variable direction with value 90 - 90 * sign(targetH)
Note: This goes BELOW the "If Variable" action
If Variable paths[ 2 + sign(targetV) ] is equal to 1
Assign Variable direction with value 180 + 90 * sign(targetV)

Declare Temporary Variable rand with value irandom(3)
While paths[ rand ] is equal to 0
Assign Variable rand with value (rand + 1) mod 4
This is a loop which will look through all paths and find an available one
Note: Next line goes BELOW While since it is not a part of the loop
Assign Variable direction with value rand * 90
Note: This goes BELOW the "If Expression" action
If Variable paths[ 2 + sign(targetV) ] is equal to 1
Assign Variable direction with value 180 + 90 * sign(targetV)

If Variable paths[ 1 - sign(targetH) ] is equal to 1
Assign Variable direction with value 90 - 90 * sign(targetH)

Declare Temporary Variable rand with value irandom(3)
While paths[ rand ] is equal to 0
Assign Variable rand with value (rand + 1) mod 4
Assign Variable direction with value rand * 90
 
At least you can create temporary variables in GMS2's DnD. lol

The following code assumes your enemy's sprite origin is CENTERED. I will also assume the size of your enemy sprite is 64x64 like the walls. It...shouldn't matter too much if it's not, though. This code also uses the built-in movement variables "direction". Set speed to how fast you want the enemy to move. Try to keep it at 0.5, 1, 1.5, 2, 4, or 8. If you want fractional speeds, you'll need to find my post on using fractional speeds with grid-aligned movement.

When a line is indented, it means it belongs to the right of the action above it, since Studio2's DnD supposedly doesn't use "blocks" per se.

In your step event:
If Expression ( ( x - 32 ) + ( y - 32) ) mod 64 is equal to 0
This will check if the enemy is in the middle of a grid cell
Put the rest of this code inside the chain of actions for the
true condition (default is to the right)

Declare Temporary Variable paths[3] with value !position_meeting(x, y+64, wall) and direction != 90
click the + sign 5 times to add 5 more variables
+ paths[2] with value !position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value !position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value !position_meeting(x + 64, y, wall) and direction != 180
The ! means we set each of these variables to 1 if position_meeting() is FALSE (meaning no walls blocking) and the enemy is not going the opposite way
+ targetH with value player.x - x replace "player" with your player object's name
+
targetV with value player.y - y
If Expression abs(targetH) < abs(targetY) check if the player is closer horizontally than vertically
If Variable paths[ 1 - sign(targetH) ] is equal to 1
Assign Variable direction with value 90 - 90 * sign(targetH)
Note: This goes BELOW the "If Variable" action
If Variable paths[ 2 + sign(targetV) ] is equal to 1
Assign Variable direction with value 180 + 90 * sign(targetV)

Declare Temporary Variable rand with value irandom(3)
While paths[ rand ] is equal to 0
Assign Variable rand with value (rand + 1) mod 4
This is a loop which will look through all paths and find an available one
Note: Next line goes BELOW While since it is not a part of the loop
Assign Variable direction with value rand * 90
Note: This goes BELOW the "If Expression" action
If Variable paths[ 2 + sign(targetV) ] is equal to 1
Assign Variable direction with value 180 + 90 * sign(targetV)

If Variable paths[ 1 - sign(targetH) ] is equal to 1
Assign Variable direction with value 90 - 90 * sign(targetH)

Declare Temporary Variable rand with value irandom(3)
While paths[ rand ] is equal to 0
Assign Variable rand with value (rand + 1) mod 4
Assign Variable direction with value rand * 90
Thank you so much for writing all of this out! I finally had time to put this code in (I had to work extra all week until now) I had some errors appear though when I finished.
Object: object_enemy3 Event: Step at line 27 : unexpected symbol ")" in expression
Object: object_enemy3 Event: Step at line 27 : malformed assignment
Object: object_enemy3 Event: Step at line 24 : Cannot set a constant ("@@NewGMLArray@@") to a value
Object: object_enemy3 Event: Step at line 25 : Cannot set a constant ("@@NewGMLArray@@") to a value
Object: object_enemy3 Event: Step at line 26 : Cannot set a constant ("@@NewGMLArray@@") to a value
Object: object_enemy3 Event: Step at line 27 : Cannot set a constant ("@@NewGMLArray@@") to a value
Pretty sure these are all from the declaring temps at the beginning. Any ideas? Thanks again for helping with this and sorry for the late reply!
 

TheouAegis

Member
There is an option somewhere supposedly the turn dragon drop into gml, find that and copy the code. It could be a bug, a typo on your part, maybe type on my part. lol but the error is for the translated code.
 
There is an option somewhere supposedly the turn dragon drop into gml, find that and copy the code. It could be a bug, a typo on your part, maybe type on my part. lol but the error is for the translated code.
Once you convert dnd to code though you cant convert it back. You can preview the dnd in code though. would that help find the problem?
 
Maybe. Probably.
These are the errors:
Object: object_enemy3 Event: Step at line 27 : unexpected symbol ")" in expression
Object: object_enemy3 Event: Step at line 27 : malformed assignment
Object: object_enemy3 Event: Step at line 24 : Cannot set a constant ("@@NewGMLArray@@") to a value
Object: object_enemy3 Event: Step at line 25 : Cannot set a constant ("@@NewGMLArray@@") to a value
Object: object_enemy3 Event: Step at line 26 : Cannot set a constant ("@@NewGMLArray@@") to a value
Object: object_enemy3 Event: Step at line 27 : Cannot set a constant ("@@NewGMLArray@@") to a value

This is the code (read only):
// GameMaker Language Preview (Read-Only)
// If Expression
if([(x - 32) + (y -32)] mod 64 = 0)
{
// Declare Temp
var paths[3] = !position_meeting(x, y + 64, wall) and direction!= 90;
var paths[2] = !position_meeting(x + 64, y, wall) and direction!= 0;
var paths[1] = !position_meeting(x, y - 64, wall) and direction!= 270;
var paths[0] = !position_meeting(x + 64, y, wall) and direction!= 180 );
var targetH = object_player2.x - x;
var targetV = object_player.y - y;
// If Expression
if(abs(targetH) < abs(targetV))
{
// If Variable
if(paths[1 - sign(targetH)] == 1)
{
// Assign Variable
direction = 90 - 90 * sign(targetH);
}

// Else
else
{
// If Variable
if(paths[2 + sign(targetV)] == 1)
{
// Assign Variable
direction = 180 + 90 * sign(targetV);
}

// Else
else
{
// Declare Temp
var rand = irandom(3);

// While Loop
while ((path[rand] == 0)) {
// Assign Variable
rand = (rand + 1)mod 4;
}

// Assign Variable
direction = rand * 90;
}
}
}
// Else
else
{
// If Variable
if(paths[2 + sign(targetV)] == 1)
{
// Assign Variable
direction = 180 + 90 * sign(targetV);
}

// Else
else
{
// If Variable
if(paths[1 - sign(targetH)] == 1)
{
// Assign Variable
direction = 90 - 90 * sign(targetH);
}

// Else
else
{
// Declare Temp
var rand = irandom(3);

// While Loop
while ((paths[rand] == 0)) {
// Assign Variable
rand = (rand + 1) mod 4;
}

// Assign Variable
direction = rand * 90;
}
}
}
}
 
I forgot I had put that in to try it and see if it worked and never changed it back. Now it says:
Object: object_enemy3 Event: Step at line 27 : unexpected symbol ")" in expression
plus the other ones
 
Yeah they are all PATHS. And the errors are still
Object: object_enemy3 Event: Step at line 24 : Cannot set a constant ("@@NewGMLArray@@") to a value
after I changed direction to image_angle
 

TheouAegis

Member
That shouldn't be happening... Especially since the error says the array is a legit array... But it's a constant. It can't be a constant and an array! I say file a bug report. Cuz that [ ] i pointed out earlier was the only error i saw.
 

TheouAegis

Member
Yeah they are all PATHS. And the errors are still
Object: object_enemy3 Event: Step at line 24 : Cannot set a constant ("@@NewGMLArray@@") to a value
after I changed direction to image_angle
Hey man, did you get this working yet? YoyoGames renewed my license temporarily, so I may be able to try to work on this on my end.
 
No not yet. Would it be easier if the enemies didn't have to follow the player? I think that's probably what I will need anyway. Just roaming enemies that pick random paths that are free of walls and won't go backwards.
 

TheouAegis

Member
No not yet. Would it be easier if the enemies didn't have to follow the player? I think that's probably what I will need anyway. Just roaming enemies that pick random paths that are free of walls and won't go backwards.
Edit: I think I confused myself in that original code, too. All the times where I had something like
if paths[1 - 90 * sign(targetH)] == 1
it should have been 0, not 1. A value of 1 meant the path was blocked, while 0 meant it's open. And we're trying to find an open path. lol

Edit 2: I confused myself twice. I forgot I used ! before position_meeting(), so my original code was fine. So now I removed ! from all my code. ... I'm so confused. I should just go to work now.


Anyway, I found the issue. I think it's a bug, personally, but there is a workaround. Unfortunately, you're going to have to retype stuff (if you want to keep it in DnD).

(minor edit: It's not really a bug, since it's in GML also. You can't declare a temporary array, but you can declare a temporary variable and then convert it to an array. That's what the below code does.)

The workaround is you need to declare paths (or PATHS by now, lol) as a temporary variable set to 0. Once paths (or PATHS) has been created, then you can convert it to an array.

Declare Temporary Variable paths with value 0
click the + sign 2 times to add 2 more variables
+ targetH with value player.x - x replace "player" with your player object's name
+
targetV with value player.y - y

Assign Variable paths[3] with value position_meeting(x, y+64, wall) and direction != 90
+ paths[2]
with value position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value position_meeting(x + 64, y, wall) and direction != 180
The ! means we set each of these variables to 1 if position_meeting() is FALSE (meaning no walls blocking) and the enemy is not going the opposite way
 
Last edited:
Edit: I think I confused myself in that original code, too. All the times where I had something like
if paths[1 - 90 * sign(targetH)] == 1
it should have been 0, not 1. A value of 1 meant the path was blocked, while 0 meant it's open. And we're trying to find an open path. lol

Edit 2: I confused myself twice. I forgot I used ! before position_meeting(), so my original code was fine. So now I removed ! from all my code. ... I'm so confused. I should just go to work now.


Anyway, I found the issue. I think it's a bug, personally, but there is a workaround. Unfortunately, you're going to have to retype stuff (if you want to keep it in DnD).

(minor edit: It's not really a bug, since it's in GML also. You can't declare a temporary array, but you can declare a temporary variable and then convert it to an array. That's what the below code does.)

The workaround is you need to declare paths (or PATHS by now, lol) as a temporary variable set to 0. Once paths (or PATHS) has been created, then you can convert it to an array.

Declare Temporary Variable paths with value 0
click the + sign 2 times to add 2 more variables
+ targetH with value player.x - x replace "player" with your player object's name
+
targetV with value player.y - y

Assign Variable paths[3] with value position_meeting(x, y+64, wall) and direction != 90
+ paths[2]
with value position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value position_meeting(x + 64, y, wall) and direction != 180
The ! means we set each of these variables to 1 if position_meeting() is FALSE (meaning no walls blocking) and the enemy is not going the opposite way
Sorry for the late response! This week(or month) has been insane! I will try this out when I get a chance but I am also going out of town next week. Thanks for all of your help through all of this! Especially explaining everything has helped a lot and I feel like I have learned a lot. Sorry I have been so late with responses. I started this project and and then happened!
 
Edit: I think I confused myself in that original code, too. All the times where I had something like
if paths[1 - 90 * sign(targetH)] == 1
it should have been 0, not 1. A value of 1 meant the path was blocked, while 0 meant it's open. And we're trying to find an open path. lol

Edit 2: I confused myself twice. I forgot I used ! before position_meeting(), so my original code was fine. So now I removed ! from all my code. ... I'm so confused. I should just go to work now.


Anyway, I found the issue. I think it's a bug, personally, but there is a workaround. Unfortunately, you're going to have to retype stuff (if you want to keep it in DnD).

(minor edit: It's not really a bug, since it's in GML also. You can't declare a temporary array, but you can declare a temporary variable and then convert it to an array. That's what the below code does.)

The workaround is you need to declare paths (or PATHS by now, lol) as a temporary variable set to 0. Once paths (or PATHS) has been created, then you can convert it to an array.

Declare Temporary Variable paths with value 0
click the + sign 2 times to add 2 more variables
+ targetH with value player.x - x replace "player" with your player object's name
+
targetV with value player.y - y

Assign Variable paths[3] with value position_meeting(x, y+64, wall) and direction != 90
+ paths[2]
with value position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value position_meeting(x + 64, y, wall) and direction != 180
The ! means we set each of these variables to 1 if position_meeting() is FALSE (meaning no walls blocking) and the enemy is not going the opposite way
Finally got back and put this all in and the game boots up again without errors!! Yay!! The problem though is that the enemies don't move still. Any ideas?
 

TheouAegis

Member
Before I say upload the project to a free file host, a couple things to check.

First of all, it freezes because "While paths[ rand ] is equal to 0" is stuck in an endless loop because every index of paths is set to 0. This would mean either the enemy is completely enclosed by walls... or standing out in the open, depending on how the paths array was set.

In the first post, I had used:
Declare Temporary Variable paths[3] with value !position_meeting(x, y+64, wall) and direction != 90
click the + sign 5 times to add 5 more variables
+ paths[2] with value !position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value !position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value !position_meeting(x + 64, y, wall) and direction != 180

If this freezes, the enemy is completely enclosed by walls.

But in the last post, I used:
Assign Variable paths[3] with value position_meeting(x, y+64, wall) and direction != 90
+ paths[2]
with value position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value position_meeting(x + 64, y, wall) and direction != 180

If this freezes, the enemy is out in the open.

Notice how in the original post I had ! in front of each position_meeting(), but I didn't in the other post? That was a typo of sorts. You probably still have the rest of the old code, so you need the ! before position_meeting() in this case.

Assign Variable paths[3] with value !position_meeting(x, y+64, wall) and direction != 90
+ paths[2]
with value !position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value !position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value !position_meeting(x + 64, y, wall) and direction != 180

Actually, there is still one more possibility. I did use two conditions for each of those, the second condition being if direction is not a certain value. I did this to prevent back-tracking. However, if your maze has dead-ends, then you'll need to remove all of the "and direction !=" parts.

It's also possible, but unlikely, that direction is not getting changed and it stays at 0, causing paths[2] to always be false. That's something I'd look for after exhausting the other possibilities.
 
Before I say upload the project to a free file host, a couple things to check.

First of all, it freezes because "While paths[ rand ] is equal to 0" is stuck in an endless loop because every index of paths is set to 0. This would mean either the enemy is completely enclosed by walls... or standing out in the open, depending on how the paths array was set.

In the first post, I had used:
Declare Temporary Variable paths[3] with value !position_meeting(x, y+64, wall) and direction != 90
click the + sign 5 times to add 5 more variables
+ paths[2] with value !position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value !position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value !position_meeting(x + 64, y, wall) and direction != 180

If this freezes, the enemy is completely enclosed by walls.

But in the last post, I used:
Assign Variable paths[3] with value position_meeting(x, y+64, wall) and direction != 90
+ paths[2]
with value position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value position_meeting(x + 64, y, wall) and direction != 180

If this freezes, the enemy is out in the open.

Notice how in the original post I had ! in front of each position_meeting(), but I didn't in the other post? That was a typo of sorts. You probably still have the rest of the old code, so you need the ! before position_meeting() in this case.

Assign Variable paths[3] with value !position_meeting(x, y+64, wall) and direction != 90
+ paths[2]
with value !position_meeting(x - 64, y, wall) and direction != 0
+ paths[1]
with value !position_meeting(x, y-64, wall) and direction != 270
+ paths[0]
with value !position_meeting(x + 64, y, wall) and direction != 180

Actually, there is still one more possibility. I did use two conditions for each of those, the second condition being if direction is not a certain value. I did this to prevent back-tracking. However, if your maze has dead-ends, then you'll need to remove all of the "and direction !=" parts.

It's also possible, but unlikely, that direction is not getting changed and it stays at 0, causing paths[2] to always be false. That's something I'd look for after exhausting the other possibilities.
I have no idea whats going on. I checked all of the code and put the "!" back in but as soon as the enemies spawn they move into a wall block and freeze the game. Could it be that I am putting in wall wrong? I tried it as "object_block" the name of the wall objects and as "wall" but "wall" shows an error before the game even boots up.
 

TheouAegis

Member
Use the name of your wall/block object.
If you have multiples, assign one of them as the parent of all the others and reference that one.

Copy the GML preview again so I can see what it's coming up as now.

Inside this main block:
If Expression ( ( x - 32 ) + ( y - 32) ) mod 64 is equal to 0

...at the end of it, put a

Show Message string(paths[0])+" "+string(paths[1])+" "+string(paths[2])+" "+string(paths[3]))

If the main IF block works, the message will at least pop up.

....I just had an idea. What are the coordinates of your enemy when he's put in the room? Maybe you don't need the -32's in the main conditional. Honestly, it could be lots of things.
 
Use the name of your wall/block object.
If you have multiples, assign one of them as the parent of all the others and reference that one.

Copy the GML preview again so I can see what it's coming up as now.

Inside this main block:
If Expression ( ( x - 32 ) + ( y - 32) ) mod 64 is equal to 0

...at the end of it, put a

Show Message string(paths[0])+" "+string(paths[1])+" "+string(paths[2])+" "+string(paths[3]))

If the main IF block works, the message will at least pop up.

....I just had an idea. What are the coordinates of your enemy when he's put in the room? Maybe you don't need the -32's in the main conditional. Honestly, it could be lots of things.
// If Expression
if(((x - 32) + (y -32)) mod 64 = 0)
{
// Set Speed
speed = 2;
// Declare Temp
var PATHS = 0;
var targetH = object_player2.x - x;
var targetV = object_player2.y - y;
// Assign Variable
PATHS[3] = !position_meeting(x, y + 64, object_block) and direction !=90;
PATHS[2] = !position_meeting(x - 64, y, object_block) and direction !=0;
PATHS[1] = !position_meeting(x, y - 64, object_block) and direction !=270;
PATHS[0] = !position_meeting(x + 64, y, object_block) and direction !=180;
// If Expression
if(abs(targetH) < abs(targetV))
{
// If Variable
if(PATHS[1 - sign(targetH)] == 1)
{
// Assign Variable
image_angle = 90 - 90 * sign(targetH);
}

// Else
else
{
// If Variable
if(PATHS[2 + sign(targetV)] == 1)
{
// Assign Variable
image_angle = 180 + 90 * sign(targetV);
}

// Else
else
{
// Declare Temp
var rand = irandom(3);

// While Loop
while ((PATHS[rand] == 0)) {
// Assign Variable
rand = (rand + 1)mod 4;
}

// Assign Variable
image_angle = rand * 90;
}
}
}
// Else
else
{
// If Variable
if(PATHS[2 + sign(targetV)] == 1)
{
// Assign Variable
image_angle = 180 + 90 * sign(targetV);
}

// Else
else
{
// If Variable
if(PATHS[1 - sign(targetH)] == 1)
{
// Assign Variable
image_angle = 90 - 90 * sign(targetH);
}

// Else
else
{
// Declare Temp
var rand = irandom(3);

// While Loop
while ((PATHS[rand] == 0)) {
// Assign Variable
rand = (rand + 1) mod 4;
}

// Assign Variable
image_angle = rand * 90;
}
}
}
}
 
// If Expression
if(((x - 32) + (y -32)) mod 64 = 0)
{
// Set Speed
speed = 2;
// Declare Temp
var PATHS = 0;
var targetH = object_player2.x - x;
var targetV = object_player2.y - y;
// Assign Variable
PATHS[3] = !position_meeting(x, y + 64, object_block) and direction !=90;
PATHS[2] = !position_meeting(x - 64, y, object_block) and direction !=0;
PATHS[1] = !position_meeting(x, y - 64, object_block) and direction !=270;
PATHS[0] = !position_meeting(x + 64, y, object_block) and direction !=180;
// If Expression
if(abs(targetH) < abs(targetV))
{
// If Variable
if(PATHS[1 - sign(targetH)] == 1)
{
// Assign Variable
image_angle = 90 - 90 * sign(targetH);
}

// Else
else
{
// If Variable
if(PATHS[2 + sign(targetV)] == 1)
{
// Assign Variable
image_angle = 180 + 90 * sign(targetV);
}

// Else
else
{
// Declare Temp
var rand = irandom(3);

// While Loop
while ((PATHS[rand] == 0)) {
// Assign Variable
rand = (rand + 1)mod 4;
}

// Assign Variable
image_angle = rand * 90;
}
}
}
// Else
else
{
// If Variable
if(PATHS[2 + sign(targetV)] == 1)
{
// Assign Variable
image_angle = 180 + 90 * sign(targetV);
}

// Else
else
{
// If Variable
if(PATHS[1 - sign(targetH)] == 1)
{
// Assign Variable
image_angle = 90 - 90 * sign(targetH);
}

// Else
else
{
// Declare Temp
var rand = irandom(3);

// While Loop
while ((PATHS[rand] == 0)) {
// Assign Variable
rand = (rand + 1) mod 4;
}

// Assign Variable
image_angle = rand * 90;
}
}
}
}
The enemies spawn in the room randomly and if they spawn over a wall or a block they respawn somewhere else. Once they spawn they snap to the grid.
 

TheouAegis

Member
Your code is setting image_angle, it's not setting direction that I see. You need to update the value of direction.

Image angle just affects the direction that the Sprite is facing. direction actually affects the the direction of motion when you use the speed variable.
 
Your code is setting image_angle, it's not setting direction that I see. You need to update the value of direction.

Image angle just affects the direction that the Sprite is facing. direction actually affects the the direction of motion when you use the speed variable.
so could I just change image_angle to direction?
 

TheouAegis

Member
In this case, yes.

I doubt you want to actually use image_angle to change the sprite. image_angle is used for fully top-down projects. Usually maze games are considered 3/4-view; so you'd change the whole sprite and not rotate it. Change the sprite at the same tim you change direction.

 

TheouAegis

Member
Yeah. Change the targetH and targetV values to different locations.

In Pac-Man when you eat a big pill, the ghosts are instructed to run to each of the four corners. Since each corner is a wall, the ghosts reroute constantly so they don't get stuck.

What I do is set two variables targetX and targetY in each ghost object in the Begin Step to where I want that particular ghostto go. One might go to player.x and player.y, while the other might go to player.x+64, player.y+64.
 
Last edited:

TheouAegis

Member
Code:
if(((x - 32) + (y -32)) mod 64 = 0)
{
// Set Speed
speed = 2;
// Declare Temp
var PATHS = 0;

// Assign Variable
PATHS[3] = !position_meeting(x, y + 64, object_block) and direction !=90;
PATHS[2] = !position_meeting(x - 64, y, object_block) and direction !=0;
PATHS[1] = !position_meeting(x, y - 64, object_block) and direction !=270;
PATHS[0] = !position_meeting(x + 64, y, object_block) and direction !=180;

// Declare Temp
var rand = irandom(3);

// While Loop
while ((PATHS[rand] == 0)) {
// Assign Variable
rand = (rand + 1) mod 4;
}

// Assign Variable
image_angle = rand * 90;
}
Essentially just those bits of the code.
 
Code:
if(((x - 32) + (y -32)) mod 64 = 0)
{
// Set Speed
speed = 2;
// Declare Temp
var PATHS = 0;

// Assign Variable
PATHS[3] = !position_meeting(x, y + 64, object_block) and direction !=90;
PATHS[2] = !position_meeting(x - 64, y, object_block) and direction !=0;
PATHS[1] = !position_meeting(x, y - 64, object_block) and direction !=270;
PATHS[0] = !position_meeting(x + 64, y, object_block) and direction !=180;

// Declare Temp
var rand = irandom(3);

// While Loop
while ((PATHS[rand] == 0)) {
// Assign Variable
rand = (rand + 1) mod 4;
}

// Assign Variable
image_angle = rand * 90;
}
Essentially just those bits of the code.
I put in just this code and I think it works but they are ignoring the wall blocks
 

TheouAegis

Member
I didn't abandon this. I got distracted by other stuff. I'll revisit the code tonight maybe. My guess is grid alignment issues, but then it should have never worked.
 
Top