Help with polishing movement code (gif included)

BQubed

Member
I have movement code working pretty well at the moment. The NPCs go where they're supposed to and face the direction I want them to afterwards. The only issue is that second they start moving there's this little moment where they move down and to the right before they begin going where they're supposed to go. It doesn't cause any problems but it looks a bit odd so I just wanted to polish that up but I can't find any reason they would do that in the code. I also set it that when NPCs are in the walk state they are unable to collide with the player so it's not a player-NPC collision issue. Here's a gif:

polishing_movement.gif

And I get the feeling someone will ask me to see the path grid so here's that too:

1617068707025.png

And last but not least, the code responsible for movement:


GML:
function MoveBegin() {
    // Initialize all the variables
    TargetX = x;
    TargetY = y;
    IsForcedMoving = false;
}
function MoveTo(x, y, face) {
    // Set the new target posiion
    TargetX = x;
    TargetY = y;
    Face_Dir = face;
    IsForcedMoving = true;
}
function MoveUpdate(spd) {
    oPlayer.state = PlayerStateInteract;
    // if not forced movement, exit
    if(!IsForcedMoving) exit;
    // get the distance to the target
    var dis = point_distance(x, y, TargetX, TargetY);
    // if we are still far away from the target, then move to it
    if(dis > spd+2) {
        // get the direction from us to the target
        var dir = point_direction(x, y, TargetX, TargetY);
        // use trig to calculate the deltaX and deltaY (how far to move in each axis this frame)
        var dx = lengthdir_x(spd, dir);
        var dy = lengthdir_y(spd, dir);
        
        //Horizontal movement with collisions
        if (place_meeting(x + dx, y, oCol))
        {
            repeat(abs(walk_speed))
            {
                if (!place_meeting(x+sign(dx), y, oCol)) { x += sign(dx); }
                else { break; }
            }
        }
        //Vertical movement with collisions
        if (place_meeting(x, y+dy, oCol))
        {
            repeat(abs(walk_speed))
            {
                if (!place_meeting(x, y+sign(dy), oCol)) { y += sign(dy); }
                else { break; }
            }
        }
 
        //Pathing Code       
        myPath = path_add();
        mp_grid_path(global.RoomGrid,myPath,x,y,TargetX,TargetY,false);
        path_start(myPath,walk_speed,path_action_stop,false);
        
        var total_frames = sprite_get_number(sprite_index) / 4;
        image_index = local_frame + (CARDINAL_DIR * total_frames);
        local_frame += sprite_get_speed(sprite_index) / FRAME_RATE;

        //Animation Loop
        if local_frame >= total_frames
        {
            animation_end = true;
            local_frame -= total_frames;
        } else { animation_end = false; }

    } else {
        // snap the last frame to the target and end force movement
        x = TargetX;
        y = TargetY;
        global.facing_dir = Face_Dir;
        IsForcedMoving = false;
    }

}
 

Pixel-Team

Master of Pixel-Fu
Looking at the generated path, it looks like this is expected behavior. Assuming you set a minimum distance between path points, you could increase this number a bit, causing the AI to skip the first path point and go to the second instead.
 

BQubed

Member
Actually I just went into this code mp_grid_path(global.RoomGrid,myPath,x,y,TargetX,TargetY,false); and set allow_diag to true and it eliminated the problem, however I distinctly recall setting it to false for a reason while I was building this code block. I'll keep it true for now and see if it troubles me later.
 
Top