GM:S 1.4 four directional grid movement issue

Discussion in 'Programming' started by TheNegroShoddy, Sep 10, 2019.

  1. TheNegroShoddy

    TheNegroShoddy Member

    Joined:
    Jul 11, 2016
    Posts:
    417
    Hello, I'm having an issue with my four-directional grid movement code. As you can see in the video below, there is something weird going on with the movement. At certain point near the end I get stuck when reaching the edge of the screen. The movement in general looks weird when the movement keys are held down and not simply pressed. Any ideas how to fix this?

    Code:
    Create Event:
    execute code:
    
    /// Initialize General variables
    
    // Define the current location of the player on the grid
    gridX = ( x div global.cellWidth ); // Cell within the row that the player is on (going horizontally) - starting from 0
    gridY = ( y div global.cellHeight ); // Cell within the column that the player is on (going vertically) - starting from 0
    
    // Define variables to store the position the player is moving from on the grid.
    gridFromX = gridX; // Set to gridX by default since the player is not in the process of moving by default.
    gridFromY = gridY; // Set to gridY by default since the player is not in the process of moving by default.
    
    // Define variables to store where the player is moving to on the grid.
    gridToX = gridX; // Set to gridX by default since the player is not in the process of moving by default.
    gridToY = gridY; // Set to gridY by default since the player is not in the process of moving by default.
    
    //
    pState = PLAYER_ST.IDLE; // The state the player is in
    pDir = DIR.DOWN; // Direction the player is moving in/facing
    
    //
    walkAniLength = 0.5; // The time it will take to cross one cell in seconds.
    walkAniTime = 0; // How much of the animation has played out in seconds.
    
    //
    walkSpd = 4;
    runSpd = walkSpd * 2;
    spd = walkSpd;
    
    Step Event:
    execute code:
    
    /// Player States
    switch( pState )
    {
       case PLAYER_ST.IDLE:
      
           if global.charControlEnabled == true && global.inputDisabled == false && global.gamePaused == false
           {
               if keyboard_check( global.leftKey ) && gridX > 0 { srcMovePlayer( DIR.LEFT ); exit; }
               if keyboard_check( global.rightKey ) { srcMovePlayer( DIR.RIGHT ); exit;  }          
               if keyboard_check( global.upKey ) && gridY > 0 { srcMovePlayer( DIR.UP ); exit; }
               if keyboard_check( global.downKey ) { srcMovePlayer( DIR.DOWN ); exit;  }          
           }
      
       break;
    
       case PLAYER_ST.WALKING:
           var walkTimeLeft = walkAniTime / walkAniLength;
           var movingGridX = lerp( gridFromX, gridToX, walkTimeLeft );
           var movingGridY = lerp( gridFromY, gridToY, walkTimeLeft );
            
       // Gradually increase the walkAniTime variable to indicate how many seconds the player walking animation has played.  
           walkAniTime += spd * ( 1 / room_speed );
          
         // Set the new x and y coordinates by multiplying the value between two points interporlated by the walking time by the cell width/height.
           x = ( movingGridX * global.cellWidth );
           y = ( movingGridY * global.cellHeight );
          
           if walkTimeLeft >= 1
           {
               walkAniTime = 0; // Reset variable
               walkTimeLeft = 1; // Ensure variable doesn't exceed 1
               pState = PLAYER_ST.IDLE; // Change state back to idle                  
           }
          
       break;
      
    }
    
    srcMovePlayer()
    Code:
    /// srcMovePlayer( DIRECTION )
    /*
        This script sets the player's grid related position variables and changes the state and direction of the player object prior to moving.
        Pass enum DIR as an argument based on the key pressed by the player.
    
        The method used to move the player is similar to doing:
            gridToX = gridX + ( keyboard_check( global.leftKey ) - keyboard_check( global.rightKey ) );
            gridToY = gridY + ( keyboard_check( global.upKey ) - keyboard_check( global.downKey ) );
    
    */
    var inputDir = argument0; // The direction the player should move in based on the player's input of either left, right, up, or down.
    var addToGridX = 0; // Must be 0 by default.
    var addToGridY = 0; // Must be 0 by default.
    
    // Change the value of either addToGridX or addToGridY depending on the key pressed by the player.
    if inputDir == DIR.LEFT { addToGridX = -1; }
    if inputDir == DIR.RIGHT { addToGridX = 1; }
    if inputDir == DIR.UP { addToGridY = -1; }
    if inputDir == DIR.DOWN { addToGridY = 1; }
    
    // Set the variables indicating where the player is moving from to the player's current position within the grid.
    gridFromX = gridX;
    gridFromY = gridY;
    
    // Set the variables indicating where the player is moving to within the grid.
    gridToX = gridX + addToGridX;
    gridToY = gridY + addToGridY;
      
    // Set the current position of the player within the grid.
    gridX = gridToX;
    gridY = gridToY;
      
    // Change the direction and player state.
    pDir = inputDir;
    pState = PLAYER_ST.WALKING;  
    
     
    Last edited: Sep 10, 2019
  2. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,780
    Because u are setting the sprite back to idle after every cell. Set it back to idle only if the player isn't trying to move or if he can't walk in the direction he's trying to go.
     
  3. TheNegroShoddy

    TheNegroShoddy Member

    Joined:
    Jul 11, 2016
    Posts:
    417
    Tried this and it didn't work:
    Code:
        case PLAYER_ST.WALKING:
            var walkTimeLeft = walkAniTime / walkAniLength;
            var movingGridX = lerp( gridFromX, gridToX, walkTimeLeft );
            var movingGridY = lerp( gridFromY, gridToY, walkTimeLeft );
              
        // Gradually increase the walkAniTime variable to indicate how many seconds the player walking animation has played.  
            walkAniTime += spd * ( 1 / room_speed );
          
          // Set the new x and y coordinates by multiplying the value between two points interporlated by the walking time by the cell width/height.
            x = ( movingGridX * global.cellWidth );
            y = ( movingGridY * global.cellHeight );
          
            if walkTimeLeft >= 1
            {
                walkAniTime = 0; // Reset variable
                walkTimeLeft = 1; // Ensure variable doesn't exceed 1                  
            }
          
            if keyboard_check_released( global.leftKey ) || keyboard_check_released( global.rightKey ) || keyboard_check_released( global.upKey ) ||
            keyboard_check_released( global.downKey )
            {
                pState = PLAYER_ST.IDLE; // Change state back to idle
            }
          
        break;
    
    Also tried:
    Code:
    if (!keyboard_check( global.leftKey )) && (!keyboard_check( global.rightKey )) && (!keyboard_check( global.upKey )) &&
            (!keyboard_check( global.downKey ))
    
     
  4. TheNegroShoddy

    TheNegroShoddy Member

    Joined:
    Jul 11, 2016
    Posts:
    417
    Nothing I'm trying seems to work. Tried doing it this way, but made things worse:
    Code:
        case PLAYER_ST.WALKING:   
            if (!keyboard_check( global.leftKey )) && (!keyboard_check( global.rightKey )) && (!keyboard_check( global.downKey )) && (!keyboard_check( global.upKey ))
            {
                var walkTimeLeft = walkAniTime / walkAniLength;
                var movingGridX = lerp( gridFromX, gridToX, walkTimeLeft );
                var movingGridY = lerp( gridFromY, gridToY, walkTimeLeft );
                   
            // Gradually increase the walkAniTime variable to indicate how many seconds the player walking animation has played.   
                walkAniTime += spd * ( 1 / room_speed );
               
              // Set the new x and y coordinates by multiplying the value between two points interporlated by the walking time by the cell width/height. 
                x = ( movingGridX * global.cellWidth );
                y = ( movingGridY * global.cellHeight );
           
                if walkTimeLeft >= 1 
                {
                    walkAniTime = 0; // Reset variable
                    walkTimeLeft = 1; // Ensure variable doesn't exceed 1     
                }
            }
            else
            {
                walkAniTime = 0;
                pState = PLAYER_ST.IDLE; // Change state back to idle         
            }
        break;
    
    Any other ideas or is it something I'm missing.
     
  5. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    786
    So the problem is with the sprite? Where are you changing the sprite from walk to idle?
     
  6. TheNegroShoddy

    TheNegroShoddy Member

    Joined:
    Jul 11, 2016
    Posts:
    417
    The problem is with movement itself. The animation is being changed the step event of the character object:
    Code:
    /// Animation Setting
    
    // Pause and play out animation depending on whether the game was paused or not.
    if global.gamePaused == false { image_speed = aniSpd; } else { image_speed = 0; }
    
    // Automatically Switch between animations
    switch( pState )
    {
        case PLAYER_ST.IDLE:
            if sprite_index != charIdleSpr[ pDir ] { image_index = 0; sprite_index = charIdleSpr[ pDir ]; setAniSpd( sprite_index ); }      
        break;
    
        case PLAYER_ST.WALKING:
            if sprite_index != charWalkSpr[ pDir ] { image_index = 0; sprite_index = charWalkSpr[ pDir ]; setAniSpd( sprite_index ); }
          
        break;
      
        case PLAYER_ST.RUNNING:
      
      
        break;
      
        case PLAYER_ST.HURT:
      
        break;
      
        case PLAYER_ST.ATTACKING:
      
      
        break;
    }
    
    
    The code I posted before is from the character object's parent.
     
  7. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    786
    @TheNegroShoddy Edit: nevermind.

    Hmm, I don't know man. The movement looks ok except for a stutter in between cells. I'm not sure tbh. Is the stutter b/c of the animation As @TheouAegis said. I didn't see any walk animation when I watched the video.

    Sorry I can't be of more help.
     
    Last edited: Sep 12, 2019
  8. TheNegroShoddy

    TheNegroShoddy Member

    Joined:
    Jul 11, 2016
    Posts:
    417
    Sorry I should've been more clear. Yeah I wanted to know how to fix that weird stutter with the movement, plus sometimes the character won't stop moving one direction even if I let the key go.
     
  9. TheNegroShoddy

    TheNegroShoddy Member

    Joined:
    Jul 11, 2016
    Posts:
    417
    Oh I didn't see you edit your post again, well I don't have a walk animation yet, only two sprites I was given. Using one for the idle and one for the walking animation, although the difference is probably hard to tell. The animation code really shouldn't be affecting how movement is behaving cause the code is separate.
     
    Last edited: Sep 12, 2019

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