Building Games in Flutter with Flame: Getting Started
Learn how to build a beautiful game in Flutter with Flame. In this tutorial, you’ll build a virtual world with a movable and animated character. By Vincenzo Guzzi.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Building Games in Flutter with Flame: Getting Started
30 mins
- Getting Started
- The Flame Game Engine
- Setting up Your Flame Game Loop
- Creating Your Player
- Adding Movement to Your Player
- Executing on Player Movement
- Animating Your Player
- What Is a Sprite Sheet?
- Adding Sprite Sheet Animations to Your Player
- Adding a World
- Adding World Collision to Your Game
- Creating Tile Maps
- Creating World Collision in RayWorld
- Bonus Section: Keyboard Input
- Where to Go From Here?
Flutter is changing the world by bringing fast, natively compiled software to the masses. This allows indie developers to release applications for every platform in the same time it would usually have taken a software company. It’s only natural that game developers want to take advantage of that, too.
Traditionally, a mobile game developer would need to choose between native performance but slow development time or building with a multi-platform tool like Unity but risk slow loading times and large app sizes.
If only there were a way to develop beautiful native games without all the bloat. That’s where Flame comes in.
Today, you’ll build a virtual world using Flutter and the Flame engine. You’ll learn how to:
- Use Flame version 1.0 to make a game for the web, Android and iOS.
- Use a game loop.
- Create a movable player character.
- Animate your character with sprite sheets.
- Add box collision by reading from a tile map.
Getting Started
You’ll develop a game called RayWorld, a 2-D orthographic game in the style of old-school Pokemon.
Using an older game engine written in something like C++, a tutorial like this would span over three or four series. But with the power of Flutter and the Flame engine combined, you’ll create all this in just one.
You’ll need the starter project to complete this tutorial. Download it by clicking the Download Materials button at the top or bottom of the tutorial.
Build and run your project in your preferred IDE. This tutorial will use Visual Studio Code.
You’ll see a blank screen with a joypad in the bottom right corner:
What you see here is rendered purely with Flutter; you’ll need Flame to build the rest of your components.
The Flame Game Engine
Flame — a lightweight game engine built on top of Flutter — gives game developers a set of tools such as a game loop, collision detection and sprite animations to create 2-D games.
The Flame team has worked on releasing v1.0.0 for over a year and is on the brink of an official release. v1.0.0 has changed a lot of the core fundamentals of Flame because the team took this opportunity to apply what they’ve learned over the years and rewrite the engine.
This tutorial will use Flame 1.0.0 release candidate 15.
The Flame engine is modular, allowing users to pick and choose which API’s they would like to use, such as:
- Flame – The core package, which offers the game loop, basic collision detection, Sprites and components.
- Forge2D – A physics engine with advanced collision detection, ported from Box2D to work with Flame.
- Tiled – A module for easily working with tile maps in Flame.
- Audio – A module that adds audio capabilities into your Flame game.
Flame harnesses the power of Flutter and provides a lightweight approach to developing 2-D games for all platforms.
Setting up Your Flame Game Loop
The first component you’ll set up in RayWorld is your Flame game loop. This will be the heart of your game. You’ll create and manage all your other components from here.
Open your lib folder and create a new file called ray_world_game.dart, then add a new class called RayWorldGame
, which extends from the Flame widget FlameGame
:
import 'package:flame/game.dart';
class RayWorldGame extends FlameGame {
@override
Future<void> onLoad() async {
// empty
}
}
Open main_game_page.dart and create an instance of your new class at the top of MainGameState
:
RayWorldGame game = RayWorldGame();
Now, add a GameWidget
to MainGameState
as the first widget in the Stack
, replacing // TODO 1
with:
GameWidget(game: game),
Add these two imports to the top of main_game_page.dart so you can use your new logic:
import 'package:flame/game.dart';
import 'ray_world_game.dart';
Right now, your game will do nothing. It needs some components to render. Time to add a playable character!
Creating Your Player
Add a folder in lib called components. This folder will store all your Flame components, starting with your player.
Create a file in components called player.dart. In this class, set up your Player
class:
import 'package:flame/components.dart';
class Player extends SpriteComponent with HasGameRef {
Player()
: super(
size: Vector2.all(50.0),
);
@override
Future<void> onLoad() async {
super.onLoad();
// TODO 1
}
}
Your Player
extends a Flame component called SpriteComponent
. You’ll use this to render a static image in your game. You’re setting the size of the player to be 50.
All components in the Flame engine have some core functionality, such as loading and rendering within the game loop they’re attached to. For now, you’ll use only onLoad
.
Replace // TODO 1
in Player
with logic to load your player image and set the player’s initial position.
sprite = await gameRef.loadSprite('player.png');
position = gameRef.size / 2;
All components have access to the game loop if you add the mixin HasGameRef
to your component class definition. Here, you use that game reference to load a sprite into your game with the image of player.png that’s located in your Flutter assets folder. You also set the players position to be in the middle of the game.
Go back to your ray_world_game.dart file and add your new Player
component as an import at the top of the file:
import 'components/player.dart';
In the top of RayWorldGame
, create your Player
:
final Player _player = Player();
In the game onLoad
method, replace // empty
with code to add your player into the game:
add(_player);
add
is a super important method when building games with the Flame engine. It allows you to register any component with the core game loop and ultimately render them on screen. You can use it to add players, enemies, and lots of other things as well.
Build and run, and you’ll see a little dude standing in the center of your game.
Pretty exciting!
Now, it’s time to get your player moving.