GMS 2 Held item lags behind while moving

Discussion in 'Programming' started by hyperreality, Jun 10, 2019.

  1. hyperreality

    hyperreality Member

    Joined:
    Nov 19, 2017
    Posts:
    67
    I made an off-hand item which I'm having move based on obj.player's x and y, + or - fixed distances based on obj.player's current animation frame to account for the position of the character's hand as the sprite cycles through its animation. It works perfectly if the player is against a wall (the animation playing while the player's x,y doesn't change), but when obj.player it actually moving, the off-hand item appears behind it, only catching up once obj.player hits a collision. Similarly, the off-hand item doesn't accurately follow obj.player while jumping, and I can't figure out why that is.

    Here's the off-hand item's movement code:

    Code:
    var facingRight = global.facingRight;
    
    if(facingRight = false){
        switch(global.player_xFrame){
            case 0:
                image_angle = 135;
                x = obj_player.x+6;
                y= obj_player.y-24;
            break;
            
            case 2:
                image_angle = 135;
                x = obj_player.x+6;
                y= obj_player.y-24;
            break;
    
            case 1:
                image_angle = 175;
                x = obj_player.x+16;
                y= obj_player.y-30;
            break;
            
            case 3:
                image_angle = 95;
                x = obj_player.x-6;
                y= obj_player.y-20;
            break;
        }
    }
    
    else{
        switch(global.player_xFrame){
            case 0:
                image_angle = 225;
                x = obj_player.x-6;
                y= obj_player.y-24;
            break;
            
            case 2:
                image_angle = 225;
                x = obj_player.x-6;
                y= obj_player.y-24;
            break;
    
            case 1:
                image_angle = 185;
                x = obj_player.x-16;
                y= obj_player.y-30;
            break;
            
            case 3:
                image_angle = 265;
                x = obj_player.x+6;
                y= obj_player.y-20;
            break;
        }
    }
    Thanks!
     
  2. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    724
    Try putting everything that follows the player in the End Step.
     
    hyperreality likes this.
  3. hyperreality

    hyperreality Member

    Joined:
    Nov 19, 2017
    Posts:
    67
    Yeah, that's what I thought would fix it at first, but when it didn't work I didn't really know what else could be causing this. Any other thoughts?
     
  4. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,874
    Position is just a number (two numbers) so if something isn't where you want there's really only a few possibilities: (1) things are updated in the wrong order; or (2) there's a mistake in the math/code.

    For update order, perhaps player's x for a frame is updated after player's x is used to update this x. It also looks like you are basing the x on a specific frame index. So you'd also need to account for that as well.

    Otherwise double check all your math (and things the math is based off of). This could be off not only with the math you've used, but also with sprite origin positioning itself. This seems unlikely since you said it goes away, but given how you're doing it it seems like it would be easy to make a mistake. Remember that these could be affected by things like scale and rotation as well.
     
    hyperreality likes this.
  5. woods

    woods Member

    Joined:
    Jun 21, 2016
    Posts:
    182
    side note...probably unrelated but...

    just curios why is case 0 and case 2 the exact same?

    ;o) could be a typo and causing issues?
     
    hyperreality likes this.
  6. hyperreality

    hyperreality Member

    Joined:
    Nov 19, 2017
    Posts:
    67
    Because there are only 4 frames in this animation and frames 0 and 2 are identical, so this shouldn't affect anything.

    I'm wondering if it has to do with the fact that frame_x is incremented in obj.player's draw event. If so, I guess I have to also have the item object draw itself for it to occur at the same time? I don't understand the timing of draw events yet.
     
  7. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,874
    You should not be incrementing the frame in the draw event. Not only would that cause this problem, for the reasons stated in my earlier post, if you ever have more than one view it will play at the wrong speed as the draw event fires once for each view. In short, remember (and follow) the manual's suggestion to only have draw code in the draw event.
     
    hyperreality likes this.
  8. hyperreality

    hyperreality Member

    Joined:
    Nov 19, 2017
    Posts:
    67
    Tried a few more thing and it still doesn't give the expected result...



    Now only the actual draw functions are in obj.player's draw event. The following is in obj.player's step event

    Code:
    //speed up animation while running
    
    if(run_pressed){
        var animationSpeed = 9;
    }
    else{
        animationSpeed = 6;
    }
    
    //select spritesheet row based on the direction the player is facing
    
    if(moveX < 0) {
        y_frame = 0;
        global.facingRight = false;
        global.player_xFrame = x_frame;
        global.player_yFrame = y_frame;
    }
    else if(moveX > 0){
        y_frame = 1;
        global.facingRight = true;
        global.player_xFrame = x_frame;
        global.player_yFrame = y_frame;
    }
    else{
        x_frame = 0;  
        global.player_xFrame = x_frame;
        global.player_yFrame = y_frame;
    }
    
    //change animation while in mid-air
    if(!place_meeting(x,y+1, obj_meta_colliderParent)){
        if(y < 0){
            if (global.facingRight = true) {
                x_frame = 0;
                y_frame = 2;
                global.player_xFrame = x_frame;
                global.player_yFrame = y_frame;
            }
            else{
                x_frame = 1;
                y_frame = 3;
                global.player_xFrame = x_frame;
                global.player_yFrame = y_frame;
            }
        }
        else if(global.facingRight = false){
            x_frame = 3;
            y_frame = 2;
            global.player_xFrame = x_frame;
            global.player_yFrame = y_frame;  
        }
        else{
            x_frame = 3;
            y_frame = 3;
            global.player_xFrame = x_frame;
            global.player_yFrame = y_frame;
        }
    
    }
    
    //increment frame for animation
    if(x_frame + animationSpeed/60 < animationLength){
        x_frame += animationSpeed/60;
        }
    else{
        x_frame = 0;
        }
    
    
    and this is in the item object's end step event

    Code:
    //position held in off-hand
    var facingRight = global.facingRight;
    
    if(facingRight = false){
        switch(global.player_xFrame){
            case 0:
                image_angle = 135;
                x = obj_player.x+6;
                y= obj_player.y-24;
            break;
           
            case 2:
                image_angle = 135;
                x = obj_player.x+6;
                y= obj_player.y-24;
            break;
    
            case 1:
                image_angle = 175;
                x = obj_player.x+16;
                y= obj_player.y-30;
            break;
           
            case 3:
                image_angle = 95;
                x = obj_player.x-6;
                y= obj_player.y-20;
            break;
        }
    }
    
    else{
        switch(global.player_xFrame){
            case 0:
                image_angle = 225;
                x = obj_player.x-6;
                y= obj_player.y-24;
            break;
           
            case 2:
                image_angle = 225;
                x = obj_player.x-6;
                y= obj_player.y-24;
            break;
    
            case 1:
                image_angle = 185;
                x = obj_player.x-16;
                y= obj_player.y-30;
            break;
           
            case 3:
                image_angle = 265;
                x = obj_player.x+6;
                y= obj_player.y-20;
            break;
        }
    }
    
     
    Last edited: Jun 11, 2019
  9. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,874
    the end step code uses the global.player_xFrame which is still be updated before x_frame is incremented. Try moving this code to the beginning of the player step event:

    Code:
    
    //increment frame for animation
    if(x_frame + animationSpeed/60 < animationLength){
       x_frame += animationSpeed/60;
       }
    else{
       x_frame = 0;
       }
    
    
     
  10. hyperreality

    hyperreality Member

    Joined:
    Nov 19, 2017
    Posts:
    67
    I tried it, but it didn't fix the issue. Any other thoughts?
     
  11. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    1,874
    Use the debugger and make sure all of the values are what they are supposed to be.
     
  12. TsukaYuriko

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    1,353
    Instead of letting things follow the player, consider making the player drag things along. That is, move the thing in the player's code, not in the thing's code. That way, you can ensure this happens after all movement has been applied to the player.

    That aside, check your Draw code and make sure they match. Ensure that both the player and the thing are using the same rounding, no mix-and-matching between round/floor/ceil or absence of either.
     
    woods likes this.
  13. hyperreality

    hyperreality Member

    Joined:
    Nov 19, 2017
    Posts:
    67
    Ok, guess I have to learn how that works at some point ;)
     
  14. hyperreality

    hyperreality Member

    Joined:
    Nov 19, 2017
    Posts:
    67
    I would love to be able to avoid the positioning issue like that, but then I'd still have collision issues so I can't take a shortcut this time.

    Edit: When I first read your post I thought of it in terms of drawing the object, but then I realized that you were talking of actually moving it so I tried to add the modified code to the player's step and it still didn't work.
     
    Last edited: Jun 13, 2019 at 1:07 PM

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice