From ba2f18f26038d96f020ea89cb7974ee2df760d23 Mon Sep 17 00:00:00 2001 From: Brian Nenninger Date: Sun, 9 May 2021 13:50:55 -0400 Subject: [PATCH] Fade mood bubbles in and out --- lib/main.dart | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 9410294..7246836 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -47,6 +47,8 @@ enum AnimationMode { } final illegalSlapAnimationDuration = Duration(milliseconds: 600); +final moodDuration = Duration(milliseconds: 5000); +final moodFadeMillis = 500; enum AIMode {human_vs_human, human_vs_ai, ai_vs_ai} @@ -97,7 +99,6 @@ class _MyHomePageState extends State { int aiSlapCounter = 0; // Used to check if a previously scheduled AI slap is still valid. late List catImageNumbers; List aiMoods = [AIMood.none, AIMood.none]; - int aiMoodCounter = 0; AISlapSpeed aiSlapSpeed = AISlapSpeed.medium; final numCatImages = 4; @@ -244,17 +245,6 @@ class _MyHomePageState extends State { Rank.jack: 12, }; - void _setAiMoods(final List moods) { - aiMoodCounter += 1; - int previousMoodCounter = aiMoodCounter; - setState(() => aiMoods = moods); - Future.delayed(const Duration(milliseconds: 5000), () { - if (previousMoodCounter == aiMoodCounter) { - setState(() => aiMoods = [AIMood.none, AIMood.none]); - } - }); - } - // Whether the AI should show a mood after winning or losing a pile, as determined by the number // and importance of cards in the pile. bool _aiHasMoodForPile(final List pileCards) { @@ -266,6 +256,10 @@ class _MyHomePageState extends State { return total > 16; } + void _setAiMoods(final List moods) { + setState(() => aiMoods = moods); + } + void _updateAiMoodsForPile(final List pileCards, final int pileWinner) { if (_aiHasMoodForPile(pileCards)) { var moods = pileWinner == 0 ? [AIMood.happy, AIMood.angry] : [AIMood.angry, AIMood.happy]; @@ -415,18 +409,37 @@ class _MyHomePageState extends State { ) ), + // Fade mood bubbles in and out. if (moodImage != null) Positioned.fill(top: 5, bottom: 40, child: Transform.translate( offset: Offset(110, 0), - child: Image( - image: AssetImage('assets/cats/$moodImage'), - fit: BoxFit.fitHeight, - alignment: Alignment.center, + child: TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: moodDuration.inMilliseconds.toDouble()), + duration: moodDuration, + onEnd: () => setState(() => aiMoods = [AIMood.none, AIMood.none]), + child: Image( + image: AssetImage('assets/cats/$moodImage'), + fit: BoxFit.fitHeight, + alignment: Alignment.center, + ), + builder: (BuildContext context, double animMillis, Widget? child) { + double op = 1.0; + if (animMillis < moodFadeMillis) { + op = animMillis / moodFadeMillis; + } + else if (animMillis > moodDuration.inMilliseconds - moodFadeMillis) { + op = (moodDuration.inMilliseconds - animMillis) / moodFadeMillis; + } + return Opacity( + opacity: op, + child: child, + ); + }, ) - ) + ), ), ], - ) + ), ); }