feat: add reshuffle for ticket
This commit is contained in:
@@ -44,6 +44,7 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
|
||||
(event, emit) => repository.send({'type': 'choose_trump', 'suit': event.suit}));
|
||||
on<PlayCardEvent>(
|
||||
(event, emit) => repository.send({'type': 'play_card', 'card': event.card}));
|
||||
on<ReshuffleEvent>((event, emit) => repository.send({'type': 'reshuffle'}));
|
||||
on<LeaveGameEvent>((event, emit) => repository.send({'type': 'leave'}));
|
||||
on<StartTableEvent>((event, emit) =>
|
||||
repository.send({'type': 'start_table', 'hands': event.hands}));
|
||||
@@ -83,6 +84,7 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
|
||||
|
||||
// --- متدهای کمکی برای موتور Flame و صفحهها ---
|
||||
void chooseTrump(String suit) => add(ChooseTrumpEvent(suit));
|
||||
void reshuffle() => add(ReshuffleEvent());
|
||||
void playCard(String card) => add(PlayCardEvent(card));
|
||||
void leave() => add(LeaveGameEvent());
|
||||
void startTable(int hands) => add(StartTableEvent(hands));
|
||||
|
||||
@@ -30,6 +30,8 @@ class PlayCardEvent extends GameEvent {
|
||||
PlayCardEvent(this.card);
|
||||
}
|
||||
|
||||
class ReshuffleEvent extends GameEvent {} // بُرِ مجدد با مصرفِ یک بلیت
|
||||
|
||||
class LeaveGameEvent extends GameEvent {}
|
||||
|
||||
class StartTableEvent extends GameEvent {
|
||||
|
||||
@@ -11,6 +11,7 @@ import '../../../../core/service/app_sounds.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../wallet/presentation/bloc/wallet_bloc.dart';
|
||||
import '../../../wallet/presentation/bloc/wallet_event.dart';
|
||||
import '../../../wallet/presentation/bloc/wallet_state.dart';
|
||||
import '../../../wallet/presentation/bloc/wallet_status.dart';
|
||||
import '../../domain/entities/game_entities.dart';
|
||||
import '../bloc/game_bloc.dart';
|
||||
@@ -446,6 +447,53 @@ class _GameScreenState extends State<GameScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(color: Color(0x33E9B949), height: 1),
|
||||
const SizedBox(height: 12),
|
||||
// بُرِ مجدد با مصرفِ یک بلیت (۵ کارتِ تازه، سپس باز هم انتخابِ حکم).
|
||||
BlocBuilder<WalletBloc, WalletBlocState>(
|
||||
builder: (context, ws) {
|
||||
final tickets = ws.walletStatus is WalletLoaded
|
||||
? (ws.walletStatus as WalletLoaded).wallet.tickets
|
||||
: 0;
|
||||
final canReshuffle = tickets > 0;
|
||||
return Column(
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF8E1B7A),
|
||||
disabledBackgroundColor: const Color(0xFF3A2233),
|
||||
minimumSize: const Size(220, 48),
|
||||
),
|
||||
onPressed: canReshuffle
|
||||
? () {
|
||||
AppSounds.button();
|
||||
context.read<GameBloc>().reshuffle();
|
||||
// پس از مصرفِ بلیت، موجودی را تازه کن (بدون نگهداشتنِ context).
|
||||
final wallet = context.read<WalletBloc>();
|
||||
Future.delayed(const Duration(milliseconds: 500),
|
||||
() => wallet.add(LoadWalletEvent()));
|
||||
}
|
||||
: null,
|
||||
icon: const Icon(Icons.casino, color: Colors.white),
|
||||
label: const Text(
|
||||
'بُر مجدد (۱ بلیت)',
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
canReshuffle
|
||||
? 'بلیتهای شما: $tickets'
|
||||
: 'بلیت کافی ندارید',
|
||||
style: const TextStyle(
|
||||
color: Colors.white60, fontSize: 12),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -47,6 +47,7 @@ class HokmGame extends FlameGame {
|
||||
List<String> _prevTrick = const [];
|
||||
int _bestTrumpRank = 0; // بالاترین رتبهی حکمِ بازیشده در دستِ جاری (برای افکتِ بریدن)
|
||||
int _prevHandSize = 0; // برای تشخیصِ پخشِ کارت (دستِ جدید) جهت صدای بُر زدن
|
||||
String _prevHandSig = ''; // امضای دست؛ برای تشخیصِ بُرِ مجدد (تغییرِ ۵ کارت در فازِ حکم)
|
||||
bool _silent = false; // هنگام خروج از میز، دیگر صدایی پخش نشود
|
||||
bool _introActive = true; // تا پایانِ نمایشِ «جستجوی حریف»
|
||||
bool _pendingShuffle =
|
||||
@@ -89,6 +90,18 @@ class HokmGame extends FlameGame {
|
||||
_shuffleNow();
|
||||
}
|
||||
}
|
||||
// بُرِ مجدد: هنوز در فازِ حکم هستیم اما ۵ کارتِ حاکم عوض شده ⇒ انیمیشنِ بُر دوباره.
|
||||
final sig = (s.yourHand.toList()..sort()).join(',');
|
||||
if (!_silent &&
|
||||
!_introActive &&
|
||||
s.phase == 'choose_trump' &&
|
||||
s.trump == null &&
|
||||
_prevHandSize > 0 &&
|
||||
_prevHandSig.isNotEmpty &&
|
||||
sig != _prevHandSig) {
|
||||
_shuffleNow();
|
||||
}
|
||||
_prevHandSig = sig;
|
||||
// لحظهی انتخابِ حکم: صدا + نمایشِ بزرگِ حکم در مرکز.
|
||||
if (_prevTrump == null && s.trump != null && !_silent) {
|
||||
AppSounds.selectHokm();
|
||||
@@ -103,6 +116,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;
|
||||
_prevHandSig = (cubit.state.state!.yourHand.toList()..sort()).join(',');
|
||||
_prevTrump = cubit.state.state!.trump;
|
||||
_s = cubit.state.state;
|
||||
_relayout();
|
||||
|
||||
Reference in New Issue
Block a user