A Simple EYE Test Game, built using Flutter CustomPainter

Related tags

Gaming fCreate
Overview

fCreate

A Simple EYE Test Game, powered by Flutter CustomPainter.

Getting Started

A simple Android Application built with ❤️ using Flutter. This application is taking part in Flutter Create Competition. That's why it has limited capabilities, built using only 5112 bytes Dart Code. And it's a Dart only application, targets Android SDK version 28.

How's it working ?

  • Execution starts with App() class, which extends StatelessWidget.

  • As this application only targets Android, it's a MaterialApp.

  • As I'm going to add interactivity to our app, I need a StatefulWidget. Home() satisfies that need.

  • Due to code limit, I'm restricting my application to be only running in Portrait mode.

      SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  • In the build method I'm returing a Scaffold Widget, which provides a sound Material Design skeleton.

  • body of Scaffold is a Stack widget, which is very good at handling hiding of overlapping widgets, depending upon certain criteria or user event, by using Opacity Widget as its parent.

  • Well I'm also using a FloatingActionButton(), to go to Game Widget, from Help Widget and vice versa.

      floatingActionButton: FloatingActionButton(
        onPressed: _e
            ? () {
                swap();
                // _tm holds a periodic Timer, which helps us to generate a new Paint widget, every 1 seconds.
                _tm = Timer.periodic(Duration(seconds: 1), (t) {
                  if (t.isActive)
                    setState(() {
                      _b = Random().nextInt(12) + 8; // _b, holds number of columns and rows, to be drawn in Paint widget
                      // which also gets updated in random fashion
                    });
                });
              }
            : () {
                swap();
                _tm.cancel(); // timer, _tm is cancelled, to avoid unnecessary periodic computational tasks.
              }, // here `e` is a boolean variable, which decides behaviour of this button
        child: Icon(_e ? Icons.play_arrow : Icons.help), // icon also gets updated
        backgroundColor: Colors.cyanAccent,
        elevation: 16,
        tooltip: _e ? 'Init' : 'Help', // tooltip text is also updated as value of `e` gets updated.
      ),
  • So, you've encountered a new function swap(), it just changes opacity value of two widgets and make them either visible or invisible.

      swap() {
    var tmp = _h; // simple swapping of `_h` and `_g` is done here.
    setState(() {
      _h = _g;
      _g = tmp;
      _e = !_e; // putting negation of `_e` into `_e`, helps us to change behaviour of floatingActionButton.
    });
    }
  • You may have already found a method called setW(), which is present due to implementation of White class in _HomeState.

      @override
    setW(int c) {
    if (!_tm.isActive)
      setState(() {
        _wh = c;
      });
    else
      _wh = c; // here I'm not interested in updating the UI too, that's why assignment is put outside of setState((){}).
      // otherwise that might collide with scheduled UI updated operation, which runs periodically using Timer, and updates CustomPaint widget.
    }
  • A GestureDetector widget is used as parent of CustomPaint, to handle user input event. A single tap denotes, that user selects currently shown Paint widget and wants to know whether he/ she has selected a widget which has atleast 50% white colored balls. In response to this event a Dialog shows up to indicate status of current selection.

      onTap: () {
                  if (_tm.isActive) {
                    _tm.cancel();
                    showDialog(
                        context: context,
                        builder: (cx) => Dialog(
                            elevation: 9,
                            child: Padding(
                                padding: EdgeInsets.all(16),
                                child: Text(
                                    '$_wh/${_b * _b} White Balls ${_wh >= (_b * _b) / 2 ? '\u{2714}' : '\u{2716}'}',
                                    style: TextStyle(
                                        fontSize: 25, letterSpacing: 2)))));
                  }
                },
  • Now if you double click on screen, cancelled timer starts running again.

      
                onDoubleTap: () {
                  if (!_tm.isActive)
                    _tm = Timer.periodic(Duration(seconds: 1), (t) {
                      if (t.isActive)
                        setState(() {
                          _b = Random().nextInt(12) + 8;
                        });
                    });
                }
  • A center aligned widget is used a child of Opacity, to display help page. Changing opacity value reveals either help page or game page. Of course parent of these Opacity widget is Stack widget.

      Center(
                child: Padding(
                    padding: EdgeInsets.all(12),
                    child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Text('An EYE Test Game',
                              style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  letterSpacing: 3,
                                  fontSize: 30)),
                          Divider(color: Colors.white, height: 24),
                          Text(
                              'Click to reveal whether it has atleast 50% WHITE Balls. Double clicking restarts loop.',
                              maxLines: 3)
                        ])))
  • Lets talk about Painter class which subclasses CustomPainter and mainly takes care of painting operation to be performed in CustomPaint widget. Painter's constructor takes two parameters, number of balls to be placed along row and column( it's a square ) and an instance of White class, which works as callback mechanism for updating value of white balls generated randomly during painting, stored in a variable which resides in _HomeState class.

  • As per definition of CustomPainter, need to override paint() and shouldRepaint() methods in Painter.

  • So, I'll be drawing some circles, for that I need an Offset. Position along X-axis and Y-axis is determined as follows.

    double y = size.height / (b * 2); // b is # of balls along x and y axis.
    double x = size.width / (b * 2); 
  • White ball count is determined as following one.

      w += (p.color == Colors.white) ? 1 : 0; // p variable holds instance of Paint(), which is instantiated just in previous line.
  • This is how circle is drawn in iterative fashion, using a while loop until we reach size.width along X-axis or size.height along Y-axis.

      canvas.drawCircle(
            Offset(x, y), min(size.height / (b * 2), size.width / (b * 2)), p); // radius of circle is decreased, so that no two circle gets overlapped.
  • In inner while loop of paint(), coordinate value of x is increased size.width / b in each iteration.

    x += size.width / b;
  • Same for y too, in outer while loop.

    y += size.height / b;
  • After drawing is done, number of white balls drawn on screen is updated, where White abstract class plays an role.

    wh.setW(w); // wh is an instance of WHite, which is passed into constructor of Painter.
  • This is it.

