Created
February 1, 2020 19:47
-
-
Save misterfourtytwo/10e61c385700f0d8062d30a66d0b6024 to your computer and use it in GitHub Desktop.
Flutter Game with Implicit Animations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Implicit Animation Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: SafeArea( | |
minimum: EdgeInsets.only(top: 8), | |
child: Scaffold( | |
backgroundColor: Colors.brown[900], body: ImplicitAnimationDemo())), | |
); | |
} | |
} | |
class ImplicitAnimationDemo extends StatefulWidget { | |
ImplicitAnimationDemo({Key key}) : super(key: key); | |
@override | |
_ImplicitAnimationDemoState createState() => _ImplicitAnimationDemoState(); | |
} | |
class _ImplicitAnimationDemoState extends State<ImplicitAnimationDemo> { | |
static final _rng = Random(); | |
Color _color = Colors.red; | |
double _width = 100, _height = 100, _radius = 25; | |
Alignment _alignment = Alignment(0.5, 0.5); | |
int _score = 0; | |
void _randomize() { | |
_color = Color.fromARGB( | |
180, | |
_rng.nextInt(255), | |
_rng.nextInt(255), | |
_rng.nextInt(255), | |
); | |
_width = _rng.nextDouble() * 120 + 30; | |
_height = _rng.nextDouble() * 120 + 30; | |
_radius = min(_width, _height) / 3 + 10; | |
_alignment = Alignment( | |
_rng.nextDouble() * 2 - 1, | |
_rng.nextDouble() * 2 - 1, | |
); | |
} | |
void _increaseScore() { | |
_score++; | |
} | |
Timer _timer; | |
int _countDown = 10; | |
bool _isPlaying = false; | |
void _startTimer() { | |
_timer = Timer.periodic( | |
Duration(seconds: 1), | |
(Timer timer) => setState( | |
() { | |
// print(_countDown); | |
if (_countDown < 1) { | |
_endGame(); | |
timer.cancel(); | |
} else { | |
_countDown--; | |
} | |
}, | |
), | |
); | |
} | |
void _startGame() { | |
_score = 0; | |
_countDown = 10; | |
_isPlaying = true; | |
_randomize(); | |
_startTimer(); | |
} | |
void _endGame() { | |
_isPlaying = false; | |
} | |
@override | |
void dispose() { | |
_timer.cancel(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Stack( | |
children: <Widget>[ | |
Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Text('Score: $_score', | |
style: TextStyle( | |
color: Colors.white, | |
fontSize: 48, | |
decoration: TextDecoration.none)), | |
_isPlaying | |
? Text('$_countDown', | |
style: TextStyle( | |
color: Colors.white, | |
fontSize: 28, | |
decoration: TextDecoration.none)) | |
: GestureDetector( | |
onTap: () => setState(() { | |
_startGame(); | |
}), | |
child: Text('Start', | |
style: TextStyle( | |
color: Colors.white, | |
fontSize: 28, | |
decoration: TextDecoration.none)), | |
), | |
], | |
), | |
), | |
if (_isPlaying) | |
GestureDetector( | |
onTap: () => setState(() { | |
_countDown += _score % 2; | |
_increaseScore(); | |
_randomize(); | |
}), | |
child: _Box( | |
alignment: _alignment, | |
height: _height, | |
width: _width, | |
color: _color, | |
radius: _radius)), | |
], | |
); | |
} | |
} | |
class _Box extends StatelessWidget { | |
const _Box({ | |
Key key, | |
@required Alignment alignment, | |
@required double height, | |
@required double width, | |
@required Color color, | |
@required double radius, | |
}) : _alignment = alignment, | |
_height = height, | |
_width = width, | |
_color = color, | |
_radius = radius, | |
super(key: key); | |
final Alignment _alignment; | |
final double _height; | |
final double _width; | |
final Color _color; | |
final double _radius; | |
@override | |
Widget build(BuildContext context) { | |
return Padding( | |
padding: EdgeInsets.all(10), | |
child: AnimatedAlign( | |
curve: Curves.decelerate, | |
duration: Duration(milliseconds: 820), | |
alignment: _alignment, | |
child: AnimatedContainer( | |
duration: Duration(milliseconds: 820), | |
curve: Curves.ease, | |
height: _height, | |
width: _width, | |
decoration: BoxDecoration( | |
color: _color, borderRadius: BorderRadius.circular(_radius)), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment