Need help with tile based movement (like pokemon)

Hi, i’m trying to tile based movement like in pokemon 2d games.

Let’s say i want to move my character 1 tile to the right.
I don’t want him to teleport, I want his X position to go from his current position to his destination which is 1 tile (16px) to the right.

Here is my character class:

internal class Character
    {
        public static string direction;

        public static Vector2 charPosition = new Vector2(64, 32);

        public static Vector2 newPosition = new Vector2();

        public static float charSpeed = 1.0f;

        public static Rectangle sourceRectangle = new Rectangle(0, 0, 16, 32);

        public static void update(GameTime gameTime)
        {

        }

        public static void Draw(SpriteBatch _spriteBatch, Texture2D texture)
        {

            _spriteBatch.Draw(texture, charPosition, sourceRectangle, Color.White);

        }

        public static void MoveRight(GameTime gameTime)
        {

            float destination = charPosition.X + 16;

            while (charPosition.X < destination)
            {
                charPosition.X += (int)(charSpeed * gameTime.ElapsedGameTime.TotalMilliseconds) ;
            }
            
        }

In Game1.Update I start my MoveRight function once:

if (state.IsKeyDown(Keys.D) && prevState.IsKeyUp(Keys.D))
            {

                Character.MoveRight(gameTime);

            }

And in Game1.Draw I call my Character.draw function:

Character.Draw(_spriteBatch, charset);

I’m trying different things but I can only get my character to teleport or my game to freeze.

Any help is appreciated.

You have to do some kind of timed action. So what you’d want to do is, on each call to Game1.Update you’re going to move your character by a certain number of pixels. Record the target location that you want the character to end up at, and move one or more pixels towards that location on each call to Update (depending on how fast you want it to move).

The way you have it now is not gonna work because you’re literally going to move forward infinitely. You need to calc your destination once and not update it each time you’re calling MoveRight. And charSpeed * TotalMilliseconds is not going to work unless your charSpeed is very very low. TotalMilliseconds is a very high number, what you want to do is record TotalMilliseconds on each Update call and subtract it from the last time you recorded it to get your elapsed time, and use that for any calculations.

Thanks a lot for your answer @Ross_Arnold,
I feel so stupid, I had done the same thing in arduino but for some reason I thought it had to be done differently in monogame.

Here is my commented solution :

internal class Character
    {
        public static string direction;

        public static Vector2 charPosition = new Vector2(64, 32);

        public static Rectangle sourceRectangle = new Rectangle(0, 0, 16, 32);

        public static float timeAccumulator = 0.0f;

        public static float elapsedTime = 0.0f;

        public static float tempo = 10.0f;

        public static float destination = 0;

        public static bool movingRight = false;

        public static void update(GameTime gameTime)
        {
            timeAccumulator += (float)gameTime.ElapsedGameTime.TotalMilliseconds;   //Record the time since first update call

            if (movingRight == true)
            {
                if (charPosition.X < destination)                                   // if the charcter is not at his destination yet
                {
                    if (timeAccumulator - elapsedTime >= tempo)                     // If the time elapsed since last update call is bigger than "tempo"
                    {
                        charPosition.X += 0.5f;                                     // Move the character

                        elapsedTime = timeAccumulator;                              // Store the last time the update was called
                    }
                }
                else                                                                // if the charcter is at his destination
                {
                    movingRight = false;
                }
            }
        }

        public static void MoveRight()                                              // called once when the key is pressed
        {
            destination = charPosition.X + 16;                                      // desination is 1 tile to the right

            movingRight = true;
        }

        public static void Draw(SpriteBatch _spriteBatch, Texture2D texture)
        {
            _spriteBatch.Draw(texture, charPosition, sourceRectangle, Color.White);
        }
    }

Now i just have 99.99% left of my project to do :wink: