fix: some buggs

This commit is contained in:
2026-06-19 00:45:30 +03:30
parent f4d99043c4
commit a4cf2b5f39
7 changed files with 266 additions and 10 deletions
@@ -9,10 +9,12 @@ import 'package:flutter/material.dart';
import '../../../../../core/service/app_sounds.dart';
import '../../../domain/entities/game_entities.dart';
import '../../bloc/game_bloc.dart';
import 'badges.dart';
import 'card_codes.dart';
import 'card_component.dart';
import 'shuffle_animation.dart';
import 'table_pieces.dart';
import 'turn_timer.dart';
/// صحنه‌ی میز حکم با انیمیشن. شما همیشه پایین میز (rel=0) هستید.
/// کامپوننت‌های دست و trick ماندگارند و با افکت حرکت جابه‌جا می‌شوند.
@@ -46,6 +48,8 @@ class HokmGame extends FlameGame {
bool _silent = false; // هنگام خروج از میز، دیگر صدایی پخش نشود
bool _introActive = true; // تا پایانِ نمایشِ «جستجوی حریف»
bool _pendingShuffle = false; // بُرِ دستِ اول که تا پایانِ اینترو به تعویق افتاده
bool _shuffling = false; // در حالِ پخشِ انیمیشنِ بُر زدن (بازیِ کارت ممنوع)
String? _prevTrump; // برای تشخیصِ لحظه‌ی انتخابِ حکم
HokmGame(this.cubit);
@@ -69,6 +73,12 @@ class HokmGame extends FlameGame {
_shuffleNow();
}
}
// لحظه‌ی انتخابِ حکم: صدا + نمایشِ بزرگِ حکم در مرکز.
if (_prevTrump == null && s.trump != null && !_silent) {
AppSounds.selectHokm();
_spawnTrumpReveal(s.trump!);
}
_prevTrump = s.trump;
_prevHandSize = s.yourHand.length;
_s = s;
_relayout();
@@ -76,6 +86,7 @@ class HokmGame extends FlameGame {
if (cubit.state.state != null) {
_prevTrick = cubit.state.state!.trick.map((t) => t.card).toList();
_prevHandSize = cubit.state.state!.yourHand.length;
_prevTrump = cubit.state.state!.trump;
_s = cubit.state.state;
_relayout();
}
@@ -138,10 +149,41 @@ class HokmGame extends FlameGame {
}
/// اجرای هم‌زمانِ انیمیشن و صدای بُر زدن (صدا با پایانِ انیمیشن قطع می‌شود).
/// در طولِ انیمیشن، بازیِ کارت قفل است تا کارتی وسطِ بُر زدن انداخته نشود.
void _shuffleNow() {
if (_silent) return;
AppSounds.shuffle(cutoffMs: ShuffleAnimation.totalMs);
add(ShuffleAnimation(size));
_shuffling = true;
Future.delayed(const Duration(milliseconds: ShuffleAnimation.totalMs), () {
_shuffling = false;
if (_s != null && !_silent) _relayout(); // فعال‌سازیِ دوباره‌ی کارت‌ها
});
}
/// نمایشِ بزرگ و گذرای حکمِ انتخاب‌شده در مرکزِ میز (با پاپ).
void _spawnTrumpReveal(String trump) {
final (sym, col) = _trumpGlyph(trump);
final reveal = TextComponent(
text: 'حکم $sym',
anchor: Anchor.center,
position: size / 2 - Vector2(0, size.y * 0.10),
priority: 7000,
scale: Vector2.all(0.4),
textRenderer: TextPaint(
style: TextStyle(
fontFamily: 'Dana',
color: col,
fontSize: size.x * 0.11,
fontWeight: FontWeight.bold,
shadows: const [Shadow(color: Colors.black, blurRadius: 6)],
),
),
);
reveal.add(ScaleEffect.to(
Vector2.all(1.0), EffectController(duration: 0.35, curve: Curves.easeOutBack)));
reveal.add(RemoveEffect(delay: 1.3));
add(reveal);
}
static bool _isPrefix(List<String> a, List<String> b) {
@@ -191,6 +233,8 @@ class HokmGame extends FlameGame {
// آیا این کارت در نوبتِ فعلی قابل بازی است (با رعایت follow-suit)؟
bool _legal(String code) {
final s = _s!;
// هنگامِ نمایشِ اینترو یا انیمیشنِ بُر زدن، بازیِ کارت مجاز نیست.
if (_introActive || _shuffling) return false;
if (s.phase != 'playing' || s.trickDone || !s.isMyTurn) return false;
final lead = s.leadSuit;
if (lead == null || lead.isEmpty) return true;
@@ -441,15 +485,33 @@ class HokmGame extends FlameGame {
color: isTurn ? const Color(0xFFE9B949) : Colors.white70,
bold: isTurn,
);
// تاجِ حاکم (روی همه‌ی فازها نشان داده می‌شود تا حاکم مشخص باشد).
if (s.hakem == p.seat) {
final crown = CrownBadge(size.x * 0.06, pos - Vector2(0, size.y * 0.066))
..priority = 23;
_info.add(crown);
add(crown);
}
if (isTurn) {
final dot = CircleComponent(
radius: size.x * 0.012,
anchor: Anchor.center,
position: pos - Vector2(0, size.y * 0.03),
paint: Paint()..color = const Color(0xFFE9B949),
)..priority = 20;
_info.add(dot);
add(dot);
final tpos = pos - Vector2(0, size.y * 0.03);
final human = !p.bot && p.connected;
// حلقه‌ی شمارشِ نوبت برای بازیکنِ انسان.
if (human &&
s.turnTimeoutMs > 0 &&
(s.phase == 'playing' || s.phase == 'choose_trump')) {
final timer = TurnTimer(
radius: size.x * 0.03,
durationSeconds: s.turnTimeoutMs / 1000.0,
position: tpos,
)..priority = 20;
_info.add(timer);
add(timer);
}
// ستاره‌ی نوبت (مطابقِ تصویرِ مرجع) با ضربان.
final star = StarBadge(size.x * 0.015, tpos)..priority = 24;
star.add(pulse());
_info.add(star);
add(star);
}
}
}