feat: animate hit or miss message instead of snackbar

This commit is contained in:
Orangerot 2025-01-08 10:41:22 +01:00
parent c5cee0cb9d
commit 856949ceef

View file

@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
@ -23,7 +22,7 @@ class InputDirection {
bool right = false;
}
class _LevelState extends State<Level> {
class _LevelState extends State<Level> with SingleTickerProviderStateMixin {
final player = AudioPlayer();
bool _isPlaying = true;
Duration? _duration;
@ -35,8 +34,13 @@ class _LevelState extends State<Level> {
final FocusNode _focusNode = FocusNode();
InputDirection inputDirection = InputDirection();
String hitOrMissMessage = 'Play!';
List<Note> notes = [];
late AnimationController _animationController;
late Animation<double> _animation;
@override
void setState(VoidCallback fn) {
// Subscriptions only can be closed asynchronously,
@ -49,6 +53,15 @@ class _LevelState extends State<Level> {
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
_animation =
Tween<double>(begin: 1.0, end: 0.0).animate(_animationController);
_animationController.forward();
// Use initial values from player
player.getDuration().then(
(value) => setState(() {
@ -109,23 +122,20 @@ class _LevelState extends State<Level> {
if (keypressCorrect) {
print("you hit!");
note.wasHit = true;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Great!'),
duration: Duration(milliseconds: 500),
),
);
_animationController.reset();
_animationController.forward();
setState(() {
hitOrMissMessage = 'Great!';
});
}
} else if (note.position < -0.5 * 1.0 / 60.0) {
print("Missed");
note.wasHit = false;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Missed!'),
duration: Duration(milliseconds: 500),
),
);
_animationController.reset();
_animationController.forward();
setState(() {
hitOrMissMessage = 'Missed';
});
}
}
});
@ -215,12 +225,15 @@ class _LevelState extends State<Level> {
top: 50,
width: MediaQuery.of(context).size.width,
left: 0,
child: FadeTransition(
opacity: _animation,
child: Text(
"Great!",
hitOrMissMessage,
textScaler: TextScaler.linear(4),
textAlign: TextAlign.center,
),
),
),
Positioned(
left: MediaQuery.of(context).size.width / 2 - 50,
bottom: 50,
@ -238,6 +251,7 @@ class _LevelState extends State<Level> {
@override
void dispose() {
_animationController.dispose();
_durationSubscription?.cancel();
_positionSubscription?.cancel();
player.dispose();