8-Direction 2D Animations Flicker

Started by
0 comments, last by -XM- 10 years, 6 months ago

Hi guys,

I'm working on a 2.5D game (think top down dungeon crawler/side view like Binding of Isaac) where characters can walk in all eight directions. The player animations work fine, but the AI animations have been flickering quite a bit between movement states. The AI moves and selects an animation based on its direction:



            //Select which animation we should currently be in:
            if (velocity != Vector2.Zero)
            {
                if (direction.X < 0 && direction.Y < 0 && currentAnimation.name != "Walk Up Left")
                    ChangeAnimation(Animations.WalkUpLeft);
                else if (direction.X > 0 && direction.Y < 0 && currentAnimation.name != "Walk Up Right")
                    ChangeAnimation(Animations.WalkUpRight);
                else if (direction.X < 0 && direction.Y > 0 && currentAnimation.name != "Walk Down Left")
                    ChangeAnimation(Animations.WalkDownLeft);
                else if (direction.X > 0 && direction.Y > 0 && currentAnimation.name != "Walk Down Right")
                    ChangeAnimation(Animations.WalkDownRight);
                else if (direction.X < 0 && direction.Y == 0 && currentAnimation.name != "Walk Left")
                    ChangeAnimation(Animations.WalkLeft);
                else if (direction.X > 0 && direction.Y == 0 && currentAnimation.name != "Walk Right")
                    ChangeAnimation(Animations.WalkRight);
                else if (direction.Y > 0 && direction.X == 0 && currentAnimation.name != "Walk Down")
                    ChangeAnimation(Animations.WalkDown);
                else if (direction.Y < 0 && direction.X == 0 && currentAnimation.name != "Walk Up")
                    ChangeAnimation(Animations.WalkUp);
            }
            else if (velocity == Vector2.Zero)
            {
                if (currentAnimation.name != "Idle")
                    ChangeAnimation(Animations.Idle);
            }

The problem is that there are times when the AI has to move diagonally, and after doing so he will move straight down for a few frames to correct himself so he's fully on the grid... it's only for a few frames so visually it looks very glitchy going between the two directions.

The direction variable never has floating point values... The AI movement code is like this:

1. Calculate the next tile we need to move to.

2. Make our direction variable look at this tile.

3. Round so the direction is always a whole number, to avoid jerky movement from floating point numbers.

The code I use to round is this:


        private void TrimDirection()
        {
            //Snap our direction to one of the eight cardinal directions:
            direction.X = (float)Math.Round(MathHelper.PiOver4 * (float)Math.Round(direction.X / MathHelper.PiOver4));
            direction.Y = (float)Math.Round(MathHelper.PiOver4 * (float)Math.Round(direction.Y / MathHelper.PiOver4));
        }

Movement code is like this:


                if (direction.X > 0)
                    MoveRight();
                else if (direction.X < 0)
                    MoveLeft();

                if (direction.Y > 0)
                    MoveDown();
                else if (direction.Y < 0)
                    MoveUp();

I've been trying to figure out how to approach this issue and I've hit a wall.... do I need to implement some type of animation hysteresis to avoid animations from changing so fast? Or is this issue deeper down inside how I make the AI move?

Thanks in advance!

Advertisement

Alright, I'm open if anyone has a better idea but my solution so far is this:

1. Store a variable that holds the maxSpeed the AI can run.

2. If the current animation is idle and we want to change to a movement animation, immediately change

3. Otherwise, if we're in a movement animation, stay in this animation unless our velocity exceeds maxSpeed * .8f in the direction we want to change.

If you wait until the velocity hits maxSpeed the animation change looks delayed, but if you set that range too low it doesn't catch all of the sudden changes. .8f works fine in my case.

I haven't had any problems so far... fingers crossed this did the trick!

This topic is closed to new replies.

Advertisement