I am participating in the Mid-Autumn Festival Creative Submission contest, please see: Mid-Autumn Festival Creative Submission Contest for details
Look at the effect
The rules of the game is very simple, after the moon cake is thrown to hit the moon, that is, 1 points, otherwise the round of the game is over, the number of consecutive hits for the round of points.
coded
There is not much complexity in the code, but the general logic is as follows:
1 the moon movement animation, using Tween to achieve a Tween animation, using TweenSequence to specify the animation sequence, monitoring the completion of the animation repeat animation, so as to achieve the effect of the moon around uninterrupted movement.
_animationController = AnimationController(duration: Duration(milliseconds: 600), vsync: this); _animationControllerCake = AnimationController(duration: Duration(milliseconds: 900), vsync: this); TweenSequenceItem<double> downMarginItem = TweenSequenceItem<double>(tween: tween (begin: 1.0, end: 50.0), weight: 50); TweenSequenceItem<double> upMarginItem = TweenSequenceItem<double>(tween: tween (begin: 50.0, end: 300.0), weight: , 100); TweenSequence<double> tweenSequence = TweenSequence<double>([ downMarginItem, upMarginItem, ]); _animation = tweenSequence.animate(_animationController); _animation.addListener(() { if (_animation.isCompleted) { _animationController.reverse(); } if (_animation.isDismissed) { _animationController.forward(); } setState(() {}); });Copy the code
2. The moon cake throwing displacement effect, using StreamBuilder control and Timer countdown, continuously Stream the current position data within 1 second, so as to constantly change the distance from the moon cake to the bottom, it looks like a displacement animation effect, but in fact, it is a visual effect formed by constantly changing the distance.
_countdownTimer = new Timer.periodic(new Duration(milliseconds: 1), (timer) {
if (_milliSecond > 0) {
_milliSecond = _milliSecond - 5;
} else {
_countdownTimer.cancel();
}
_cakeStreamController.sink.add(_milliSecond < 0 ? 0 : _milliSecond);
});
Copy the code
Container( margin: EdgeInsets.only(bottom: distance), child: Image.asset( "assets/images/cake.png", width: 60, height: 60,),)Copy the code
3 The key point is how to judge the moon cake will collide with the moon after being thrown out, that is, “eat the moon cake”. The implementation scheme is: the moon’s height is known (screen height – status bar height – distance from the moon above), the moon cake’s abscissa is fixed (half the width of the screen). Listen in StreamBuilder: when the moon moon reaches the height of the moon, determine whether the moon’s abscis is the same as the moon moon. If so, the moon moon coincides with the moon, which is recorded as a valid score. In order to increase the playability of the game, the coordinates are not strictly judged to coincide completely. As shown in the picture, when the moon cake reaches the height of the moon, if the moon is in the red area, it will be recorded as a valid score.
Judgment logic:
// When the moon cake reaches the height of the moon, Distance < (_screenheight-120) && distance > (_screenheight-170 - MediaQuery.of(context).padding.top)) { print(_animation.value); if (_animation.value < (_screenWidth / 2 + 10) && _animation.value > (_screenWidth / 2 - 90)) { _hintStreamController.add(" Awesome "); Print (" hit "); _score++; } else { _hintStreamController.add("MISS"); print("MISS"); } _milliSecond = 1000; _cakeStreamController.sink.add(_milliSecond); _countdownTimer.cancel(); }Copy the code
Introducing leaderboards
In order to increase the fun of the game, the online score ranking mechanism is added in the game. In the game, the highest score of the player will be uploaded to the server, and you can check your position in the ranking in the upper right corner of the main interface.
The cloud server storage function here uses a third-party platform called LeanCloud, which supports Flutter and just added an air safety iteration in August.
Scan the download link
Currently support android version download, what are you waiting for, quickly download the list of ~
The code address
Making a link
As the cloud server uses LeanCloud, the downloaded old iron needs to apply for AppKey on LeanCloud platform and fill in the initial position in Main. dart in the project.
LeanCloud.initialize(
"", "",
server: "https://zsyju4p5.lc-cn-n1-shared.com", // to use your own custom domain
queryCache: new LCQueryCache() // optinoal, enable cache
)
Copy the code