70 lines
2.0 KiB
Dart
70 lines
2.0 KiB
Dart
import 'dart:math' as math;
|
|
|
|
import 'package:flame/components.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../../../../../core/theme/app_theme.dart';
|
|
|
|
/// حلقهی شمارشِ معکوسِ نوبت: کمانی که در طولِ مهلتِ نوبت خالی میشود.
|
|
/// در ثانیههای پایانی قرمز و ضرباندار میشود. (صدای ضربانِ قلب در HokmGame
|
|
/// مدیریت میشود تا هنگامِ بازیشدنِ کارت بلافاصله قطع شود.)
|
|
class TurnTimer extends PositionComponent {
|
|
final double radius;
|
|
final double durationSeconds;
|
|
double _elapsed = 0;
|
|
|
|
TurnTimer({
|
|
required this.radius,
|
|
required this.durationSeconds,
|
|
required Vector2 position,
|
|
}) : super(
|
|
position: position,
|
|
size: Vector2.all(radius * 2),
|
|
anchor: Anchor.center,
|
|
);
|
|
|
|
double get _warnSecs => math.min(8.0, durationSeconds * 0.4);
|
|
|
|
static final _bg = Paint()
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = 3
|
|
..color = Colors.black54;
|
|
|
|
@override
|
|
void update(double dt) {
|
|
_elapsed += dt;
|
|
final remaining = durationSeconds - _elapsed;
|
|
// ضربانِ تصویری در پنجرهی هشدار.
|
|
if (remaining > 0 && remaining <= _warnSecs) {
|
|
scale = Vector2.all(1 + 0.18 * math.sin(_elapsed * 2 * math.pi / 0.7).abs());
|
|
} else {
|
|
scale = Vector2.all(1);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void render(Canvas canvas) {
|
|
final center = Offset(radius, radius);
|
|
canvas.drawCircle(center, radius, _bg);
|
|
|
|
final frac = durationSeconds <= 0
|
|
? 0.0
|
|
: (1 - _elapsed / durationSeconds).clamp(0.0, 1.0);
|
|
if (frac <= 0) return;
|
|
|
|
final color = frac > 0.35 ? AppColors.gold : AppColors.suitRed;
|
|
final arc = Paint()
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = 4
|
|
..strokeCap = StrokeCap.round
|
|
..color = color;
|
|
canvas.drawArc(
|
|
Rect.fromCircle(center: center, radius: radius),
|
|
-math.pi / 2,
|
|
2 * math.pi * frac,
|
|
false,
|
|
arc,
|
|
);
|
|
}
|
|
}
|