create account

Setting Up a Widget-Tree Based Game with Flame and Flutter by japalekhin

View this thread on: hive.blogpeakd.comecency.com
· @japalekhin ·
$14.28
Setting Up a Widget-Tree Based Game with Flame and Flutter
One of the advantages of being a developer making your own games is that you have full control over the outcome. You control how a certain element functions or how an enemy character behaves. You can even control the (in-game) world and play around with the physical rules like gravity.

![](https://jap.alekhin.io/wp-content/uploads/2019/05/setup-widget-tree-flame-flutter-game.jpg)

With this kind of freedom though, most beginner developers find it hard to establish a structure when developing games along with the UI that goes with it.

## Standard structure

It seems that  **there’s no standard structure**  when it comes to game development with  [Flame](https://flame-engine.org/)  and  [Flutter](https://flutter.dev/).

The closest thing to it is simply feeding the main game class’  `.widget`property directly into  `runApp`. This setup is perfect for simple “tap-tap” games and the hyper-casual games like  [Langaw](https://github.com/japalekhin/langaw).

![](https://jap.alekhin.io/wp-content/uploads/2019/05/langaw.jpg)

Here’s an example  `./lib/main.js`  from  **Shadow Training**.

```
import 'package:flame/flame.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:shadow_training/shadow-training.dart';

void main() async {
  await Flame.util.fullScreen();
  await Flame.util.setOrientation(DeviceOrientation.portraitUp);

  await Flame.images.loadAll([
    'background.png',
    'boxer/dizzy.png',
    'boxer/idle.png',
    'boxer/punch-left.png',
    'boxer/punch-right.png',
    'boxer/punch-up.png',
  ]);

  ShadowTraining game = ShadowTraining();
  runApp(game.widget);

  TapGestureRecognizer tapper = TapGestureRecognizer();
  tapper.onTapDown = game.onTapDown;
  Flame.util.addGestureRecognizer(tapper);
}
```

If a game has been released for a while, chances are, there are going to be updates. These updates most probably present more features.

As the number of features grows, the game will be needing  **UI (user-interface) elements**.

UI elements help the players connect, understand, and interact with the game. Examples of UI elements include the score display, health bar, settings dialog box, exit button, play button.

In fact, even the simplest game (except maybe the  [Box Game](https://github.com/japalekhin/boxgame)) needs to have at least a play button or a score display.

This presents a problem with the “standard structure” as this would mean building the UI manually.  **The developer has to write everything**. Rendering managing states and screens,  **and animation**.

Again, as long the game is simple, this can be bearable to manually write.

The moment your game gets more complex than a game that can be described as dead simple, this becomes an easy source of a headache (_based on personal experience_).

## Taking advantage of the widget-tree

Let me introduce Flutter, no wait, we’re already developing in Flutter. When developing games using Flame, it’s easy to forget that we’re still developing apps using Flutter.

Flutter is actually a framework designed for business mobile app development. The type of apps that aren’t really that graphical, just some nice looking buttons, lists, labels, checkboxes, input controls. Maybe some basic animation and transition effects.

One of the things that are very easy to do in Flutter is UI. Exactly those elements we need for our game but too troublesome to write on our own.

**Let’s take advantage of this**

A Flame game is still rendered inside a widget (`Game`‘s  `.widget`property). If we put this game widget in a  `Stack`, we can easily build UI elements on top of it.

![](https://jap.alekhin.io/wp-content/uploads/2019/05/shadow-training-dialog.jpg)

Here’s the same code from  **Shadow Training**‘s  `./lib/main.dart`; but this time the game widget is enclosed in a  `MaterialApp`  widget (for possible navigation or routing between screens in the future).

```
import 'package:flame/flame.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:shadow_training/shadow-training-ui.dart';
import 'package:shadow_training/shadow-training.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() async {
  await Flame.util.fullScreen();
  await Flame.util.setOrientation(DeviceOrientation.portraitUp);

  await Flame.images.loadAll([
    'background.png',
    'boxer/dizzy.png',
    'boxer/idle.png',
    'boxer/punch-left.png',
    'boxer/punch-right.png',
    'boxer/punch-up.png',
    'markers.png',
    'perfect-time.png',
  ]);

  SharedPreferences storage = await SharedPreferences.getInstance();
  ShadowTrainingUI gameUI = ShadowTrainingUI();
  ShadowTraining game = ShadowTraining(gameUI.state);
  gameUI.state.storage = storage;
  gameUI.state.game = game;

  runApp(
    MaterialApp(
      title: 'Shadow Training',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Stack(
          fit: StackFit.expand,
          children: [
            Positioned.fill(
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTapDown: game.onTapDown,
                child: game.widget,
              ),
            ),
            Positioned.fill(
              child: gameUI,
            ),
          ],
        ),
      ),
      debugShowCheckedModeBanner: false,
    ),
  );
}
```

The main difference here is instead of passing  `game.widget`  directly to  `runApp`, we pass a  `MaterialApp`  first. This  `MaterialApp`  has a  `Scaffold`  as its  `home`  property (which is basically the child widget that will be shown when starting the app).

The  `Scaffold`  in turn, has a  `Stack`  as its body.

This  `Stack`  has two  `Positioned.fill`  widgets as its children. This is just to make sure that whatever gets assigned as their children will take up the entire screen. One has the  `game.widget`, the other has  `gameUI`  which is a  `ShadowTrainingUI`. It’s a class that extends a  `StatefulWidget`.

## Performance and drawbacks

As I was developing and testing the game, I checked and kept an eye on the performance every step of the way.

There’s actually a commented out code that prints out the real-time FPS of the game and this is what I’ve been monitoring. The whole time I was close to 60 FPS.

https://www.youtube.com/watch?v=e5kcADlFWt8

That being said, there were no noticeable performance issues seen during these tests. So having the widget inside a  `MaterialApp`  in the widget tree while running the game is fine within a Flame game.

Of course, this can’t all be good. There are some drawbacks like the need to expose the state in the widget so you can pass it on the to the game class. This is important in order to update the state of the UI from the game class.

A two-way communication system between the game and the UI class is important as you will probably need to write code on each side that changes things on the other side.

This can be a tricky situation but can be solved by writing the classes so they have instance variables that hold the reference to the other. Another way is to have a globally accessible singleton class that has references to both the main game class and the UI class.

## Conclusion

Based on my experience developing games using Flame and Flutter, I have found out that having a regular widget tree in a game is generally good practice.

Buttons, text, dialog boxes, text input, and other UI elements become significantly easier to create.

There’s no set-back on performance and the only thing tricky to set up is the communication between the game and the UI class.

If you have any questions, please leave a comment below or ask me by joining  [my Discord server](https://discord.gg/SNvNfas). Shadow Training is an open-source game that can be found  [on GitHub](https://github.com/japalekhin/shadow-training).
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 936 others
properties (23)
authorjapalekhin
permlinksetting-up-a-widget-tree-based-game-with-flame-and-flutter
categoryoriginalworks
json_metadata{"tags":["originalworks","development","games","flutter","android"],"image":["https://jap.alekhin.io/wp-content/uploads/2019/05/setup-widget-tree-flame-flutter-game.jpg","https://jap.alekhin.io/wp-content/uploads/2019/05/langaw.jpg","https://jap.alekhin.io/wp-content/uploads/2019/05/shadow-training-dialog.jpg","https://img.youtube.com/vi/e5kcADlFWt8/0.jpg"],"links":["https://flame-engine.org/","https://flutter.dev/","https://github.com/japalekhin/langaw","https://github.com/japalekhin/boxgame","https://www.youtube.com/watch?v=e5kcADlFWt8","https://discord.gg/SNvNfas","https://github.com/japalekhin/shadow-training"],"app":"steemit/0.1","format":"markdown"}
created2019-05-11 20:32:42
last_update2019-05-11 20:32:42
depth0
children5
last_payout2019-05-18 20:32:42
cashout_time1969-12-31 23:59:59
total_payout_value10.760 HBD
curator_payout_value3.519 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length7,959
author_reputation2,100,519,034,865
root_title"Setting Up a Widget-Tree Based Game with Flame and Flutter"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,682,089
net_rshares27,388,505,875,699
author_curate_reward""
vote details (1000)
@artturtle ·
message
### Thank you japalekhin! You've just received an upvote of 43% by artturtle!

<a href="https://steemit.com/art/@artopium/artturtle-will-upvote-each-and-every-one-of-your-art-music-posts">
<img src="https://www.rovingfestival.com/images/artturtlead.png"></a>

### [Learn how I will upvote each and every one of *your* posts](https://steemit.com/art/@artopium/artturtle-will-upvote-each-and-every-one-of-your-art-music-posts)
<br> 
Please come visit me to see my daily report detailing my current upvote power and how much I'm currently upvoting.
properties (22)
authorartturtle
permlinkre-setting-up-a-widget-tree-based-game-with-flame-and-flutter-20190511t210117
categoryoriginalworks
json_metadata""
created2019-05-11 21:01:18
last_update2019-05-11 21:01:18
depth1
children0
last_payout2019-05-18 21:01:18
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length546
author_reputation18,796,114,672,508
root_title"Setting Up a Widget-Tree Based Game with Flame and Flutter"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,683,111
net_rshares0
@curie ·
Congrats on a Curie vote!
Hi japalekhin,
<div class="pull-right">
https://steemitimages.com/DQmXgrYG8AKimJKRSu2urPB5SPcftN6GCGx2gVJJMwBkuTu/Curie%20Logo%2075px.png
</div>
This post  has been upvoted by the Curie community curation project and associated vote trail as exceptional content (human curated and reviewed).  Have a great day :) <br>
 
Visit <a href="http://curiesteem.com/">curiesteem.com</a> or join the <a href="https://discord.gg/G6RPUMu">Curie Discord community</a> to learn more.
properties (22)
authorcurie
permlinkre-setting-up-a-widget-tree-based-game-with-flame-and-flutter-20190512t020559
categoryoriginalworks
json_metadata""
created2019-05-12 02:06:00
last_update2019-05-12 02:06:00
depth1
children0
last_payout2019-05-19 02:06:00
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length469
author_reputation613,039,945,737,625
root_title"Setting Up a Widget-Tree Based Game with Flame and Flutter"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,694,911
net_rshares0
@edencourage ·
Some cool activity you have there. I am always wondering if I would have not pursued my profession, will I do the same? Having a passion for computers and the like and maybe has some background on programming, it would have been fun and exciting. Especially if your concept will become a trend, no one really knows. 

Anyway, good luck with your endeavor and I hope that many will follow you and your games. Just don't stop and I am sure that you can formulate something unique that will attract many players. Cheers.
👍  
properties (23)
authoredencourage
permlinkre-japalekhin-setting-up-a-widget-tree-based-game-with-flame-and-flutter-20190512t102743181z
categoryoriginalworks
json_metadata{"tags":["originalworks"],"app":"steemit/0.1"}
created2019-05-12 10:27:42
last_update2019-05-12 10:27:42
depth1
children1
last_payout2019-05-19 10:27:42
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length517
author_reputation3,413,597,020,958
root_title"Setting Up a Widget-Tree Based Game with Flame and Flutter"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,712,891
net_rshares833,379,574
author_curate_reward""
vote details (1)
@japalekhin ·
Hey, thanks for visiting and the encouragement.

It's not too late! You can do programming as a non-serious hobby. :D
properties (22)
authorjapalekhin
permlinkre-edencourage-re-japalekhin-setting-up-a-widget-tree-based-game-with-flame-and-flutter-20190512t145927684z
categoryoriginalworks
json_metadata{"tags":["originalworks"],"app":"steemit/0.1"}
created2019-05-12 14:59:27
last_update2019-05-12 14:59:27
depth2
children0
last_payout2019-05-19 14:59:27
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length117
author_reputation2,100,519,034,865
root_title"Setting Up a Widget-Tree Based Game with Flame and Flutter"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,725,006
net_rshares0
@minnowsupport ·
<p>Congratulations!  This post has been upvoted from the communal account, @minnowsupport, by JapAlekhin from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows.  Please find us at the <a href="https://discord.gg/HYj4yvw"> Peace, Abundance, and Liberty Network (PALnet) Discord Channel</a>.  It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.</p> <p>If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: <a href="https://v2.steemconnect.com/sign/delegateVestingShares?delegator=&amp;delegatee=minnowsupport&amp;vesting_shares=102530.639667%20VESTS">50SP</a>, <a href="https://v2.steemconnect.com/sign/delegateVestingShares?delegator=&amp;delegatee=minnowsupport&amp;vesting_shares=205303.639667%20VESTS">100SP</a>, <a href="https://v2.steemconnect.com/sign/delegateVestingShares?delegator=&amp;delegatee=minnowsupport&amp;vesting_shares=514303.639667%20VESTS">250SP</a>, <a href="https://v2.steemconnect.com/sign/delegateVestingShares?delegator=&amp;delegatee=minnowsupport&amp;vesting_shares=1025303.639667%20VESTS">500SP</a>, <a href="https://v2.steemconnect.com/sign/delegateVestingShares?delegator=&amp;delegatee=minnowsupport&amp;vesting_shares=2053030.639667%20VESTS">1000SP</a>, <a href="https://v2.steemconnect.com/sign/delegateVestingShares?delegator=&amp;delegatee=minnowsupport&amp;vesting_shares=10253030.639667%20VESTS">5000SP</a>. <br><strong>Be sure to leave at least 50SP undelegated on your account.</strong></p>
properties (22)
authorminnowsupport
permlinkre-setting-up-a-widget-tree-based-game-with-flame-and-flutter-20190511t210720z
categoryoriginalworks
json_metadata"{"app": "beem/0.20.20"}"
created2019-05-11 21:07:21
last_update2019-05-11 21:07:21
depth1
children0
last_payout2019-05-18 21:07:21
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length1,693
author_reputation148,902,805,319,183
root_title"Setting Up a Widget-Tree Based Game with Flame and Flutter"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id84,683,360
net_rshares0