home_board.dart 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import 'dart:ui' as ui;
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. import 'package:logging/logging.dart';
  5. import 'package:puzzleweave/config/device.dart';
  6. import 'package:puzzleweave/models/download.dart';
  7. import 'package:puzzleweave/models/items.dart';
  8. final Logger _log = Logger('home_board');
  9. enum HomeBoardStatus { loading, dealing, playing, done, unlocking }
  10. class HomeBoard {
  11. final Device device;
  12. // 原合集图
  13. ui.Image? image;
  14. // 纸牌背面图
  15. late ui.Image cardImage;
  16. // board 的canvas绘制区域尺寸
  17. final double canvasWidth;
  18. final double canvasHeight;
  19. /// 一张合集分为几宫格,固定5x5
  20. final int rows = 5;
  21. final int cols = 5;
  22. int get count => rows * cols;
  23. // 每个piece的逻辑尺寸
  24. double get pieceLogicalWidth => canvasWidth / cols;
  25. double get pieceLogicalHeight => canvasHeight / rows;
  26. ValueNotifier boardNotifier = ValueNotifier(1);
  27. HomeBoardStatus status = HomeBoardStatus.loading;
  28. ListItem? _currentCollectionItem;
  29. ListItem? get currentCollectionItem => _currentCollectionItem;
  30. set currentCollectionItem(ListItem? item) {
  31. if (item == null) return;
  32. if (_currentCollectionItem == null || _currentCollectionItem!.id != item.id) {
  33. _currentCollectionItem = item;
  34. _loadImage();
  35. }
  36. }
  37. ValueNotifier isReadyNotifier = ValueNotifier(false);
  38. // 用于存储合集解锁动画相关信息
  39. Offset _unlockTargetOffset = Offset.zero;
  40. double _unlockTargetScale = 1.0;
  41. Offset get unlockTargetOffset => _unlockTargetOffset;
  42. double get unlockTargetScale => _unlockTargetScale;
  43. void setUnlockAnimationTarget({required Offset targetOffset, required double targetScale}) {
  44. _unlockTargetOffset = targetOffset;
  45. _unlockTargetScale = targetScale;
  46. }
  47. HomeBoard({required this.canvasWidth, required this.canvasHeight, required this.device}) {
  48. _loadCardImage();
  49. }
  50. void invalidate() {
  51. boardNotifier.value++;
  52. }
  53. // 加载合集图
  54. void _loadImage() async {
  55. double dpr = device.devicePixelRatio;
  56. ItemLoader itemLoader = ItemLoader.load(currentCollectionItem!);
  57. image = await itemLoader.getImageBySize((canvasWidth * dpr).round(), (canvasHeight * dpr).round());
  58. isReadyNotifier.value = true;
  59. invalidate();
  60. _log.info('加载collection图片: ${currentCollectionItem.toString()}');
  61. }
  62. // 加载卡片图
  63. void _loadCardImage() async {
  64. double dpr = device.devicePixelRatio;
  65. // 加载扑克背面图片,用于制作发牌动画
  66. final Size bestCardImageSize = Size(pieceLogicalWidth * dpr, pieceLogicalHeight * dpr);
  67. final ByteData cardData = await rootBundle.load('assets/images/backcard_green.png');
  68. final ui.Codec cardCodec = await ui.instantiateImageCodec(
  69. cardData.buffer.asUint8List(),
  70. targetWidth: bestCardImageSize.width.round(),
  71. targetHeight: bestCardImageSize.height.round(),
  72. );
  73. final ui.FrameInfo cardFrameInfo = await cardCodec.getNextFrame();
  74. cardImage = cardFrameInfo.image;
  75. invalidate();
  76. }
  77. // 老的合集完成,切换到新的合集
  78. void switchToNextCollection(ListItem newItem) {
  79. _log.info('合集完全解锁,切换到新的合集');
  80. // // 先释放原来的资源
  81. // image?.dispose();
  82. // image = null;
  83. // 重新加载新合集图
  84. isReadyNotifier.value = false;
  85. currentCollectionItem = newItem;
  86. }
  87. }