import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:logging/logging.dart'; import 'package:puzzleweave/config/device.dart'; import 'package:puzzleweave/models/download.dart'; import 'package:puzzleweave/models/items.dart'; final Logger _log = Logger('home_board'); enum HomeBoardStatus { loading, dealing, playing, done, unlocking } class HomeBoard { final Device device; // 原合集图 ui.Image? image; // 纸牌背面图 late ui.Image cardImage; // board 的canvas绘制区域尺寸 final double canvasWidth; final double canvasHeight; /// 一张合集分为几宫格,固定5x5 final int rows = 5; final int cols = 5; int get count => rows * cols; // 每个piece的逻辑尺寸 double get pieceLogicalWidth => canvasWidth / cols; double get pieceLogicalHeight => canvasHeight / rows; ValueNotifier boardNotifier = ValueNotifier(1); HomeBoardStatus status = HomeBoardStatus.loading; ListItem? _currentCollectionItem; ListItem? get currentCollectionItem => _currentCollectionItem; set currentCollectionItem(ListItem? item) { if (item == null) return; if (_currentCollectionItem == null || _currentCollectionItem!.id != item.id) { _currentCollectionItem = item; _loadImage(); } } ValueNotifier isReadyNotifier = ValueNotifier(false); // 用于存储合集解锁动画相关信息 Offset _unlockTargetOffset = Offset.zero; double _unlockTargetScale = 1.0; Offset get unlockTargetOffset => _unlockTargetOffset; double get unlockTargetScale => _unlockTargetScale; void setUnlockAnimationTarget({required Offset targetOffset, required double targetScale}) { _unlockTargetOffset = targetOffset; _unlockTargetScale = targetScale; } HomeBoard({required this.canvasWidth, required this.canvasHeight, required this.device}) { _loadCardImage(); } void invalidate() { boardNotifier.value++; } // 加载合集图 void _loadImage() async { double dpr = device.devicePixelRatio; ItemLoader itemLoader = ItemLoader.load(currentCollectionItem!); image = await itemLoader.getImageBySize((canvasWidth * dpr).round(), (canvasHeight * dpr).round()); isReadyNotifier.value = true; invalidate(); _log.info('加载collection图片: ${currentCollectionItem.toString()}'); } // 加载卡片图 void _loadCardImage() async { double dpr = device.devicePixelRatio; // 加载扑克背面图片,用于制作发牌动画 final Size bestCardImageSize = Size(pieceLogicalWidth * dpr, pieceLogicalHeight * dpr); final ByteData cardData = await rootBundle.load('assets/images/backcard_green.png'); final ui.Codec cardCodec = await ui.instantiateImageCodec( cardData.buffer.asUint8List(), targetWidth: bestCardImageSize.width.round(), targetHeight: bestCardImageSize.height.round(), ); final ui.FrameInfo cardFrameInfo = await cardCodec.getNextFrame(); cardImage = cardFrameInfo.image; invalidate(); } // 老的合集完成,切换到新的合集 void switchToNextCollection(ListItem newItem) { _log.info('合集完全解锁,切换到新的合集'); // // 先释放原来的资源 // image?.dispose(); // image = null; // 重新加载新合集图 isReadyNotifier.value = false; currentCollectionItem = newItem; } }