feat: add game graphic

This commit is contained in:
2026-07-08 09:06:32 +03:30
parent ffd2646eea
commit 46a649166b
15 changed files with 521 additions and 57 deletions
@@ -13,6 +13,7 @@ import '../bloc/wallet_bloc.dart';
import '../bloc/wallet_event.dart';
import '../bloc/wallet_state.dart';
import '../bloc/wallet_status.dart';
import '../widgets/coin_fly.dart';
import '../widgets/streak_dialog.dart';
/// لابی اصلی: کیف‌پول، دکمه بازی/دورهمی/فروشگاه/سکه روزانه.
@@ -24,6 +25,9 @@ class LobbyScreen extends StatefulWidget {
}
class _LobbyScreenState extends State<LobbyScreen> {
final _coinKey = GlobalKey(); // چیپِ سکه (مقصدِ پروازِ سکه‌ها)
final _dailyKey = GlobalKey(); // کارتِ هدیه‌ی روزانه (مبدأ)
@override
void initState() {
super.initState();
@@ -32,6 +36,20 @@ class _LobbyScreenState extends State<LobbyScreen> {
void _reload() => context.read<WalletBloc>().add(LoadWalletEvent());
Offset? _center(GlobalKey k) {
final box = k.currentContext?.findRenderObject() as RenderBox?;
if (box == null || !box.attached) return null;
return box.localToGlobal(box.size.center(Offset.zero));
}
void _flyCoins() {
final from = _center(_dailyKey);
final to = _center(_coinKey);
if (from != null && to != null && mounted) {
CoinFly.play(context, from: from, to: to);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -41,6 +59,7 @@ class _LobbyScreenState extends State<LobbyScreen> {
listener: (context, state) {
final d = state.dailyStatus;
if (d is DailySuccess) {
_flyCoins(); // پروازِ سکه‌ها از کارتِ هدیه به چیپِ سکه
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('سکه روزانه دریافت شد: +${d.amount}')),
);
@@ -56,7 +75,10 @@ class _LobbyScreenState extends State<LobbyScreen> {
return SafeArea(
child: Column(
children: [
_TopBar(wallet: wallet, onCoinTap: () => _openShop(context)),
_TopBar(
wallet: wallet,
coinKey: _coinKey,
onCoinTap: () => _openShop(context)),
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(16, 6, 16, 8),
@@ -121,6 +143,7 @@ class _LobbyScreenState extends State<LobbyScreen> {
),
const SizedBox(height: 14),
_DailyCard(
key: _dailyKey,
wallet: wallet,
onTap:
() => StreakDialog.show(
@@ -347,7 +370,7 @@ class _ActionTile extends StatelessWidget {
class _DailyCard extends StatelessWidget {
final WalletEntity? wallet;
final VoidCallback onTap;
const _DailyCard({required this.wallet, required this.onTap});
const _DailyCard({super.key, required this.wallet, required this.onTap});
@override
Widget build(BuildContext context) {
@@ -478,7 +501,8 @@ class _DailyCard extends StatelessWidget {
class _TopBar extends StatelessWidget {
final WalletEntity? wallet;
final VoidCallback onCoinTap;
const _TopBar({required this.wallet, required this.onCoinTap});
final Key? coinKey;
const _TopBar({required this.wallet, required this.onCoinTap, this.coinKey});
@override
Widget build(BuildContext context) {
@@ -582,6 +606,7 @@ class _TopBar extends StatelessWidget {
),
const SizedBox(width: 8),
GestureDetector(
key: coinKey,
onTap: onCoinTap,
child: StatChip(
icon: Icons.monetization_on,