feat:add frames

This commit is contained in:
2026-07-08 12:15:06 +03:30
parent 46a649166b
commit df2ae2a215
9 changed files with 379 additions and 70 deletions
@@ -431,22 +431,28 @@ class HokmGame extends FlameGame {
}
}
// چیدمانِ بادبزنیِ منحنی: کارت‌ها چرخش و قوسِ ملایم دارند (مثل دستِ واقعی).
// اندازه‌ی دست کمی بزرگ‌تر از کارت‌های روی میز است (خوانا ولی نه نامتوازن).
// چیدمانِ بادبزنیِ واقعی: کارت‌ها روی قوسِ یک دایره چیده و هم‌راستا با شعاعِ آن
// چرخانده می‌شوند (کارتِ وسط بالا و صاف، کناری‌ها پایین‌تر و چرخیده) — مثلِ دستِ
// واقعی. مرکزِ قوس پایینِ دست است. اندازه‌ی دست کمی بزرگ‌تر از کارت‌های میز.
final hw = size.x * 0.24, hh = hw * kCardRatio;
final handW = size.x * 0.90;
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.83;
final baseY = size.y * 0.86;
final tMax = (n - 1) / 2;
const edgeAngle = 0.34; // چرخشِ کارت‌های کناری (رادیان)
final dip = hh * 0.16; // افتِ عمودیِ کارت‌های کناری برای قوس
// زاویه‌ی بینِ کارت‌ها؛ با تعدادِ زیاد جمع‌تر می‌شود تا بادبزن بیش‌ازحد باز نشود.
final perCard = n > 1 ? (0.9 / (n - 1)).clamp(0.0, 0.11) : 0.0;
final maxA = perCard * tMax;
// شعاعِ قوس از عرضِ گسترشِ دست مشتق می‌شود تا فاصله‌ها متوازن بماند.
final spreadX = size.x * 0.86 - hw;
final radius = maxA > 0.01 ? (spreadX / 2) / math.sin(maxA) : size.y;
final pivotY = baseY + radius;
for (var i = 0; i < n; i++) {
final code = codes[i];
final t = i - tMax;
final norm = tMax > 0 ? t / tMax : 0.0;
final target = Vector2(cx + t * stepX, baseY + norm * norm * dip);
final a = (i - tMax) * perCard; // زاویه‌ی این کارت روی قوس
final target = Vector2(
cx + radius * math.sin(a),
pivotY - radius * math.cos(a),
);
final legal = _legal(code);
var c = _hand[code];
final isNew = c == null;
@@ -464,7 +470,7 @@ class HokmGame extends FlameGame {
} else {
c.size = Vector2(hw, hh);
}
c.angle = norm * edgeAngle; // چرخشِ بادبزنی
c.angle = a; // چرخشِ کارت هم‌راستا با شعاعِ قوس
c.onPlay = legal ? () => cubit.playCard(code) : null;
c.dimmed = s.phase == 'playing' && s.isMyTurn && !legal;
c.home = target;