JEMcG
Member
Hello!
So I have been wrestling for some time with pathing. I'm trying to make a game where the player can choose whether to use keyboard or controller movement (which works just fine) or mouse movement.
For mouse movement so far I am using an mp_grid and mp_grid_path to do the movement.
This is working really well for finding where the player needs to go and avoiding abjects. I have a script set up for if the player clicks within a collision etc...
So I'd like to keep this system for finding the path the player needs to take.
My main issue is that when the player (or AI) follows these paths, it tends to be quite janky, in terms of the animation.
Below is the 8-directional code I'm using (onpath is what I'm using to signal they are moving using the mouse):
When the character follows they path, especially when going on a diagonal, they tend to flit between two frames rapidly which looks rather bad. I have tried turning the "allow diagonal" on and off within the mp_grid_path code, but neither work.
I don't have this issue with keyboard or controller movement, which is based around point_direction and then moving the player towards it.
I have searched but I can't tell if there's anyway to pull the points from an mp_grid_path and then move towards them as I would were I using key presses?
This seems like it would be the cleanest way to me, although perhaps there's a more elegant way?
I'll post my movement code below also in case that helps:
So I have been wrestling for some time with pathing. I'm trying to make a game where the player can choose whether to use keyboard or controller movement (which works just fine) or mouse movement.
For mouse movement so far I am using an mp_grid and mp_grid_path to do the movement.
This is working really well for finding where the player needs to go and avoiding abjects. I have a script set up for if the player clicks within a collision etc...
So I'd like to keep this system for finding the path the player needs to take.
My main issue is that when the player (or AI) follows these paths, it tends to be quite janky, in terms of the animation.
Below is the 8-directional code I'm using (onpath is what I'm using to signal they are moving using the mouse):
GML:
//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);
I don't have this issue with keyboard or controller movement, which is based around point_direction and then moving the player towards it.
I have searched but I can't tell if there's anyway to pull the points from an mp_grid_path and then move towards them as I would were I using key presses?
This seems like it would be the cleanest way to me, although perhaps there's a more elegant way?
I'll post my movement code below also in case that helps:
Code:
//----------------------MOVEMENT
//KB or Controller
//Inputs
hInput = global.right - global.left;
vInput = global.down - global.up;
if(hInput != 0 or vInput != 0){
//reset path
if(path_exists(wpath)){
path_delete(wpath);
finalx = -1;
finaly = -1;
onpath = false;
wpath = -1;
}
//Calculate direction (including changing diagonal speed)
dir = point_direction(0, 0, hInput, vInput);
//Make changes for isometric movement
if(dir == 135) or (dir == 315){ iso_buff = 18.5}
else if(dir == 225) or (dir == 45){ iso_buff = -18.5 }
else { iso_buff = 0;}
//Calculate movement
moveX = lengthdir_x(spd, dir + iso_buff);
moveY = lengthdir_y(spd, dir + iso_buff);
//----Collisions
//Horizontal
if(place_meeting(x+sign(moveX), y, obj_col)){
repeat(abs(moveX)){
if(!place_meeting(x+sign(moveX), y, obj_col)){ x += sign(moveX);}
else { break;}
}
moveX = 0;
}
//Vertical
if(place_meeting(x, y+sign(moveY), obj_col)){
repeat(abs(moveY)){
if(!place_meeting(x, y+sign(moveY), obj_col)){ x += sign(moveY);}
else { break;}
}
moveY = 0;
}
//Apply Movement
x += moveX;
y += moveY;
}
//Mouse Movement
if(mouse_check_button_pressed(mb_left)){
//wipe previous path
if(path_exists(wpath)){
path_end();
path_clear_points(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, true);
path_start(wpath, spd, path_action_stop, false);
finalx = mx;
finaly = my;
onpath = true;
}
//---Animations
//when path ends, turn off anims
if(abs(x-finalx)<1 and abs(y-finaly)<1){ //ensure you're less than 1 pixel from target
path_delete(wpath);
finalx = -1;
finaly = -1;
onpath = false;
wpath = -1;
}
//get Direction info for anim
if(onpath){
dir = direction;
}