diff --git a/lib/dash_sweeper.dart b/lib/dash_sweeper.dart index 8cbce5e..0af1a9b 100644 --- a/lib/dash_sweeper.dart +++ b/lib/dash_sweeper.dart @@ -14,15 +14,36 @@ class DashSweeper extends StatefulWidget { State createState() => _DashSweeperState(); } -class _DashSweeperState extends State { +class _DashSweeperState extends State + with TickerProviderStateMixin { + static const countdownMax = 3; + late List tiles; + late Animation countdown; + late AnimationController countdownController; + + bool paused = false; @override void initState() { super.initState(); + countdownController = AnimationController( + vsync: this, + duration: Duration(seconds: countdownMax), + ); + countdown = Tween( + begin: countdownMax.toDouble(), + end: 0, + ).animate(countdownController); _generateTiles(widget.rows, widget.columns); } + @override + void dispose() { + countdownController.dispose(); + super.dispose(); + } + void _generateTiles(int rows, int columns) { // calculate tiles final amount = rows * columns; @@ -189,6 +210,8 @@ class _DashSweeperState extends State { } void _resetGame() { + paused = false; + countdownController.reset(); setState(() { _generateTiles(widget.rows, widget.columns); }); @@ -200,6 +223,10 @@ class _DashSweeperState extends State { .map((tile) => tile.copyWith(state: TileState.revealed)) .toList(growable: false); }); + _gameOverDialog(); + } + + void _gameOverDialog() { showDialog( context: context, barrierDismissible: false, @@ -208,8 +235,8 @@ class _DashSweeperState extends State { title: Text('Game Over'), content: Text('Bummer...'), actions: [ - OutlinedButton( - onPressed: () {}, + ElevatedButton( + onPressed: _timerToDialog, child: Text('Show field'), ), ElevatedButton( @@ -225,6 +252,19 @@ class _DashSweeperState extends State { ); } + void _timerToDialog() { + Navigator.of(context).pop(); + countdownController.forward(from: 0); + countdownController.addStatusListener((status) { + if (status == AnimationStatus.completed) { + if (mounted && (ModalRoute.of(context)?.isCurrent ?? false)) { + _gameOverDialog(); + countdownController.reset(); + } + } + }); + } + /// Recursive function to get all empty tiles to reveal at once. Set emptyTilesToReveal( int index, { @@ -252,6 +292,53 @@ class _DashSweeperState extends State { @override Widget build(BuildContext context) { return Scaffold( + appBar: AppBar( + title: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text('DashSweeper'), + AnimatedBuilder( + animation: countdown, + builder: (context, child) { + if (countdownController.value == 0) return SizedBox.shrink(); + return Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Stack( + alignment: Alignment.center, + children: [ + CircularProgressIndicator.adaptive( + value: countdown.value / countdownMax, + ), + IconButton( + onPressed: () { + setState(() { + paused = !paused; + }); + if (paused) { + countdownController.stop(); + } else { + countdownController.forward(); + } + }, + icon: Icon( + paused ? Icons.play_arrow : Icons.pause, + ), + ), + ], + ), + ); + }, + ), + ], + ), + centerTitle: true, + actions: [ + IconButton( + onPressed: _resetGame, + icon: Icon(Icons.refresh), + ), + ], + ), body: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: widget.columns,