Advanced Animation with Flutter Flame Engine — Ep.1 Sprite Sheet
--
In my experience, good apps are the apps that users enjoy using. It might solve their pains, make their lives easier, or it’s fun to use. In this article, I will focus on how to make your app fun to use.
“Fun”, in my terminology, is something remarkable. It’s something that makes people smile and say ‘wow!’. It can leave quite an impression on the user and keep them coming back. Considering all these requirements, the first thing that comes to my mind is animation. Now the question becomes ‘which app provides the most fun to the user?’ The answer is pretty obvious, isn’t it? It’s games! For this reason, I am considering adding some sort of mini-games to an app. I did research on how to put games inside Flutter and found a famous lib for Flutter called “Flame Engine.”
Here’s the link to the lib:
The cool thing about flame animation is it’s already the game engine. The things you need to create a game are already here:
- Advanced animation with the sprite sheet
- Physics
- Collision detection
- Particles
- Sound*
*I’ll be skipping this section because personally, I always get annoyed when an app has an unexpected sound. Sure, if it’s an app that people already expect a sound like music, video or gaming apps, that’s totally fine. Daily-use apps, meanwhile… just imagine you’re use a calculator app and constantly hear a “ding” sound every time you press a number 😅
I will divide this series into 4 articles: sprite sheet, physics, collision detection, and particles. This article will focus on the Sprite sheet, so let’s begin.
Advanced Animation with the Sprite Sheet
A sprite sheet is an image that contains a series of character actions. For example, the picture below is the sprite sheet of the character walking. When we animate, we replace the series of images very quickly to make it look like the character is moving.
Here’s another basic animation, an older one like in 2D Disney cartoons. Still the same concept and idea: quickly change the image to the next one and loop it for animation.
In this article, I got the inspiration from “Apollo for Reddit”, where they created a cat and dog animation at the top of the dynamic island on iOS, so I want to make it work for Flutter as well. In this article, I will use Flutter Flame with a sprite sheet and put it inside our app to make our animation more interesting.
Let’s get started
First, let’s add flame to pubspec.
dependencies:
flame: ^1.4.0
To use the Flame widget along with the Flutter widget, you have to import the Flutter Flame
import 'package:flame/game.dart';
and add GameWidget
in the normal widget like this:
GameWidget(game: SpriteSheetWidget());
To create an animation on top of the dynamic island, since the height above the capsule is 12px, I use this code to create the animation.
SizedBox(
width: 12,
height: 12,
child: Align(
alignment: Alignment.topCenter,
child: GameWidget(game: SpriteSheetWidget())))
Now I can use GameWidget, which is the Flutter Flame Engine, inside the normal widget.
Now for SpriteSheetWidget…
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flame/sprite.dart';
import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flutter/animation.dart';
class SpriteSheetWidget extends FlameGame with TapDetector {
@override
void onTapDown(TapDownInfo info) {
print(info.eventPosition.game);
}
@override
Future<void> onLoad() async {
final spriteSheet = SpriteSheet(
image: await images.load('cat_sprite_long.png'),
srcSize: Vector2(50.0, 50.0),
);
final spriteSize = Vector2(50.0, 50.0);
final animation =
spriteSheet.createAnimation(row: 0, stepTime: 0.1, to: 60);
final component1 = SpriteAnimationComponent(
animation: animation,
scale: Vector2(0.4, 0.4),
position: Vector2(160, -5),
size: spriteSize,
);
add(
component1
..add(
MoveEffect.to(
Vector2(250, -5),
EffectController(
duration: 10,
reverseDuration: 10,
infinite: true,
curve: Curves.linear,
),
),
),
);
}
}
My SpriteSheetWidget
will extend FlameGame and conform with TapDetector (if you want it to be tappable).
When you conform with FlameGame
, it will require OnLoad to load an asset.
I downloaded this cat_sprite_long.png from the internet and make it into a single line of an image like so.
I resize it to 50 by 50, then create animation for every 0.1 seconds up to 60 frames.
And here’s our final animation! As you can see, the area is too small to put a clear character and animations 😅 It might be nice for a gimmick, but I don’t think we can do anything significant over there.
For this use case, we can also do complex animation like cartoon characters or other cute animals with the sprite kit. Currently, I’m trying Rive animation in order to create something interactive with user inputs. However, the sprite kit is able to create a more fluid and more realistic animation, which also depends on the designer’s skill set. They can even create 3D sprite sheets.
The idea is just not a cartoonish animation. You can create a sprite sheet with a particle rain effect. As the raindrop hit your widget, the splash sprite sheet will play to make it look like it’s really hitting the surface and splashing.
Below is my GitHub repo. Currently, there’s only the sprite sheet, but I will keep updating the animation as we continue.
For the next article, I will discuss the physics in the app by using Flutter Flame Physics and will go step-by-step on how to create a raining effect like in the iOS Weather app. 🆒 🆒 🆒
Want to read more stories like this? Or catch up with the latest trends in the technology world? Be sure to check out our website for more at www.kbtg.tech