| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- import 'package:gobang/controllers/game_controller.dart';
- import 'package:gobang/models/position.dart';
- import 'package:gobang/widgets/board_painter.dart';
- /// 可点击的五子棋棋盘;最后一手带落子动画与高亮标记。
- class GobangBoard extends StatefulWidget {
- const GobangBoard({super.key, required this.size});
- final double size;
- @override
- State<GobangBoard> createState() => _GobangBoardState();
- }
- class _GobangBoardState extends State<GobangBoard>
- with SingleTickerProviderStateMixin {
- late final AnimationController _controller;
- late final Animation<double> _scale;
- late final Animation<double> _pulse;
- Worker? _paintWorker;
- @override
- void initState() {
- super.initState();
- _controller = AnimationController(
- vsync: this,
- duration: const Duration(milliseconds: 520),
- );
- _scale = CurvedAnimation(
- parent: _controller,
- curve: const Interval(0, 0.55, curve: Curves.easeOutBack),
- );
- _pulse = TweenSequence<double>([
- TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 1),
- TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.35), weight: 1),
- TweenSequenceItem(tween: Tween(begin: 0.35, end: 0.8), weight: 1),
- TweenSequenceItem(tween: Tween(begin: 0.8, end: 0.0), weight: 1),
- ]).animate(
- CurvedAnimation(
- parent: _controller,
- curve: const Interval(0.2, 1.0, curve: Curves.easeInOut),
- ),
- );
- final c = Get.find<GameController>();
- _paintWorker = ever<int>(c.paintVersion, (_) {
- if (c.board.state.isEmpty) {
- _controller.value = 0;
- return;
- }
- _controller.forward(from: 0);
- });
- }
- @override
- void dispose() {
- _paintWorker?.dispose();
- _controller.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- final c = Get.find<GameController>();
- return Obx(() {
- // 必须在 Obx 作用域内直接读取 .obs,不能放进 AnimatedBuilder
- final version = c.paintVersion.value;
- final pieces = List<Position>.unmodifiable(c.board.state);
- return GestureDetector(
- onTapDown: (d) => c.onBoardTap(d.localPosition, widget.size),
- child: AnimatedBuilder(
- animation: _controller,
- builder: (context, _) {
- return CustomPaint(
- size: Size.square(widget.size),
- painter: BoardPainter(
- pieces: pieces,
- version: version,
- lastMoveScale: _scale.value,
- lastMovePulse: _pulse.value,
- ),
- );
- },
- ),
- );
- });
- }
- }
|