Screen Captures

ScreenCapture 1 ScreenCapture 2 ScreenCapture 3

Download

Release version of apk can be found here.

Courtesy

Last but not least thanks to Flutter, Dart, Google and all other persons who're somehow associated with this project. Thanks for building such a great ecosystem.

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

Hope it was helpful 😄

You might also like...

A Simple TicTacToe Game Built With Flutter

A Simple TicTacToe Game Built With Flutter

A Simple TicTacToe Game Built With Flutter

Jun 30, 2022

A simple TicTacToe game app built with Flutter

Tic-Tac-Toe A simple TicTacToe game app built with Flutter. Getting Started This project is a starting point for a Flutter application. A few resource

Jan 22, 2021

Dungeon Fantasy - A simple RPG game built with Bonfire and Flame engine

dungeon_fantasy A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started

Dec 28, 2021

FiveSins: A Web3 Game Built Using Flutter

FiveSins: A Web3 Game Built Using Flutter

FiveSins FiveSins is a Web3 Game 团队 Ziqiang Huang:合约开发 Wenhao Deng:游戏开发、前端 Rui S

Jul 14, 2022

A simple dino game using flutter

A simple dino game using flutter

Dino game A new Flutter application. Getting Started This project is a starting

Jul 16, 2022

SnakeGameFlutter - A Simple Snake Game Developed using Flutter

SnakeGameFlutter - A Simple Snake Game Developed using Flutter

snakegame Snacke Game Developed Using Flutter Getting Started This project is a

Feb 12, 2022

Tap-Tap-Go Game built with flutter

Tap-Tap-Go Game built with flutter

Tap Tap Go A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Oct 12, 2021

Tic Tac Toe Game built with flutter

Tic Tac Toe Game built with flutter

Flutter Tic Tac Game 🎮 ⭐️ this repo if you like it. Getting Started 🚀 Clone the repo Install the dependicies Run it Preview 📸 Contact me 📧 Email :

Dec 6, 2022

😘 A wordle game clone built in flutter.

😘 A wordle game clone built in flutter.

Worddle A wordle game clone built in flutter. Uses hooks_riverpod for state management 📸 Screen Shots To Do - Add Statistics - Add Dark Mode - Add Cu

Dec 25, 2022
Owner
Anjan Roy
Learning :)
Anjan Roy
An application cum Game-based App built using Flutter that compose a mind-tricked word game, Just for fun.

destini_challenge A new Flutter application. Getting Started This project is a starting point for a Flutter application. A few resources to get you st

dev_allauddin 3 Feb 3, 2022
Chess-game - Some simple lines of coding and made this awesome looking full functional chess board game

flutter simple chess game It's a flutter chess game application with fast code.

Munem Sarker 5 Jun 17, 2022
Game characters ui - A redesign of a game characters app using flutter

Game characters ui - A redesign of a game characters app using flutter

null 20 Oct 23, 2022
Game Flutter Using Flame.It was for the Game Jam 2022

binarymemory Memory Binary Flame Flutter Game Jam Getting Started This project is a starting point for a Flutter application. A few resources to get y

Victor Manuel Lagunas Franco 2 Sep 7, 2022
A simple 2D multiplayer online game built using Flutter and Flame engine

Club Penguin Introduction ?? Club Penguin A multiplayer game involving penguins and anonymous chat in a virtual 2D world Before we start, you can take

Sanjeev Madhav 67 Dec 24, 2022
M.U.D. Role-playing text-based game. A multiple-choice multiplayer interactive game developed on Flutter (Android, iOS, Windows, Web)

Teia M.U.D. Role-playing text-based game. A multiple-choice multiplayer interactive game developed on Flutter (Android, iOS, Windows, Web). The main f

Pedro Gonçalves 3 Feb 17, 2022
Warrior Runner - Game made with Flutter and Flame game engine

Warrior Runner - Game made with Flutter Demo and Screenshot Flutter Version Used : 1.22.4 flame: 0.29.3 hive: 1.5.0-pre Learing Resources: Create a Mo

Mohammed Hashim 20 Oct 10, 2022
Snake-Game - A flutter based classic snake game with nothing just and just a feel to have play

snake_game This is a simple snake Game under development made with the help of y

Shubham Kumar 2 Mar 22, 2022
Flutter Switch Game: Get Fun With Play This Game

switch_game A new Flutter project. Getting Started Try Swap red circle to green

Sermed Berwari 1 Jun 17, 2022
A starter game in Flutter with all the bells and whistles of a mobile (iOS & Android) game

A starter game in Flutter with all the bells and whistles of a mobile (iOS & Android) game including the following features: sound music main menu scr

Samuel Abada 14 Dec 22, 2022