Sprite Animation
Introduction
Sprite animation is an essential aspect of creating captivating and visually appealing games and applications. With the advent of powerful game development frameworks like Flutter Flame Engine, animating sprites has become more accessible than ever for developers. In this blog post, we'll explore the basics of sprite animation using Flutter Flame Engine and provide practical examples to help you get started on your animation journey.
Understanding Sprite Animation
Before diving into the implementation, let's briefly understand what sprite animation is. A sprite is a 2D image or graphical object that can move around the screen. Sprite animation is the process of displaying a series of images (frames) in quick succession, creating the illusion of movement.
In flame there is a special component handling Sprites and it is called - SpriteAnimationComponent 🎉
So when implementing Sprite Animation in your Flame game you basically have to extend the SpriteAnimationComponent and implement the basic functions and you are already set:
class Player extends SpriteAnimationComponent with CollisionCallbacks {
late SpriteAnimation _moveAnimation;
@override
Future<void> onLoad() async {
await super.onLoad();
position = gameRef.size / 2;
priority = 1;
// Load Animations
_loadAnimations();
// Set animation
animation = _moveAnimation;
add(CircleHitbox(position: Vector2(0, 0), radius: 32));
}
@override
void update(double dt) {
super.update(dt);
// Basic movement
position.add(Vector2(offset.dx, offset.dy) * dt * _maxSpeed);
// Player rotation on the field
angle = offset.direction + (-pi / 2);
}
void _loadAnimations() {
final spriteSheet = SpriteSheet(
image: gameRef.images.fromCache(
'player/move_sprite.png'),
srcSize: Vector2(420, 524));
_moveAnimation = spriteSheet.createAnimation(
row: 0, stepTime: 0.1, to: 8, loop: true);
}
// As we implement CollisionCallbacks we need to handle collisions here
@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
if (other is Enemy) {
if (!isAttacking) {
_playerModel.health -= other.attackStrength;
isAttacking = true;
attackCountdown.start();
if (_playerModel.health <= 0) {
die();
}
}
}
super.onCollision(intersectionPoints, other);
}
}
As you can see the SpriteAnimationComponent is pretty similar to the already familiar flame component. Just implement the onLoad
and update
methods and you are almost done.
The only thing left to get some animation is the _loadAnimations
method triggered from the onLoad
method:
Here the real magic happens: A SpriteSheet is loaded from the image cache (which itself is loaded at game startup). A SpriteSheet typically consists of several images in a row which are animated quickly to create the illusion of movement:
And that is exactly what we implement in _moveAnimation - we create an animation from the SpriteSheet with a short stepTime.
So let's break it down:
final spriteSheet = SpriteSheet(
image: gameRef.images.fromCache(
'player/move_sprite.png'),
srcSize: Vector2(420, 524));
Here we load the move_sprite.png
asset from the game cache and set it's size to 420px x 524px.
_moveAnimation = spriteSheet.createAnimation(
row: 0, stepTime: 0.1, to: 8, loop: true);
Now is time to make some (very) simple math: the sprite contains 8 images to animate the movement of the character. So here we create the animation with a stepTime 0.1
until we reach sprite 8
. Finally we set the loop-flag to true to animate the sprite in a loop.
That's it! Our character now is moving and we can implement all the cool stuff to make playing more fun 🎉.
Conclusion
Flame provides a very handy class SpriteAnimationComponent to animate sprites. As this class directly inherits from component, it is perfectly embedded into the engine and makes sprite animation in flame a breeze.