Hey bru. Last week I launched my first app Icing Addict - one of 12 startup projects I’m building this year. This series will be a deep dive into how I built it.
In this first post will be talking about Flutter itself. What is it you ask? I’ll tell you all about it so you can start using it today!
To see my game or a summary of its features check out these links.
Want to build a cross platform mobile application? Flutter can do that. It sports some cool features like:
👌 Overall I’ve been very impressed. I was initially concerned that it wouldn’t be suitable for games, however that notion was quickly proven wrong. It’s handled everything I’ve thrown at it so far.
Critical features like on-the-fly processing as the user draws, intimate manipulation of SVGs, and overall rendering speed were easily achieved. The comprehensive widget library and animation support made Flutter even sweeter to use.
Want to get started? Check out these links:
Tooling is fantastic too. There are a few options but I recommend developing with VSCode. As a development experience this is what you can expect:
Consider using these VSCode extensions:
Some Flutter packages to consider using would be:
Overall Google have done a fantastic job to making it easy to developer for the platform. You really can beautiful apps quickly and easily.
The Flutter extension come full of nice little touches.
Ctrl .
on a nested widget for some useful operations. Note that 'Remove' removes the outer widget but keeps in children. Much faster than doing it manually.
Ok so what’s it like to actually use? Well Dart is the language of choice here. It feels somewhat like coding in Typescript, React, with a sprinkle of C# perhaps. I think it combines the better elements of all of them.
If you’re comfortable with async usage, stateful components, and inline functions then you’ll feel right at home. Your knowledge of OO programming concepts will come in handy too.
I highly recommend you simply run through the Dart language features to see how common thing are done. One thing to note is that constructors are quite unique in Dart and need to be learned.
And I mean everything. Things like padding, aligning widgets, and even animation are done by wrapping widgets in other widgets.
// An example of how padding is applied
Padding(
padding: EdgeInsets.only(top: 20),
child: MyWidget(...),
),
Useful operators like null conditional ?.
and null coalescing ??
ship out of the box.
Inline functions work similar to Javascript.
// Assign a variable with an arrow function
setImage((Image image) => _image = image);
// Assign a variable with an inline function
setImage((Image image) {
_image = image;
});
Dart also has cool operators like ..
which allows you to chain object references everywhere.
// Creates an object and assigns variables without
// traditional().method().chaining()
var paint = Paint()
..strokeCap = StrokeCap.round
..strokeJoin = StrokeJoin.round;
Or use use the ~/
to divide and return an integer.
var var1 = 100 / 33; // 3.0303....
var var2 = 100 ~/ 33; // 3 (int)
Use set and get variables within a class.
bool _isValid;
bool get isValid => _isValid;
bool set isValid(bool isValid) {
_isValid = isValid;
updateStuff();
}
A mixin
can be used to encapsulate logic that is reusable. I use these all the time for animations, timer logic etc. which come in handy all over the place. A simple mixin to handle timers safely and easily might look like:
/// A mixin to safely handle timers in stateful widgets
mixin EasyTimer<T extends StatefulWidget> on State<T> {
// Internal timers hidden from parent class
List<Timer> _timers = [];
// A public accessor used by parent widgets
setTimer(Timer timer) => _timers.add(timer);
// Make use of parent methods and variables
@override
void dispose() {
super.dispose();
// Safely stop timers when the widget closes
_timers.forEach((t) => t.cancel());
}
}
// Use the mixin like this
class _MyWidgetState extends State<MyWidget> with EasyTimer {
...
setTimer(...);
...
}
Now all of your timers are managed safely in the background! Mixins are great for these types of patterns.
Use extension methods to extend shit.
// Add a method directly to all strings
extension NumberParsing on String {
int parseInt() => int.parse(this);
}
// Use it like this
var myNum = "12345".parseInt();
Throw control logic directly in lists as you make them.
var widgets = [
MyWidget(),
...otherWidgets, // spread em
if (something) MyWidget(), // if em
for (var item in items) MyWidget(), // for em
];
Most math operations are methods on the numbers themselves.
100.floor();
100.abs();
100.toInt();
100.clamp(0, 10);
Typing is generally good but watch out when using number types!
// This compiles but throws an error
num myInt = 1; // Uses a generic num type
double myDouble = myInt; // Throws type error
// You have to force the type instead
double myDouble = myInt.toDouble(); // 👍
Hopefully you can see there are some really cool features when developing Flutter apps. The whole platform has been a pleasure to use and it’s made app creation fun again for me.
This was a quick overview of Flutter and where you can go to start using it. I hope you have now a better idea on what you can expect. To conclude here are couple more advanced resources I found very helpful to get inspired and get started.
In my next post I’ll be going over how I use Flutter in my game specifically. Some topics I’ll be covering will be:
This week marks 3 months since I arrived to Guatemala - 2 of those during the pandemic. Things are generally good still and I’ve been enjoying working on my app. I’m quite busy though since I’ve got a second app to release this month!
Here’s a view of Volcán de Fuego erupting which I can see from my bedroom. Pretty cool huh?