feat: staggered star reveal and near-miss progress ring
Stars on win now appear sequentially with elastic-bounce via TweenAnimationBuilder (400/650/900 ms). Lost overlay shows a CircularProgressIndicator ring with "87% complete!" (l10n: almostThere) when objectiveProgress > 0. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,5 +20,13 @@
|
|||||||
"type": "int"
|
"type": "int"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"almostThere": "{percent}% complete!",
|
||||||
|
"@almostThere": {
|
||||||
|
"placeholders": {
|
||||||
|
"percent": {
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -13,5 +13,6 @@
|
|||||||
"giveUp": "포기하기",
|
"giveUp": "포기하기",
|
||||||
"playAgain": "다시 하기",
|
"playAgain": "다시 하기",
|
||||||
"nextStage": "다음 스테이지",
|
"nextStage": "다음 스테이지",
|
||||||
"streakMilestone": "{days}일 연속 플레이! 대단해요!"
|
"streakMilestone": "{days}일 연속 플레이! 대단해요!",
|
||||||
|
"almostThere": "{percent}% 달성!"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,16 +344,46 @@ class _GameScreenState extends ConsumerState<GameScreen>
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < 3; i++)
|
for (var i = 0; i < 3; i++)
|
||||||
Icon(
|
TweenAnimationBuilder<double>(
|
||||||
Icons.star,
|
tween: Tween(begin: 0, end: 1),
|
||||||
size: 40,
|
duration: Duration(milliseconds: 400 + i * 250),
|
||||||
color: i < view.starsEarned
|
curve: Interval(i * 0.22, 1, curve: Curves.elasticOut),
|
||||||
? Colors.amber
|
builder: (context, v, child) =>
|
||||||
: Colors.white24,
|
Transform.scale(scale: v, child: child),
|
||||||
|
child: Icon(
|
||||||
|
Icons.star,
|
||||||
|
size: 44,
|
||||||
|
color: i < view.starsEarned ? Colors.amber : Colors.white24,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
if (view.phase == GamePhase.lost && view.objectiveProgress > 0) ...[
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
SizedBox(
|
||||||
|
width: 88,
|
||||||
|
height: 88,
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
CircularProgressIndicator(
|
||||||
|
value: view.objectiveProgress,
|
||||||
|
strokeWidth: 7,
|
||||||
|
backgroundColor: Colors.white12,
|
||||||
|
color: Colors.amber,
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
l10n.almostThere((view.objectiveProgress * 100).round()),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: theme.textTheme.labelSmall,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
...actions,
|
...actions,
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user