Welcome to Season Two of Learning to Fly.
I'm Eric, and I'm an engineer on the Flutter team.
I'm Khanh. I'm also a Developer Relations Engineer on the Flutter team.
If you were around to catch the first season of Learning to Fly,
welcome back.
If you're new, thanks for joining us.
Learning to Fly is a vlog series where we'll document our journey
learning to build something new in Flutter.
In Season One, I built MyDash,
a fan club app for Dash's biggest fans.
It was a fun project as I was ramping up with Flutter,
but for the second season,
we're going to turn up the heat just a little bit.
[chuckles] Get it?
Heat, and we're using Flame.
I tried.
♪ [music] ♪
This season, we are going to be focusing
on building a game called Doodle Dash,
a game in which the player controls Dash
and tries to get Dash jump as high as possible
by jumping on little platforms.
It's like an infinite runner, but vertical.
I come from an app development background,
and I've been using Flutter professionally since, I think, 2017,
but I've never used it to build a game,
so except for Khanh's three-day sprint
to build Flappy Dash in the last season,
neither of us have any experience building games.
We both wanted to take on this project for that reason.
We both find the idea of being a game developer pretty intimidating.
First off, it seems that there are a ton of moving parts in games,
and you have to manage all of them at all times.
Second,
I don't have much of a math or physics background,
and as far as I know,
math and physics are both big parts of making games.
But I do love playing games,
so there's no time like the present to give it a try.
Yeah, I completely agree.
I had some math and physics classes in college.
I actually really enjoyed Physics class,
but even then, taking some physics theory
and applying it in code for a game
is, well, a totally different ball game.
I promise, that's the last dad joke I have here.
The goal for these first three episodes of this season
is to have the core game finished,
fun, and polished.
For those of you at home,
we'll also have a codelab for you to follow along
and build Doodle Dash with us,
so stay tuned until the very end.
From there, we'll be looking to y'all to tell us
what features you want added to the game.
We'll turn those ideas into code
and cover it in the upcoming episodes
after we've built out the core functionality of the game.
Now, without further ado, let's jump into the code.
Eric, you want to kick us off?
Yeah, sure.
For this first episode, our goal
was to have the core functionality of the game complete.
This means that we wanted to have Dash on the screen
and be able to move her lefts and rights.
We're building this for web first,
so we're starting with keyboard inputs to control Dash.
Dash also needs to move in the vertical space,
which meant we wanted platforms for her to jump off of
and move up,
but we'd also want some gravity to be acting on Dash
and pulling her down.
Of course,
the point of this game is to jump higher forever,
so platforms spawn infinitely.
The game also detects when Dash misses a platform
and falls off the screen,
causing the player to lose.
Finally, we had to make sure the player can't lose
by moving too far horizontally,
so if Dash jumps out of the view to the right,
she'll come back in on the left and vice versa.
Now that we know our requirements, let's talk about the implementation.
We're building this game using Flame.
Flame is a 2D game engine built on top of Flutter.
Out of the box, it helps
with implementing core pieces of building a game,
like the game loop,
and it abstracts away
some of the most intimidating parts of building a game,
like collision detection.
Plus, the neat thing about Flame is that it's easily accessible,
just like any other package on
To get started, all we had to do was run
and we were ready to get coding.
The goal with our project architecture
was to keep things as simple as possible
because we don't know what we're doing.
In the
and a
In that
there are three files at the top level
and one more subdirectory called
where we have files for sprites and a barrel file.
I can imagine a future
in which we'd want more separation of files by concern,
but for now, we kept it simple.
[Khanh] The base class for most of Flame is the component class.
Similar to widgets in Flutter,
you could say that in Flame, everything is a component.
Components are the building blocks for every Flame game.
We started by making a class called
that extends
This class is the entry point for most of the rest of the code.
It's the central nervous system of the game
and generally is used to manage the rest of the components.
From there, we added a background.
The background is added using another component
called the
This is a component that tells Flame about an image asset,
and then the
can create an instance of the
and register it with Flame.
Registering is done here in the
which you'll override for almost every Flame component.
It's done by calling the built-in
We learned pretty quickly
that
we'd be using a lot in Flame.
Yeah, we repeated a very similar process
to add Dash to the screen.
The difference here is that we need a way to handle two Dash assets:
one from when she's facing left and the one from when she's facing right.
We used Flame's built-in class called
to solve this.
You can give the
all of the assets that you need in the
and the component gives you the ability to switch between the sprites.
Once we added that component, the game looks like this.
Great! We managed to get two of the components
that we needed on the screen.
What do we do next?
After we got Dash moving,
the next step was getting platforms on the screen
for Dash to interact with.
The platform component itself
is a sprite component with a hit box.
A hit box is an invisible shape
that surrounds a sprite
that allows the sprite to detect
when it's colliding with other objects
that also have hit boxes.
I really didn't know how to approach the logic
for managing the platforms,
so I actually went to the repo for Flappy Dash
from Season One
and reused a lot of your
You want to give us a quick TL;DR
on the
Sure. The
was previously used to spawn the pieces of luggage
at random coordinates
so that Dash would have to dodge it in Flappy Dash,
but now for Doodle Dash,
it's called
The logic
from
has remained mostly the same,
but we did add some additional logic
to continually spawn more platforms
as Dash jumps off the platforms,
and she's moving upward.
The
and adds those platforms to the screen
at semi-random coordinates.
Once the platforms were rendering,
we needed to work on
what was one of the more intimidating parts in my mind:
collision detection,
but it turns out,
implementing collision detection was easier than expected
because Flame does a lot of the work for you.
First, we added a hit box to Dash
so that both Dash and the platforms had hit boxes.
Then I used a mix-in from Flame on the Dash component
that provides the component
with an
which is called by Flame when two objects collide.
When Flame calls
it passes a reference
to the other objects being collided with
into the callback,
which, in this case, is a platform.
Because the
is called on the Dash object,
We were able to determine whether Dash was moving up or down
when the collision happened,
so then we can say
if it was moving down when it collided with the platform,
jump up.
If it was moving up,
it should just move to the platform without triggering a jump.
This is a great example of the value that Flame provides:
the calculations needed to determine
if a collision was happening.
It seems like it would be quite difficult to do on your own.
The other interesting part about Dash
is that we needed her to be acted on by gravity.
There had to constantly be a force that was pulling her down.
As a result, we stuffed the logic for gravity
in Dash's
Whatever her velocity was,
we subtract a constant value from her y-axis speed
to pull her down, like gravity would.
You've seen
update
because it's called on every tick of the game loop,
which is once every frame.
It allows you to incrementally move components on the screen,
so instead of looking janky,
the movement looks smooth and natural--
especially important for sprites.
It's a good lesson that I learned
from my attempt at building Flappy Dash.
[Eric] From there, we deployed the game to Firebase Hosting
to get it live,
and you can play it right now
at the link in the description.
But keep in mind,
it's deployed as is
at the end of this episode,
so it's a little boring.
After each episode, though, we'll update the game
to match the state at the end of that episode.
We have to keep y'all on your toes!
Eric, this was your first time working with Flame.
What do you think was interesting and challenging?
Well, the most challenging part for me
was getting the camera right.
The camera is supposed to follow Dash as she moves up,
but stop when she's moving down,
and the game ends
when Dash misses a platform and falls off the screen.
If the camera was always following Dash,
the game would never end
because there would be no falling off the bottom of the screen.
I did eventually find a way to solve this,
which was basically to reset the bottom bounds of the camera
within the game component's
This might be the best way to do this,
but it does feel weird
to be doing this sort of computation on every frame tick.
But it is funny now
because the code is relatively simple,
but I was really banging my head against the wall for a while
trying to get this part right.
What about you?
Any struggles in particular?
Yeah, gravity.
Definitely gravity.
I know from Physics class that gravity is 9.8 m/s^2--
thanks, Mr. [Aman] and Mr. A--
but what am I supposed to do with that in Flame?
How does it translate?
There was a lot of trial and error there for me.
But yeah, so far, how are you feeling
about Flame in making games
now that you've been working with it for a bit?
Well, I still feel wildly unqualified for game development,
and I am feeling even more like
real games would be extremely difficult to program.
But I don't feel as intimidated by it.
I feel like I don't know anything,
but I could learn whatever I needed
given enough time, of course.
Yeah, I totally feel the same way there as well.
I think the great thing about using a game engine
is that it makes things a little bit easier to pick up.
We don't have to implement
the most complex parts from scratch,
which is absolutely great.
Yes, absolutely great.
But anyways, now that we've built this portion, what could we do better?
What'd we miss?
[Khanh] Well, the first thing I noticed when testing out our game
was that it's not responsive.
I resized my window,
and Dash does not jump nearly far enough
to make it to the other side of the screen,
so that could use some work.
Yes, that's on me. I completely missed that.
It's a major oversight since we're targeting the web
where the screen could be so many different sizes.
I'd like to also tweak some of the details,
like the number of platforms that rendered,
Dash's jump speed, gravity speed,
and stuff like that
because right now, it technically works,
but it's not challenging,
and it is boring.
Well, that sounds like something that we'll definitely need to tackle
in the next few episodes,
but for now, I think that's a wrap
on the first episode of Learning to Fly, Season Two.
Yeah, and in the next episode,
we'll be adding in more game functionality
that should exist in every game ever,
like a start screen,
the ability to pause the game and keeping score.
We'll also be adding some elements that make the game more interesting,
like different levels of difficulty
and different platforms.
This is where you all come in.
While the first three episodes of the season
are dedicated to the core functionalities of the game,
the rest of the season is pretty open-ended,
so let us know if there's anything that you'd like to see,
like what characters would you like to see
or any game mechanics
that you'd like to see in the game in the future.
If you're getting antsy
waiting for this game to come together,
just letting you know
that you can build the entire completed game that we're building
with the Build A Game with Flutter and Flame codelab
that's linked in the show notes right down below.
With that said, thanks for joining us on this episode of Learning to Fly,
and, well, we'll see you tomorrow.
Adiós
♪ [music] ♪