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}));
|
(event, emit) => repository.send({'type': 'choose_trump', 'suit': event.suit}));
|
||||||
on<PlayCardEvent>(
|
on<PlayCardEvent>(
|
||||||
(event, emit) => repository.send({'type': 'play_card', 'card': event.card}));
|
(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<LeaveGameEvent>((event, emit) => repository.send({'type': 'leave'}));
|
||||||
on<StartTableEvent>((event, emit) =>
|
on<StartTableEvent>((event, emit) =>
|
||||||
repository.send({'type': 'start_table', 'hands': event.hands}));
|
repository.send({'type': 'start_table', 'hands': event.hands}));
|
||||||
@@ -83,6 +84,7 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
|
|||||||
|
|
||||||
// --- متدهای کمکی برای موتور Flame و صفحهها ---
|
// --- متدهای کمکی برای موتور Flame و صفحهها ---
|
||||||
void chooseTrump(String suit) => add(ChooseTrumpEvent(suit));
|
void chooseTrump(String suit) => add(ChooseTrumpEvent(suit));
|
||||||
|
void reshuffle() => add(ReshuffleEvent());
|
||||||
void playCard(String card) => add(PlayCardEvent(card));
|
void playCard(String card) => add(PlayCardEvent(card));
|
||||||
void leave() => add(LeaveGameEvent());
|
void leave() => add(LeaveGameEvent());
|
||||||
void startTable(int hands) => add(StartTableEvent(hands));
|
void startTable(int hands) => add(StartTableEvent(hands));
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ class PlayCardEvent extends GameEvent {
|
|||||||
PlayCardEvent(this.card);
|
PlayCardEvent(this.card);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ReshuffleEvent extends GameEvent {} // بُرِ مجدد با مصرفِ یک بلیت
|
||||||
|
|
||||||
class LeaveGameEvent extends GameEvent {}
|
class LeaveGameEvent extends GameEvent {}
|
||||||
|
|
||||||
class StartTableEvent extends GameEvent {
|
class StartTableEvent extends GameEvent {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import '../../../../core/service/app_sounds.dart';
|
|||||||
import '../../../../core/theme/app_theme.dart';
|
import '../../../../core/theme/app_theme.dart';
|
||||||
import '../../../wallet/presentation/bloc/wallet_bloc.dart';
|
import '../../../wallet/presentation/bloc/wallet_bloc.dart';
|
||||||
import '../../../wallet/presentation/bloc/wallet_event.dart';
|
import '../../../wallet/presentation/bloc/wallet_event.dart';
|
||||||
|
import '../../../wallet/presentation/bloc/wallet_state.dart';
|
||||||
import '../../../wallet/presentation/bloc/wallet_status.dart';
|
import '../../../wallet/presentation/bloc/wallet_status.dart';
|
||||||
import '../../domain/entities/game_entities.dart';
|
import '../../domain/entities/game_entities.dart';
|
||||||
import '../bloc/game_bloc.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 [];
|
List<String> _prevTrick = const [];
|
||||||
int _bestTrumpRank = 0; // بالاترین رتبهی حکمِ بازیشده در دستِ جاری (برای افکتِ بریدن)
|
int _bestTrumpRank = 0; // بالاترین رتبهی حکمِ بازیشده در دستِ جاری (برای افکتِ بریدن)
|
||||||
int _prevHandSize = 0; // برای تشخیصِ پخشِ کارت (دستِ جدید) جهت صدای بُر زدن
|
int _prevHandSize = 0; // برای تشخیصِ پخشِ کارت (دستِ جدید) جهت صدای بُر زدن
|
||||||
|
String _prevHandSig = ''; // امضای دست؛ برای تشخیصِ بُرِ مجدد (تغییرِ ۵ کارت در فازِ حکم)
|
||||||
bool _silent = false; // هنگام خروج از میز، دیگر صدایی پخش نشود
|
bool _silent = false; // هنگام خروج از میز، دیگر صدایی پخش نشود
|
||||||
bool _introActive = true; // تا پایانِ نمایشِ «جستجوی حریف»
|
bool _introActive = true; // تا پایانِ نمایشِ «جستجوی حریف»
|
||||||
bool _pendingShuffle =
|
bool _pendingShuffle =
|
||||||
@@ -89,6 +90,18 @@ class HokmGame extends FlameGame {
|
|||||||
_shuffleNow();
|
_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) {
|
if (_prevTrump == null && s.trump != null && !_silent) {
|
||||||
AppSounds.selectHokm();
|
AppSounds.selectHokm();
|
||||||
@@ -103,6 +116,7 @@ class HokmGame extends FlameGame {
|
|||||||
if (cubit.state.state != null) {
|
if (cubit.state.state != null) {
|
||||||
_prevTrick = cubit.state.state!.trick.map((t) => t.card).toList();
|
_prevTrick = cubit.state.state!.trick.map((t) => t.card).toList();
|
||||||
_prevHandSize = cubit.state.state!.yourHand.length;
|
_prevHandSize = cubit.state.state!.yourHand.length;
|
||||||
|
_prevHandSig = (cubit.state.state!.yourHand.toList()..sort()).join(',');
|
||||||
_prevTrump = cubit.state.state!.trump;
|
_prevTrump = cubit.state.state!.trump;
|
||||||
_s = cubit.state.state;
|
_s = cubit.state.state;
|
||||||
_relayout();
|
_relayout();
|
||||||
|
|||||||
Reference in New Issue
Block a user