SOLVED Problem with changing/deleting paths

JEMcG

Member
Hi,

I've been making a click to move system (that works alongside keyboard movement), which works other than one irritating bug.

When I click a path is made and I use mp_grid_path to move the character.
I've linked this to the animation system. When the character reaches their destination, this deletes the path and resets the variables, stopping the character.

This works just fine unless I click a second time.
This uses the same variable/path (wpath) though I have set it to delete on click to stop several paths being generated.
This does not seem to work and if the mouse is clicked prior to reaching the end of the path, nothing resets and the player continues to animate.

Wondered if anyone could help as to why?

(hInput & vInput are from the keyboard movement and the script "space_check" just finds the nearest free space in the event of a collision.)

Thanks!

STEP EVENT:

//Mouse Movement
if(mouse_check_button_pressed(mb_left)){
//wipe previous path
if(path_exists(wpath)){
path_delete(wpath);
}
finalx = -1;
finaly = -1;
onpath = false;
wpath = -1;
//Get mouse location
var mx = mouse_x;
var my = mouse_y;
//Is this on a collision?
if(position_meeting(mx, my, obj_col)){
var newsp = space_check(mx, my);
//change mx/y to new location
mx = newsp[0];
my = newsp[1];
}
//move to mx/my
wpath = path_add();
mp_grid_path(global.mgrid, wpath, x, y, mx, my, false);
path_start(wpath, spd, path_action_stop, false);
finalx = mx;
finaly = my;
onpath = true;
}
//---Animations
//turn off anim
if((x == finalx) and (y == finaly)){
path_delete(wpath);
finalx = -1;
finaly = -1;
onpath = false;
wpath = -1;
}

//get Direction info for anim
if(onpath){
dir = direction;
}

DRAW EVENT:
//Work out anim frame
if(hInput != 0 or vInput != 0 or onpath){
y_frame = floor(dir/45);
//Increment frame for animation (if we make an idle anim take this out of IF)
x_frame += anim_speed/room_speed;
if(x_frame >= anim_length) x_frame = 0;
} else {
x_frame = 0.9;
}

var xx = x-x_offset;
var yy = y-y_offset;

//Draw Sprite
draw_sprite_part(spr_mc, 0, floor(x_frame)*frame_width, y_frame*frame_height, frame_width, frame_height, xx, yy);
 
Your getting pretty close now, your definitely on the right track. What does wpath contain on the second click? Is it just an empty path? Or still set to -1 or what exactly? It may be related to trying to destroy it and recreate it and use it with mp grid all in the same step, though I think that is unlikely. However, I would probably suggest not destroying the path, but clearing it instead. Delete the path when the parent object is destroyed or room end or whatever, but for moving around you really only need the one path that you fill/empty. Think of a path as a special data structure where it's basically just a list of x/y positions with some specialized functions.
 

JEMcG

Member
Your getting pretty close now, your definitely on the right track. What does wpath contain on the second click? Is it just an empty path? Or still set to -1 or what exactly? It may be related to trying to destroy it and recreate it and use it with mp grid all in the same step, though I think that is unlikely. However, I would probably suggest not destroying the path, but clearing it instead. Delete the path when the parent object is destroyed or room end or whatever, but for moving around you really only need the one path that you fill/empty. Think of a path as a special data structure where it's basically just a list of x/y positions with some specialized functions.
If I let it resolve it will go to -1, then change to zero when I click and a new path begins.
If I click twice the number appears to rocket up to however many paths have been made in total, even those that have been deleted.

Strangely enough the code for deleting and wiping the variables is used when I press WASD (which are my keyboard controls) and then happily resets it. So you may be on to something with that theory.
I will give path_clear_points a go.
Thanks for your help!
 

TheouAegis

Member
You need to call path_stop(). Or was it path_end()? All path_delete() does is destroy the path resource, not the path that the instance is actually using. This is also why you can't rotate, scale, or shift a path and expect the instance using that path to be adjusted accordingly, because you're modifying the path resource, not the instance's path data.
 

JEMcG

Member
Ok so both of your ideas were great, and needed, but sadly didn't work in isolation.

To fix it I had to end the path on click, and I also cleared it rather than deleting it (on click only, if it naturally resolved I deleted it).

However, it stayed broken.
I found that for some reason if I had it divert midpath gamemaker would resolve the path early sometimes by a fraction of a pixel.

So if the target was x = 320, y=100, it would sometimes send the character to x =320, y =99.758937.
As such I had to change my "end path" code to as follows:


//---Animations
//turn off anim
if((x <= finalx+1 and x >= finalx-1) and (y >= finaly-1 and y <= finalx+1)){
path_delete(wpath);
finalx = -1;
finaly = -1;
onpath = false;
wpath = -1;
}

Thank you both for your help!
 

TheouAegis

Member
if((x <= finalx+1 and x >= finalx-1) and (y >= finaly-1 and y <= finalx+1)){
If you copy-pasted that, you have a typo in the last conditional.

You can truncate that to
if abs(x-finalx)<1 && abs(y-finaly)<1

But couldn't you have just checked if(path_index && path_speed==0)? Doesn't path_speed get set to 0 at the end of the path if you set the endaction to stop?
 

JEMcG

Member
If you copy-pasted that, you have a typo in the last conditional.

You can truncate that to
if abs(x-finalx)<1 && abs(y-finaly)<1

But couldn't you have just checked if(path_index && path_speed==0)? Doesn't path_speed get set to 0 at the end of the path if you set the endaction to stop?
Thanks you just saved future me a huge headache!

As for the path thing, that makes sense but using that code and substituting in my path variable (or using path_exists) doesn't seem to work.
I'm not sure why, I'm rather new to paths (and coding in general) but that causes him to not stop animating even on a single click.

I've used the truncated code for now and that works perfectly. Thanks!
 
Top