Changing animation of an AI

Hi, so I’ll get right into it. Let’s say I have 4 animations, one for each direction, upAnim, downAnim, leftAnim and rightAnim. I have
code that will move my AI sprite towards the player, but how do I tell it which animation should be used? I tried something like


if(vel.x < 0){
    //sprite is moving left
    setAnim(leftAnim);
}else{
    setAnim(rightAnim);
}

However, it get’s tricky with all four directions, and the sprite will switch animations rapidly at the wrong times.

What’s the best way to get animations to change based on the velocity of the sprite?

It really is all a matter of if statements. However, if the sprite is moving diagonally (e.g.: up and left), you need to choose if it should show the up animation or the left animation.

I’m also assuming you don’t want it to show the animation if the entity isn’t moving, so you would need another if statement to check if the entity is even moving.

Example code:


if(vel.x != 0){
    if(vel.x < 0){
        // sprite is moving left
        setAnim(leftAnim);
    }else{
        // sprite is moving right
        setAnim(rightAnim);
    }
}

// the y-check statements are placed after the x-check so moving up/down has "priority" over left/right
// if you want it the other way around, place the y-checks before the x-checks
if(vel.y != 0){
    if(vel.y < 0){
        // sprite is moving up
        setAnim(leftAnim);
    }else{
        // down
        setAnim(rightAnim);
    }
}

In addition to chrislo27’s suggestion, here’s another approach you could try. In short, if the entity is moving ‘more’ up or down than laterally (as determined by the absolute values of the velocity components) you’d use an up or down animation, else you’d use a lateral animation. Pseudocode (may be errors):

// If exact comparisons to zero aren't suitable for numerical reasons, or if you
// know a priori when the entity isn't moving, you can use some other method here
// for determining that the entity is stationary.
if (vel.x == 0 && vel.y == 0) {
    animation = "stationary";
} else if (abs(vel.x) > abs(vel.y)) {
    animation = (vel.x < 0) ? "left" : "right";
} else {
    // You might need to invert this, depending on your coordinate system.
    animation = (vel.y < 0) : "down" : "up";
}

If the entity is moving more or less diagonally, you might find that it switches back and forth between two animations frequently in a way that may not be desirable. This can be addressed by applying some hysteresis (this would make the code a little more complex though).