| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import 'package:flutter/cupertino.dart';
- import 'package:gobang/models/position.dart';
- import 'package:gobang/utils/constants.dart';
- /// 棋盘 + 棋子绘制;最后一手支持缩放入场与高亮光圈。
- class BoardPainter extends CustomPainter {
- BoardPainter({
- required this.pieces,
- required this.version,
- this.lastMoveScale = 1,
- this.lastMovePulse = 0,
- });
- final List<Position> pieces;
- final int version;
- final double lastMoveScale;
- final double lastMovePulse;
- @override
- void paint(Canvas canvas, Size size) {
- final cell = size.width / (kBoardSize - 1);
- final bg = Paint()
- ..isAntiAlias = true
- ..style = PaintingStyle.fill
- ..color = const Color(0x77cdb175);
- canvas.drawRect(Offset.zero & size, bg);
- final line = Paint()
- ..style = PaintingStyle.stroke
- ..color = CupertinoColors.systemGrey6
- ..strokeWidth = 1;
- for (var i = 0; i < kBoardSize; i++) {
- final o = cell * i;
- canvas.drawLine(Offset(0, o), Offset(size.width, o), line);
- canvas.drawLine(Offset(o, 0), Offset(o, size.height), line);
- }
- final radius = cell / 2 - 2;
- final fill = Paint()..style = PaintingStyle.fill;
- final lastIndex = pieces.length - 1;
- for (var i = 0; i < pieces.length; i++) {
- final p = pieces[i];
- final isLast = i == lastIndex;
- final center = Offset(p.dx, p.dy);
- final scale = isLast ? lastMoveScale.clamp(0.0, 1.2) : 1.0;
- final r = radius * scale;
- if (isLast && lastMovePulse > 0) {
- final ring = Paint()
- ..style = PaintingStyle.stroke
- ..strokeWidth = 2.5
- ..color = const Color(0xE0E53935).withValues(
- alpha: 0.85 * lastMovePulse,
- );
- canvas.drawCircle(center, radius * (1.15 + 0.45 * lastMovePulse), ring);
- }
- fill.color = p.chess.color;
- if (p.chessShape.shape == 1) {
- canvas.drawCircle(center, r, fill);
- } else {
- canvas.drawRect(
- Rect.fromCircle(center: center, radius: r),
- fill,
- );
- }
- // 最后一手中心小三角标记,方便辨认落点
- if (isLast && scale > 0.85) {
- final mark = Paint()
- ..style = PaintingStyle.fill
- ..color = const Color(0xFFE53935);
- final s = radius * 0.28;
- final path = Path()
- ..moveTo(center.dx, center.dy - s)
- ..lineTo(center.dx - s * 0.9, center.dy + s * 0.7)
- ..lineTo(center.dx + s * 0.9, center.dy + s * 0.7)
- ..close();
- canvas.drawPath(path, mark);
- }
- }
- }
- @override
- bool shouldRepaint(covariant BoardPainter oldDelegate) {
- return oldDelegate.version != version ||
- oldDelegate.lastMoveScale != lastMoveScale ||
- oldDelegate.lastMovePulse != lastMovePulse;
- }
- }
|