SpriteAnimationTicker in Flame to control an animation in Flutter

- Andrés Cruz

En español
SpriteAnimationTicker in Flame to control an animation in Flutter

An AnimationTicker is a technique used in various animation libraries and allow to control an animation; in the case of Flame, they also allow you to listen to the states of the animation; for example, when the animation is complete:

animationTicker.onComplete = () {
    ***
  }
};

When a frame of the animation is executed:

animationTicker.onFrame = (index) {
  ***
  }
};

This is all done by Flame's SpriteAnimationTicker class; for the game we are implementing, it is necessary to know when the "dying" animation ends to restart the game; for this, we can use any of the listeners shown above.

First, we need to initialize the ticker:

lib/components/player_component.dart

class PlayerComponent extends Character {
  ***
  late SpriteAnimationTicker deadAnimationTicker;

  @override
  void onLoad() async {
    ***
    deadAnimationTicker = deadAnimation.createTicker();
  }

  @override
  void update(double dt) {
    ***
    deadAnimationTicker.update(dt);
    super.update(dt);
  }
}

With the createTicker() function we create a ticker (SpriteAnimationTicker) on the animation that we are going to control; in the case of the game that we are implementing, we are interested in detecting when the dying animation ends, which will be executed only when the player runs out of lives and when the animation ends, the level restarts. The reason that the deadAnimationTicker property is initialized in the onLoad() and not when the deadAnimation animation is used (when the player runs out of lives) is that it is necessary to update the ticker in the upload() function according to the ticker life cycle:

deadAnimationTicker.update(dt)

With the ticket, a listener is created to detect when the animation has finished running; to do this, we can execute the onComplete() listener:

deadAnimationTicker.onComplete = () {
  // TODO
};

Or the onFrame() one, which is executed for each Frame, but, asking if the current frame is the last one:

deadAnimationTicker.onFrame = (index) {
  if (deadAnimationTicker.isLastFrame) {
    // TODO
  }
};

Finally, the complete code looks like:

lib/components/player_component.dart

class PlayerComponent extends Character {
  void reset({bool dead = false}) async {
    game.overlays.remove('Statistics');
    game.overlays.add('Statistics');
    velocity = Vector2.all(0);
    game.paused = false;
    blockPlayer = true;
    inviciblePlayer = true;
    movementType = MovementType.idle;
    if (dead) {
      animation = deadAnimation;

      deadAnimationTicker = deadAnimation.createTicker();
      deadAnimationTicker.onFrame = (index) {
        // print("-----" + index.toString());
        if (deadAnimationTicker.isLastFrame) {
          animation = idleAnimation;
          position =
              Vector2(spriteSheetWidth / 4, mapSize.y - spriteSheetHeight);
        }
      };

      deadAnimationTicker.onComplete = () {
        if (animation == deadAnimation) {
          animation = idleAnimation;
          position =
              Vector2(spriteSheetWidth / 4, mapSize.y - spriteSheetHeight);
        }
      };
    } else {
      animation = idleAnimation;
      position = Vector2(spriteSheetWidth / 4, mapSize.y - spriteSheetHeight);
      size = Vector2(spriteSheetWidth / 4, spriteSheetHeight / 4);
    }
    game.colisionMeteors = 0;
    game.addConsumibles();

    //position = Vector2(spriteSheetWidth / 4, 0);
  }
}
Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.