feat: style
This commit is contained in:
@@ -5,9 +5,9 @@ import 'package:flutter/material.dart';
|
||||
|
||||
/// یک کارت روی میز؛ اگر تصویر `assets/images/cards/<code>.png` موجود باشد از آن
|
||||
/// استفاده میکند، وگرنه نسخهی برداری میکشد. برای پشت کارت `back.jpg`.
|
||||
/// کارتهای قابلبازی هم با tap و هم با کشیدن (drag) به سمت زمین بازی میشوند.
|
||||
/// کارتهای قابلبازی فقط با **کشیدن (drag)** به سمت زمین بازی میشوند (نه tap).
|
||||
class CardComponent extends PositionComponent
|
||||
with TapCallbacks, DragCallbacks, HasGameReference {
|
||||
with DragCallbacks, HasGameReference {
|
||||
final String code; // مثل "AS"؛ برای پشت کارت خالی
|
||||
final bool faceUp;
|
||||
VoidCallback? onPlay; // در صورت مجاز بودن، بازیِ این کارت
|
||||
@@ -42,11 +42,6 @@ class CardComponent extends PositionComponent
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onTapUp(TapUpEvent event) {
|
||||
if (_playable) onPlay!.call();
|
||||
}
|
||||
|
||||
@override
|
||||
void onDragStart(DragStartEvent event) {
|
||||
super.onDragStart(event);
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:math' as math;
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/effects.dart';
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame_audio/flame_audio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../game_cubit.dart';
|
||||
@@ -40,6 +41,7 @@ class HokmGame extends FlameGame {
|
||||
double _shake = 0;
|
||||
double _t = 0;
|
||||
List<String> _prevTrick = const [];
|
||||
int _prevHandSize = 0; // برای تشخیصِ پخشِ کارت (دستِ جدید) جهت صدای بُر زدن
|
||||
|
||||
HokmGame(this.cubit);
|
||||
|
||||
@@ -49,19 +51,31 @@ class HokmGame extends FlameGame {
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
add(Felt());
|
||||
// پیشبارگذاریِ صدای بُر زدن (در صورت نبودِ فایل، بیصدا رد میشود).
|
||||
FlameAudio.audioCache.load('shuffle.mp3').catchError((_) => Uri());
|
||||
_sub = cubit.stream.listen((ui) {
|
||||
if (ui.state == null) return;
|
||||
_checkCut(ui.state!);
|
||||
_s = ui.state;
|
||||
final s = ui.state!;
|
||||
_checkCut(s);
|
||||
// شروعِ دستِ جدید (پخشِ کارت): صدای بُر زدن.
|
||||
if (_prevHandSize == 0 && s.yourHand.isNotEmpty) _playShuffle();
|
||||
_prevHandSize = s.yourHand.length;
|
||||
_s = s;
|
||||
_relayout();
|
||||
});
|
||||
if (cubit.state.state != null) {
|
||||
_prevTrick = cubit.state.state!.trick.map((t) => t.card).toList();
|
||||
_prevHandSize = cubit.state.state!.yourHand.length;
|
||||
_s = cubit.state.state;
|
||||
_relayout();
|
||||
}
|
||||
}
|
||||
|
||||
void _playShuffle() {
|
||||
// اگر فایل صدا نباشد، خطا نادیده گرفته میشود (بازی بیصدا).
|
||||
FlameAudio.play('shuffle.mp3', volume: 0.7).then((_) {}, onError: (_) {});
|
||||
}
|
||||
|
||||
@override
|
||||
void onGameResize(Vector2 size) {
|
||||
super.onGameResize(size);
|
||||
@@ -173,16 +187,21 @@ class HokmGame extends FlameGame {
|
||||
}
|
||||
}
|
||||
|
||||
// کارتهای دستِ خودتان بزرگتر از کارتهای روی میز.
|
||||
// چیدمانِ بادبزنیِ منحنی: کارتها چرخش و قوسِ ملایم دارند (مثل دستِ واقعی).
|
||||
final hw = size.x * 0.225, hh = hw * kCardRatio;
|
||||
final handW = size.x * 0.80;
|
||||
final step = n > 1 ? (handW - hw) / (n - 1) : 0.0;
|
||||
final startX = size.x / 2 - (step * (n - 1)) / 2;
|
||||
final y = size.y * 0.85;
|
||||
final handW = size.x * 0.86;
|
||||
final stepX = n > 1 ? ((handW - hw) / (n - 1)).clamp(0.0, hw * 0.62) : 0.0;
|
||||
final cx = size.x / 2;
|
||||
final baseY = size.y * 0.86;
|
||||
final tMax = (n - 1) / 2;
|
||||
const edgeAngle = 0.34; // چرخشِ کارتهای کناری (رادیان)
|
||||
final dip = hh * 0.16; // افتِ عمودیِ کارتهای کناری برای قوس
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
final code = codes[i];
|
||||
final target = Vector2(startX + i * step, y);
|
||||
final t = i - tMax;
|
||||
final norm = tMax > 0 ? t / tMax : 0.0;
|
||||
final target = Vector2(cx + t * stepX, baseY + norm * norm * dip);
|
||||
final legal = _legal(code);
|
||||
var c = _hand[code];
|
||||
if (c == null) {
|
||||
@@ -193,6 +212,7 @@ class HokmGame extends FlameGame {
|
||||
} else {
|
||||
c.size = Vector2(hw, hh);
|
||||
}
|
||||
c.angle = norm * edgeAngle; // چرخشِ بادبزنی
|
||||
c.onPlay = legal ? () => cubit.playCard(code) : null;
|
||||
c.dimmed = s.phase == 'playing' && s.isMyTurn && !legal;
|
||||
c.home = target;
|
||||
@@ -240,6 +260,7 @@ class HokmGame extends FlameGame {
|
||||
_trick[tc.card] = c;
|
||||
}
|
||||
c.size = Vector2(_cardW, _cardH);
|
||||
c.angle = 0; // کارتهای روی زمین صافاند (چرخشِ بادبزنیِ دست حذف میشود)
|
||||
c.priority = 5;
|
||||
_moveTo(c, slot);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user