From 500c61a4099114a779153447ea2717f402f2671f Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Wed, 24 Jun 2026 14:17:21 +0330 Subject: [PATCH] fix: trump trick --- assets/audio/turn.mp3 | Bin 0 -> 12582 bytes lib/core/service/app_sounds.dart | 5 ++ .../game/presentation/screen/game_screen.dart | 60 ++++++++++++++++-- .../presentation/widgets/flame/hokm_game.dart | 18 ++++-- 4 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 assets/audio/turn.mp3 diff --git a/assets/audio/turn.mp3 b/assets/audio/turn.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..141aaac7d43958f9cdd375bb1f7fe75668529dc9 GIT binary patch literal 12582 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 Yl{TWeiJHc`3V%OE`1iYk|L^Jl0Ft$DssI20 literal 0 HcmV?d00001 diff --git a/lib/core/service/app_sounds.dart b/lib/core/service/app_sounds.dart index 81bb7af..7089d88 100644 --- a/lib/core/service/app_sounds.dart +++ b/lib/core/service/app_sounds.dart @@ -16,6 +16,7 @@ class AppSounds { static const _button = 'button.mp3'; // فشردنِ دکمه‌ها static const _selectHokm = 'select_hokm.mp3'; // انتخابِ حکم static const _heartBeat = 'heart_beat.mp3'; // ثانیه‌های پایانیِ نوبت + static const _turn = 'turn.mp3'; // شروعِ نوبتِ خودِ کاربر static const _all = [ _shuffle, @@ -26,6 +27,7 @@ class AppSounds { _button, _selectHokm, _heartBeat, + _turn, ]; static final Map _pools = {}; @@ -59,6 +61,9 @@ class AppSounds { static void cut() => _play(_cut, 0.9); static void win() => _play(_win, 0.9); static void selectHokm() => _play(_selectHokm, 0.9); + static void turn() => _play(_turn, 0.9); // نوبتِ کاربر برای بازی + // شمارشِ معکوسِ شروعِ بازی (۳…۲…۱) — کلیکِ کوتاه برای هر عدد. + static void tick() => _play(_button, 0.7, cutoffMs: 200); // کنترلِ ضربانِ قلب: همیشه حداکثر یک ضربان هم‌زمان (بدون انباشت/تکرارِ سریع) // و قابلِ توقف وقتی نوبت تمام می‌شود. diff --git a/lib/feature/game/presentation/screen/game_screen.dart b/lib/feature/game/presentation/screen/game_screen.dart index 851b30e..9c1e8d0 100644 --- a/lib/feature/game/presentation/screen/game_screen.dart +++ b/lib/feature/game/presentation/screen/game_screen.dart @@ -31,6 +31,7 @@ class _GameScreenState extends State { late final HokmGame _game; Timer? _introTimer; bool _introHidden = false; + int _countdown = 0; // شمارشِ معکوسِ شروعِ بازی پس از یافتنِ حریفان (۳…۲…۱) @override void initState() { @@ -90,12 +91,23 @@ class _GameScreenState extends State { }, builder: (context, state) { if (state.state != null && _introTimer == null) { - // کمی «حریفان پیدا شد» نشان بده، بعد اوورلی را کنار بزن و همان - // لحظه انیمیشنِ بُر زدن (با صدا) را اجرا کن. - _introTimer = Timer(const Duration(milliseconds: 1000), () { - if (!mounted) return; - setState(() => _introHidden = true); - _game.endIntro(); + // حریفان پیدا شدند ⇒ شمارشِ معکوسِ ۳…۲…۱ با صدا تا کاربر بداند + // بازی در حالِ شروع است، سپس اوورلی کنار می‌رود و بُر زدن اجرا می‌شود. + _countdown = 3; // داخلِ build هستیم؛ همین build مقدار را نشان می‌دهد + AppSounds.tick(); + _introTimer = Timer.periodic(const Duration(seconds: 1), (t) { + if (!mounted) { + t.cancel(); + return; + } + if (_countdown <= 1) { + t.cancel(); + setState(() => _introHidden = true); + _game.endIntro(); + } else { + setState(() => _countdown--); + AppSounds.tick(); + } }); } return Stack( @@ -286,6 +298,42 @@ class _GameScreenState extends State { 'در حال یافتن حریفان…', style: TextStyle(color: Colors.white70, fontSize: 13), ), + ] else if (_countdown > 0) ...[ + const SizedBox(height: 14), + const Text( + 'شروع بازی', + style: TextStyle(color: Colors.white70, fontSize: 13), + ), + const SizedBox(height: 6), + TweenAnimationBuilder( + // هر عدد با یک «پاپ» ظاهر می‌شود تا واضح و جلب‌توجه باشد. + key: ValueKey(_countdown), + tween: Tween(begin: 1.6, end: 1.0), + duration: const Duration(milliseconds: 400), + curve: Curves.easeOut, + builder: (_, scale, child) => + Transform.scale(scale: scale, child: child), + child: Container( + width: 54, + height: 54, + alignment: Alignment.center, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: const LinearGradient( + colors: [AppColors.gold, AppColors.goldDark], + ), + border: Border.all(color: Colors.white, width: 2), + ), + child: Text( + '$_countdown', + style: const TextStyle( + color: Color(0xFF3A0A12), + fontSize: 26, + fontWeight: FontWeight.bold, + ), + ), + ), + ), ], ], ), diff --git a/lib/feature/game/presentation/widgets/flame/hokm_game.dart b/lib/feature/game/presentation/widgets/flame/hokm_game.dart index 697202a..ed56786 100644 --- a/lib/feature/game/presentation/widgets/flame/hokm_game.dart +++ b/lib/feature/game/presentation/widgets/flame/hokm_game.dart @@ -45,7 +45,7 @@ class HokmGame extends FlameGame { double _shake = 0; double _t = 0; List _prevTrick = const []; - bool _cutThisTrick = false; // افکتِ بریدن فقط یک‌بار در هر دست + int _bestTrumpRank = 0; // بالاترین رتبه‌ی حکمِ بازی‌شده در دستِ جاری (برای افکتِ بریدن) int _prevHandSize = 0; // برای تشخیصِ پخشِ کارت (دستِ جدید) جهت صدای بُر زدن bool _silent = false; // هنگام خروج از میز، دیگر صدایی پخش نشود bool _introActive = true; // تا پایانِ نمایشِ «جستجوی حریف» @@ -135,17 +135,19 @@ class HokmGame extends FlameGame { } final addedOne = now.length == _prevTrick.length + 1 && _isPrefix(_prevTrick, now); - if (now.length <= 1) _cutThisTrick = false; // دستِ جدید ⇒ ریستِ افکتِ بریدن + if (now.length <= 1) _bestTrumpRank = 0; // دستِ جدید ⇒ ریستِ بالاترین حکم if (addedOne) { final card = s.trick.last; - final isCut = - s.trump != null && + // بریدن: خالِ راهبر حکم نیست و کارتِ بازی‌شده حکم است. + final isTrump = s.trump != null && s.leadSuit != null && s.leadSuit != s.trump && suitName(card.card) == s.trump; - // افکتِ بریدن فقط برای اولین بریدنِ هر دست (بریدن‌های بعدی فقط صدای گذاشتن). - if (isCut && !_cutThisTrick) { - _cutThisTrick = true; + final rank = isTrump ? rankValue(card.card) : 0; + // افکتِ بریدن فقط وقتی حکمِ بازی‌شده «دست را می‌برد» (بالاترین حکم تا کنون): + // یعنی اولین بریدن یا روبریدنِ بالاتر. حکمِ پایین‌تر (بازنده) فقط صدای گذاشتن. + if (isTrump && rank > _bestTrumpRank) { + _bestTrumpRank = rank; _shake = 1.0; add(Lightning()); AppSounds.cut(); // بریدن با حکم (شمشیر) @@ -273,6 +275,8 @@ class HokmGame extends FlameGame { _turnElapsed = 0; _beatPlayed = false; _hbAccum = 0; + // صدای «نوبتِ شما» فقط هنگامِ بازیِ کارت (نه پخش/انتخابِ حکم). + if (s.phase == 'playing' && !_dealing) AppSounds.turn(); } _turnElapsed += dt;