GameMaker: Studio

GameMaker: Studio

View Stats:
Al_Ka_Pwn Sep 4, 2018 @ 4:32am
Help with pathfinding
So I have some enemies that I'm trying to make pathfind correctly and I'm having some trouble because I'm not sure how to make them update their movement to move towards the player correctly, and I'm also not sure how to make them stop when they get near the player instead of walking forward.

So this is what I have in my enemy create event

//Create the Path path = path_add();

This is what I have in my step event for the enemy, I was told that having the pathfinding happen every step is too intensive so to create an alarm for it

if distance_to_object(monk_obj) <= 300 alarm[1] = 3;

and then inside the alarm I have this

if(mp_grid_path(global.grid, path, x, y, monk_obj.x, monk_obj.y, 1)) { path_start(path, 4, path_action_continue, false); }

I'm still trying to learn how to make the pathfinding work correctly, if anyone has any suggestions that could help I'd really appreciate it! Thanks in advance.
< >
Showing 1-7 of 7 comments
The Winter Bud Sep 4, 2018 @ 4:52am 
From the manual[docs.yoyogames.com]
globalvar grid; grid = mp_grid_create(0, 0, room_width div 32, room_height div 32, 32, 32); // NOTICE YOU NEED A GRID mp_grid_add_instances(grid, obj_wall, false);// ADDING OBSTACLES TO THE GRID with (obj_Enemy) { path = path_add(); if mp_grid_path(grid, path, x, y, obj_Player.x, obj_Player.y, 1) { path_start(path, 0, 3, 0); } }

As you can see from GM's example you will first need a grid, and then a controller object updates the enemy every few seconds.

You can convert this to your style by
1. creating a grid in the create event of the enemy (without globalvar in front of it) and start the alarm event to update 30-90 steps (1-3 seconds)
grid=mp_grid-create(0,0,room_width div 32,room_height div 32,32,32); mp_grid_add_instances(grid,obj_wall,false); path = path_add(); if mp_grid_path(grid, path, x, y, obj_Player.x, obj_Player.y, 1) { path_start(path, 0, 3, 0); } } alarm[0]=30;
2. in the alarm event update the path, start the alarm again
path_end(); // stop the current path path_clear_points(path); // clear all path points in the path if(mp_grid_path(grid,path,x,y,obj_Player.x,obj_Player.y,1)){ path_start(path,0,3,0); } alarm[0]=30;


EDIT: the code has been revised a few times since original post. I added in the path_end() and path_clear_points() functions in the alarm event for possible old/new path conflicts. You'll also notice that you'll have to change the names of objects, paths, and other resources to fit your game. Also the values of the path_start function may not be your desired values.
Last edited by The Winter Bud; Sep 4, 2018 @ 5:02am
The Winter Bud Sep 4, 2018 @ 5:08am 
One tweak you could try is setting the alarm 0 to go off in the number of steps equal to the distance the enemy is away from the player
alarm[0]=distance_to_object(obj_Player) div moveSpeed;
the farther away the enemy is from the player the longer it takes for it to get an update to it's path.
Last edited by The Winter Bud; Sep 4, 2018 @ 5:09am
MrDave Sep 4, 2018 @ 12:25pm 
Just to note.
if distance_to_object(monk_obj) <= 300 alarm[1] = 3;
If you do this every frame alarm[1] will never run because every frame it will reset the counter back to 3.
Al_Ka_Pwn Sep 5, 2018 @ 1:54am 
Originally posted by MrDave:
Just to note.
if distance_to_object(monk_obj) <= 300 alarm[1] = 3;
If you do this every frame alarm[1] will never run because every frame it will reset the counter back to 3.


So what's the proper way to make it trigger whenever the player object comes into range then?
The Winter Bud Sep 5, 2018 @ 2:27pm 
Originally posted by Al_Ka_Pwn:
So what's the proper way to make it trigger whenever the player object comes into range then?


if(distance_to_object(monk_obj)<=300 && alarm[1]<0){ alarm[1]=3; }

Alarms work by counting down. You give the alarm a starting value (such as 3) and every step it will count down 1 until it reaches (0) and triggers the event. When the alarm is shut off (aka: not counting) the value is (-1)

So to expand on MrDave's comment. When you say
distance_to_object(monk_obj)<300 alarm[1]=3;
in the step event you are resetting the value of the alarm. This doesn't allow the alarm to count down to zero as it keeps getting set to 3. The solution is to check for the distance and then check to see if the alarm is going off already. If the alarm==-1 then the alarm is not counting allowing you to set it.
Last edited by The Winter Bud; Sep 5, 2018 @ 2:56pm
Al_Ka_Pwn Sep 6, 2018 @ 4:00am 
Originally posted by The Winter Bud:
Originally posted by Al_Ka_Pwn:
So what's the proper way to make it trigger whenever the player object comes into range then?


if(distance_to_object(monk_obj)<=300 && alarm[1]<0){ alarm[1]=3; }

Alarms work by counting down. You give the alarm a starting value (such as 3) and every step it will count down 1 until it reaches (0) and triggers the event. When the alarm is shut off (aka: not counting) the value is (-1)

So to expand on MrDave's comment. When you say
distance_to_object(monk_obj)<300 alarm[1]=3;
in the step event you are resetting the value of the alarm. This doesn't allow the alarm to count down to zero as it keeps getting set to 3. The solution is to check for the distance and then check to see if the alarm is going off already. If the alarm==-1 then the alarm is not counting allowing you to set it.

so would that be something like

in the step event

if distance_to_object(monk_obj)<=300 and alarm[1] ==-1
then execute all the code?
The Winter Bud Sep 6, 2018 @ 6:07am 
tomato, tomato really whether you use ==-1 OR <0 it's the same thing. Because the alarm will never go below -1.

EDIT: at zero the alarm event will trigger any actions/code you have in the alarm event. Doing something like this can skip the event all together
// step event if(alarm[0]==1) alarm[0]=-1; // skipping (0) will result in the alarm not executing
Though I have no idea why you would use code such as this, I use it mearly to show an example.

EDIT: setting the alarm to zero executes the alarm's action/code. This is how we short circuit the alarm. Say you set the alarm to go off in 30 steps. Like patrolling. But then the player comes into view and you want to stop his alarm and go to chase. You would just set the alarm to zero to execute the actions, or -1 if you just want to stop the alarm
// assume the alarm[0] was set to 30 in the create event // step event if(distance_to_object(obj_player)<100)){ // if player is in range if(alarm[0]>0){ // if alarm is active if(place_snappped(32,32)){ // if snapped to the grid alarm[0]=-1; // stop the alarm }else{ // if not snapped to the grid alarm[0]=0; // set off the alarm early } }else{ // if alarm is not active alarm[0]=30; // activate the alarm } }else{ // the player is not in range if(alarm[0]>0){ // alarm is active if(place_snapped(32,32)){ // if snapped to a grid alarm[0]=-1; // stop alarm }else{ // not snapped to a grid alarm[0]=0; // set alarm off early } }else{ // alarm is not active alarm[0]=30; // activate alarm } }
Last edited by The Winter Bud; Sep 11, 2018 @ 5:31pm
< >
Showing 1-7 of 7 comments
Per page: 1530 50

Date Posted: Sep 4, 2018 @ 4:32am
Posts: 7