0
\$\begingroup\$

What I want to achieve is a 'smooth' movement from tile to tile. I'd like for the movement to not be instant.

My map has 32x32px tiles and my player is also 32x32.

This is what I already have so far:

Player class:

       public Player()
       {
          state = State.Idle;
          destination = Sprite.Hitbox;
       }

       ...

       public void UpdatePosition(GameTime gameTime, Input input)
       {
        switch (state)
        {
            case State.Idle:
                if (input.IsKeyDown(Keys.Up) || input.IsKeyDown(Keys.Z))
                {
                    Sprite.Direction = Direction.UP;
                    Sprite.AnimationTimer += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
                    if (Sprite.Hitbox.Y > 0)
                    {
                        destination.Y -= 32;
                        state = State.MovingUp;
                    }
                }
                else if (input.IsKeyDown(Keys.Down) || input.IsKeyDown(Keys.S))
                {
                    Sprite.Direction = Direction.DOWN;
                    Sprite.AnimationTimer += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
                    if (Sprite.Hitbox.Y < (Globals.SCREEN_HEIGHT - Sprite.Hitbox.Height))
                    {
                        Sprite.AnimationTimer += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
                        destination.Y += 32;
                        state = State.MovingDown;                            
                    }
                }
                else if (input.IsKeyDown(Keys.Left) || input.IsKeyDown(Keys.Q))
                {
                    Sprite.Direction = Direction.LEFT;
                    Sprite.AnimationTimer += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
                    if (Sprite.Hitbox.X > 0)
                    {
                        destination.X -= 32;
                        state = State.MovingLeft;                        
                    }
                }
                else if (input.IsKeyDown(Keys.Right) || input.IsKeyDown(Keys.D))
                {
                    Sprite.Direction = Direction.RIGHT;
                    Sprite.AnimationTimer += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
                    if (Sprite.Hitbox.X < (Globals.SCREEN_WIDTH - Sprite.Hitbox.Width))
                    {
                        destination.X += 32;
                        state = State.MovingRight;                         
                    }
                }
                break;

            case State.MovingUp:
                if (Sprite.Hitbox.Y - (Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds) < destination.Y)
                {      
                    Sprite._hitbox.Y = destination.Y;
                    state = State.Idle;
                }
                else
                    Sprite._hitbox.Y -= (int)(Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
                break;

            case State.MovingDown:
                if (Sprite.Hitbox.Y + (Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds) > destination.Y)
                {
                    Sprite._hitbox.Y = destination.Y;
                    state = State.Idle;
                }
                else
                    Sprite._hitbox.Y += (int)(Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
                break;

            case State.MovingLeft:
                if (Sprite.Hitbox.X - (int)(Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds) < destination.X)
                {
                    Sprite._hitbox.X = destination.X;
                    state = State.Idle;
                }
                else
                    Sprite._hitbox.X -= (int)(Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
                break;

            case State.MovingRight:
                if (Sprite.Hitbox.X + (int)(Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds) > destination.X)
                {
                    Sprite._hitbox.X = destination.X;
                    state = State.Idle;
                }
                else
                    Sprite._hitbox.X += (int)(Globals.Speed * gameTime.ElapsedGameTime.TotalMilliseconds);
                break;
        }
    }

       public void Update(GameTime gameTime, Input input)
       {
          UpdatePosition(gameTime, input);
          base.Update(gameTime);
       }
\$\endgroup\$
1
\$\begingroup\$

The same deltaTime you use in the conditions of your if statements must be used also while assigning the new position.

newPos = pos + (speed * deltaTime);
if (newPos < targetPos) {
    pos = newPos;
}

Currently, you are assigning pos = targetPos, that's why it's moving instantly.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.