The Good Tech Companies - MVP Game Development With Flutter and Flame
Episode Date: June 6, 2024This story was originally published on HackerNoon at: https://hackernoon.com/mvp-game-development-with-flutter-and-flame. Follow along as we build an example game, demon...strating the power and efficiency of Flutter and Flame for creating engaging and functional games quickly. Check more stories related to gaming at: https://hackernoon.com/c/gaming. You can also check exclusive content about #game-development, #mvp-development, #mvp-examples, #flutter-app-development, #flame-tutorial, #app-development, #good-company, #flutter-and-flame, and more. This story was written by: @leobit. Learn more about this writer by checking @leobit's about page, and for more stories, please visit hackernoon.com. MVPs (minimum viable products) are becoming increasingly popular in the gaming industry. With MVP, you can build an app with basic functionality in short terms and on a limited budget. With the help of Flame, a robust and open-source game engine built on top of Flutter, you can craft stunning 2D games.
Transcript
Discussion (0)
This audio is presented by Hacker Noon, where anyone can learn anything about any technology.
MVP Game Development with Flutter and Flame, by Leobit.
Only two in five startups are profitable, according to a recent survey.
An MVP, Minimum Viable Product, significantly increases the chances of a startup's profitability
as it allows such businesses to collect early user feedback without spending the entire budget
on an app with complete functionality. With MVP, you can build an app with basic
functionality in short terms and on a limited budget, collect user feedback, and continue
expanding the solution with your development team according to this feedback. MVPs are becoming
increasingly popular in the gaming industry. Today, we will explore the ins and outs of rapid game MVP development with Flutter and Flame, a stellar combination for building
cross-platform minimum viable products. Why choose Flutter and Flame?
Flutter, a feature-packed and secure platform for cross-platform development,
has taken the mobile app world by storm, and its reach extends far beyond UI.
With the help of Flame, a robust and open-source
game engine built on top of Flutter, you can craft stunning 2D games that run smoothly on Android,
iOS, web, and desktop devices. Flutter has also become a popular solution for building game MVPs
due to ITS integral features that facilitate the fast development of solutions that present
the basic functionality across different devices. In particular, various Flutter benefits and integral functions allow
create a product with a shared codebase for different platforms, including Android and iOS,
which is much faster and cost-efficient than building separate native apps for different
platforms. There are also certain practices for building Flutter web apps with the same codebase.
Build flexible user interfaces with pre-built widgets and default animations,
which boosts development speed, one of the most critical factors in terms of MVP development.
Flutter offers hot reload functionality that allows developers to view the changes made in
app code that appear on the screen simultaneously, ensuring greater flexibility in MVP development.
This feature makes iteration and experimentation much simpler,
allowing developers to quickly try out different mechanics and visuals.
The development of a minimum viable product usually involves a minimum number of resources,
and Flutter fully satisfies this requirement, as Flutter's default integration with Firebase
significantly reduces the complexity of server-side programming. Flutter's default integration with Firebase significantly reduces the complexity
of server-side programming. Flutter doesn't consume many computing resources and facilitates
the simple setup of cross-platform applications. The app MVP based on the Flutter and Flame
combination is a reliable yet relatively simple-to-develop solution. It compiles directly
to native code, ensuring smooth gameplay and responsiveness.
You can develop your game MVP once and deploy it across different platforms,
saving time and resources. Flutter and Flame handle the platform differences under the hood.
In addition, both technologies boast vibrant communities with extensive documentation,
tutorials, and code examples. This means that you'll never bestuck for an answer or inspiration.
So what can Flame do? Flame provides a whole toolset for creating MVP game features in short terms and without overspending resources. This cross-platform modeling framework offers tools
for a wide array of different use cases sprites and animations. You can quickly create your sprites
or use them from various online libraries.
Flame also supports skeletal animation, which allows you to make more complex and realistic animations. Collision detection
It has a built-in collision detection system that makes it easy to create games with your
own physics. You can use collision detection to build platforms, walls, collectibles,
and other stuff with which your game characters can interact.
Physics simulations Flame also supports physics simulations,
which allow you to create more dynamic and engaging gameplay mechanics.
You can use physics simulations to create things like gravity, jumping, and bouncing.
Audio and Sound Effects You can use audio to create background music,
sound effects, like hit, jump, etc.
And even voice acting, state management. Flame provides a number of features for
managing the state of your game. This includes things like scorekeeping,
level management, and player data. Input devices.
Flame supports various input devices, such as touchscreens, keyboards, and game controllers.
This makes it a great option
for developing games for a variety of platforms. Parallax Scrolling
It supports parallax scrolling, which can add depth and immersion to your game world.
Parallax scrolling creates the illusion of depth by moving different layers of the background at
different speeds. Particle Systems
Flame also supports particle systems, which can be used to create a variety
of visual effects, such as explosions, smoke, and rain. Multiplayer Gameplay. This allows players
to compete or collaborate with each other in real-time. Most of the above-mentioned features
are essential for many games and should not be overlooked even at the MVP development stage.
What is really important is that Flame significantly
boosts the speed of developing the functionality mentioned above, allowing you to release such
features even in the earliest product versions. Let's try it. Now, instead of talking about Flame,
let's create an MVP containing basic features of our own game with this framework.
Before we start, you must have installed Flutter 3.13 or higher,
your favorite IDE and device for testing. A-N-I-D-E-A This game is inspired by Chrome Dino.
Ah, the famous Dino run. It's more than just a game from Chrome. It's a beloved Easter egg
hidden within the browser's offline mode. Our project will have the following gameplay.
You play as Jack, an adventurous adventurous guy who runs endlessly across a
dark forest controls are minimal tap the spacebar or click on the screen to jump the game starts
slow but gradually ramps up speed keeping you on your toes your goal is simple avoid the obstacles
and run as far as possible racking up points along the way and it will be called forest run
prepare yourself create
an empty flutter project like you do every time you start a new app. To start, we need to set
dependencies in pubspec. YAML for our project. When writing this post, the latest version of
flame is 1.14.0. Also, let's define all assets paths now, so there will be no need to return to
this file later. And put image
asinto directory assets, images. We need to put it here because flame will scan exactly this path
remember to put all images under assets, images, because flame will not parse other directories.
You'll need a lot of images for any game, but what if you are not good at design? Thankfully,
there are a lot of open sourcesource assets that you can use for
your projects. Assets for this game were taken from itch.io. We will use these resources for
our project Jack and Forest from Jungle Asset Pack by Jesse Munguia. Obstacles from Moon Graveyard
by Anochalisa. Text font from Font Pack by Xin Jin Meng. You can visit those links, or just download prepared assets, link to ASSETSARCHIVE, for this project and copy all content to your project.
Flame has a similar philosophy to Flutter. In Flutter, everything is a widget, in Flame,
everything is a component, even the whole game. Every component can override two methods,
onload and update. Onload, is called only once when component is mounted into the component tree and update
is fired on each frame.
Very similar to init state and build from stateful widget in Flutter.
Now, let's write some code.
Create a class that extends flame game and loads all or assets into the cache.
Next, use forest run game in main.
Dart.
Also, you can use methods from flame,
device to configure device orientation. And there is game widget, which serves as a bridge between widgets and components. At this point, we can already start the game, but there will be only
a black screen. So, we need to add our components. Dark forest we will divide the forest into two
components, background and foreground. Firstly, we will divide the forest into two components, background
and foreground.
Firstly, we'll handle the background.
Have you ever scrolled through a page that filled dynamic?
As if you were scrolling through more than one view at once?
That's a parallax effect, and it happens when the different elements of a page move
at different speeds, creating a 3D depth effect.
As you can think, we'll use a parallax for our background. Extend parallax
component and set up a stack of images using parallax image data. Also, there is base velocity
for the initial layer's speed and velocity multiplier delta, which stands for the relative
difference in speed between layers. And the last thing, configure the priority field, z-index,
to move it behind other components. The background
is done, now, it's time to add the foreground. Extend the position component so we can align
the ground to the bottom of the screen. We also need the has-game-reference mixin to access the
gamecache. To create ground, you just need to put the ground block image in line multiple times.
In Flame, image components are called sprites. A sprite
is a region of animage that can be rendered in the canvas. It might represent the entire image
orb one of the pieces a sprite sheet comprises. Also, remember that the x-axis is right-oriented
and the y-axis is bottom-oriented. The center of the axes is positioned in the left top corner of
the screen. And the last thing, add these components to our forest run game.
Now, try to launch the game. At this point we already have our forest.
A stranger in the forest forest looks good, but it's only a picture at this moment.
So, we are going to create Jack, who will run through this forest under the player's guidance.
Unlike trees and ground, the player needs animations to feel alive.
We used sprite for ground blocks, but we're going to use sprite animation for Jack.
How does this work? Well, all is easy, you just need to loop a sequence of sprites.
For example, our run animation has 8 sprites, which replace each other with a small timegap.
Jack can run, jump, and be idle. To represent his states,
we can add a player state enum. Then create a player that extends sprite animation group
component and pass player state as a generic argument. This component has an animations
field where animations for every player state error stored in a current field,
which represents the current state of the player, that needs to be animated.
The player states are ready. Now, we need to give the player a size and position on the screen.
I'm going to set his size to 69 by 102 pixels, but feel free to change it as you like.
For position, we must know the coordinates of the ground. By adding the hasGameReference mixin,
we can access the foreground field and get its coordinates.
Now, let's override the onGame
resize method, which is called every time the size of the application is changed, and set the
position of Jack there. As was done before, add the player to our game. If you start the game,
you see Jack is already in the forest, runJack, run. Our game has three states, intro, play,
and gameOver. So, we'll add the enum game state that
represents those ones. To make Jack run, we need speed and acceleration variables. Also,
we need to calculate the distance traveled, we'll use later. As was mentioned earlier,
the component has two main methods, onload and update. We already used the onload method a few
times. Now, let's talk about update. This
method has one parameter called dt. It represents the time thought has passed from the last time
the update was called. To calculate current speed and travel distance, we'll use the update
method on some basic kinematics formulas. Distance equals speed asterisk time. Speed equals
acceleration asterisk time. Actually, we will
use a trick to make development simpler. Jack will be steady, but the forest will move towards Jack.
So, we need our forest to apply game speed. For parallax background, we just need to pass game
speed. And it will automatically handle the rest. For the foreground, we need to shift every ground
block. Also, we need to check if the
first block in the queue has left the screen. If so, then remove it and put it at the end of the
queue. Everything is ready, but a trigger. We want to start running on click. Our targets are
both mobile and desktop, so we want to handle screen taps and keyboard events. Luckily,
Flame has a way to do it. Just add a mixin for your input type. For the keyboard,
it is keyboard events and tap callbacks for screen tapping. Those mixins give you the
possibility to override related methods and provide your logic. The game must start if
the user presses the spacebar or taps the screen. As a result, Jack can run now after clicking.
Oh no, a bush. Now, we want to have obstacles on the road.
In our case, they will be represented as poisonous bushes. Bush is not animated,
so we can use sprite component. Also, we need a game reference to access its speed.
And one more thing. We don't want to spawn bushes one by one, because this approach can
cause a situation when Jack simply can't pass a line of bushes with a jump.
Itis a random number from the range, which depends on the current game speed.
Who is planting bushes? Nature, of course. Let's create nature which will manage our
bush generation. Now, let's add nature to our forest foreground. Now, our forest has bushes.
But wait, Jack is just running through them. Why is this happening? It's because we haven't implemented hitting yet. Here, hitbox will help us. Hitbox is another component in Flame's zoo
of components. It encapsulates collision detection and gives you the possibility to handle it with
custom logic. Add one for Jack. Remember that the component's position will place its left-right
corner, not center. And with size, you handle the rest. And one for the bush.
Here, we will set the collision type to passive for Somi optimization. By default, the type is
active, which means that flame will check if this hitbox is collided with every other hitbox.
We have only a player and bushes. Since the player already has an active collision type
and bushes can't collide with each other, we can set the type to passive. It's cool, but I can't see if the position of the hitbox was
adjusted right. How can I test it? Well, you can set the debug mode field of player and bush to
true. It will allow you to see how your hitboxes are positioned. Purple defines the size of the
component and yellow indicates the hitbox. Now, we want to detect when there is a
collision between the player and the bush. For this, you need to add has collision detection
mixin to game and then collision callbacks for components, which need to handle collision.
For now, just pause the game when the collision is detected. Jump OR die if Jack wants to avoid
those bushes, he needs to jump. Let's teach him. For this feature,
we need the gravity constant and the initial vertical speed of Jack's jump.
Those values were chosen by eye, so feel free to adjust them. So, how does gravity work? Basically,
it's the same acceleration but oriented to the ground. So, we can use the same formulas for
vertical position and speed. So, our jump will have three steps.
1. Jump is triggered, and Jack's vertical speed changes from 0 to the initial value.
2. He is moving up and gravity gradually changes his speed. At one moment, Jack will stop moving
up and start moving down. 3. When Jack touches the ground,
we need to stop applying gravity to him and reset his state back to running. And now let's trigger jumping by click from forest run game, now, Jack can handle bushes.
Game OVER when the game is over, we want to show text on the screen.
Text in flame works differently from flutter. You have to create a font first. Under the hood,
ID's just a map, where char is a key and sprite is a value. Almost always,
the game's font is one image where all needed symbols are gathered. For this game, we need
only digits and caps letters. So, let's create our font. To do so, you have to pass source image
and glyphs. What is a glyph? Glyph is onion of information about char, its size, and position
in the source image.
Now, we can create the game over panel and use it in the game.
Now, we can show our panel, when Jack hits the bush.
Also let's modify the start method, so we can restart the game on click.
Also, we need to clear all the bushes from the forest.
And now, we need to update the collision callback in the player.
Now, you can see game over when Jack hits a bush.
And restart the game just by clicking again.
What about my score, and the final touch score calculation?
That's all folks, now, try it out, and try to beat my high score.
It's 2537 points, conclusions.
It was a lot, but we did it.
We have created a minimum viable product for Amabile game with physics, animations, score calculation, and much more. There is always
room for improvement, and, just like any other MVP, our product can be expected with new features,
mechanics, and game modes in the future. Also, there is a flame underscore audio package,
which you can use to add some background music,
sounds of jumping or hitting, etc.
As for now, our main objective was creating the basic product functionality in short terms
and with limited resource allocation.
The combination of Flutter and Flame proved to be a perfect fit for building a game MVP
that can be used to collect user feedback and keep upgrading the app in the future.
You can check the results of our
effort here. With its powerful features, ease of use, and thriving community, Flutter and Flame
are a compelling choice for aspiring game developers. Whether you're a seasoned pro or
just starting out, this combination offers the tools and potential to bring your game ideas to
life. So, grab your creativity, dive into the world of Flutter and Flame, and start building
the next mobile gaming sensation. We hope you found this article enjoyable and informative.
If you want more insights into software development or wish to discuss your own MVP project,
don't hesitate to explore Leobit or reach out to our technical team.
Thank you for listening to this Hackernoon story, read by Artificial Intelligence.
Visit hackernoon.com to read, write, learn and publish.
