Building ABND Project 2 — Score Keeper App with Flutter

(This is the Second post in Series of Recreating ABND Projects with Flutter.)

Finished App

📝 Project Overview

Score-Keeper will contain following things.

  • An app-bar with reset button.
  • Body is divided in 2 equal sections.
  • Each section will have following details of a player - name, score, image, health-points (HP), 2 buttons.

🔌 Prerequisites

🔧 Setup

flutter create score_keeper
  • App contains 2 image file (asset) for displaying player images. So, create a new directory named assets at root of the project. You can download player images from here (Cuphead) & here (Mugman). Then add them in assets/ directory & register these assets in pubspec.yaml as follows.
pubspec.yaml after registering assets
  • Your pubspec.yaml will look something like this:
  • That’s it, we’re done with the project setup. So let’s get started with some code.

🎹 Coding

  • Remove everything from main.dart file.
  • We’re going to use Material Widgets for designing app, which are present in flutter/material.dart package. They are implemented according to Google’s Material Design Guidelines.
  • Add main function with runApp function inside it’s body. Pass MyApp() inside runApp function. runApp will inflate MyApp widget & it is going to be parent of all other widgets. Return MaterialApp from build method & set home to Game(), which (Game) is going to be a class which we’ll create in next step.
  • Create a new class named Game (You can name it anything) which extends StatefulWidget. We need StatefulWidget because UI of app is dynamic, that means here certain part of app like ScoreBoard, Health-Points does change when Button is pressed. So we need to maintain states of those widgets, that’s why we need a StatefulWidget.
  • In Game class, there is createState method, which return an instance of _GameState class (State Object), which (_GameState) we’re going to create in next steps.
main.dart after adding some Initial Code
  • Now create _GameState class which is going to extend State<Game>, and contains build method, which can be called multiple times to redraw UI (by calling setState). It has several data-members which stores things like score & health-points of each player. Along with some colours to indicate who is leading player in the Game.
main.dart after creating _GameState class
  • Now let’s add some code in build method. Add a Scaffold & AppBar to get started. Set action property of AppBar and add a IconButton with refresh icon, which will reset the scores & health-points of players.
  • Set body of Scaffold with SingleChildScrollView & add Row as it’s child widget. Add 2 playerInformation widgets, which we’re going to create in next steps. This widget creates a section to display each player’s stats with some Text, Button and Image.
main.dart after adding build method
  • playerInformation method returns a Widget like this. It has 4 Texts, 1 Image, 2 Buttons. We can add 2 playerInformation widgets as children of Row.
playerInformation Widget for Cuphead
  • There are 3 local variables - colors (for Buttons, Text & Background), playerImage & playerImagePadding (for adjusting player images since both images are of different sizes). By default colors stores Cuphead theme that is 3 shades of Red, playerImage has path to Cuphead’s image & playerImagePadding is 12.
  • Now if playerName is “Mugman”, then we assign empty list to the colors (list) and add 3 shades of Blue, set playerImage to Mugman’s image & playerImagePadding to 38.
  • Now add an Expanded widget with flex set to 1 & add a Container as it’s child. It’s background is set to first value (either Colors.blue[100] or Colors.red[100]) in the colors (list).
  • Add a Column as child of Container, which will contain 7 children widgets. Let’s see each of these in sequence. Depending upon value playerName parameter, things will be rendered differently.
  • First widget displays name of a player (Cuphead or Mugman) & colour of Text is set according the value of playerName parameter. If it’s “Cuphead”, then text-colour will be Colors.red[500], otherwise Colors.blue[500], that is third element in colors (list).
  • Second widget displays score of a player. It is wrapped around a Padding widget to give some equal padding from all 4 sides.
  • Third widget displays image of a player. Image.asset is wrapped around a Padding widget, in turn it is wrapped around a SizedBox with a fixed height of 70 & width is set to double.infinity, which is like match_parent in Android.
  • Fourth widget displays the text “HP”. It is wrapped inside a Padding widget.
  • Fifth widget displays health-points of a player. It is wrapped around a Padding widget. Depending upon playerName parameter, it displays HP of that specific player.
  • Sixth widget is a RaisedButton, when it is pressed, it decrements 1 HP of opposite player & score of the player who pressed it gets incremented by 1.
  • Last widget is also a RaisedButton, when it is pressed, it decrements 2 HP of opposite player & score of the player who pressed it gets incremented by 2.
main.dart after adding playerInformation method
  • Now let’s understand methods which are used to update scores and HPs & methods which are used to highlight colours of scores and HPs.
  • First method is _cupheadShoot, which calls setState method to update cuphead’s score by 1 and decrement mugman’s HP by 1. It also call _scoreHighlighter method to highlight scores of both players. If a player’s score is greater than other player than, leading player’s score is highlighted with green (Colors.green[800]) colour and other player’s score is highlighted with (Colors.red[800]). After that _hpHighlighter method is called to highlight HP of opposite player. This method checks current value of HP of that player and highlights it with Colors.green if value is between 21 & 25, else if value is between 16 & 20, it highlights HP with Colors.lightGreen and so on.
  • Similarly there are 3 other methods, _cupheadExmove, _mugman & _mugmanExmove. They do the almost same things as _cupheadShoot.
main.dart after adding helper methods.
  • Finally we’re now left with 2 more methods, _resetGame & showWinnerDialog.
  • _resetGame method calls setState to set score, HP, score highlight colour, HP highlight colour of both players to their initial values.
  • showWinnerDialog displays an AlertDialog when HP of one of the player reaches 0 to display name of the winner.
main.dart after adding _resetGame & showWinnerDialog

👀 Demo

Demo

That’s it for this one. Thank you for reading this 💙

You can find complete source code of this app in this repository.

If you find this post useful, press� button as many times as you can and share this post with others. You can leave your feedback/suggestion in comments 💬 below. For future posts of this series, you can follow me on medium to receive post updates. 🔔

You can checkout the original project written in Java here.

For any other issues feel free to reach out to me via Twitter.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store