252 lines
6.6 KiB
Dart
252 lines
6.6 KiB
Dart
import 'dart:async';
|
||
import 'dart:math' as math;
|
||
import 'package:flutter/material.dart';
|
||
import 'package:aesthetica_wallpaper/models/puzzle_game.dart';
|
||
|
||
/// 简化版拼图Provider,用于快速测试
|
||
class SimplePuzzleProvider extends ChangeNotifier {
|
||
PuzzleGame? _currentGame;
|
||
Timer? _timer;
|
||
List<GameRecord> _records = [];
|
||
|
||
PuzzleGame? get currentGame => _currentGame;
|
||
List<GameRecord> get records => _records;
|
||
|
||
/// 创建简化版游戏(使用颜色块而不是图片)
|
||
void createSimpleGame({
|
||
required GameDifficulty difficulty,
|
||
GameMode mode = GameMode.classic,
|
||
}) {
|
||
// 停止之前的计时器
|
||
_timer?.cancel();
|
||
|
||
// 创建颜色块拼图
|
||
final pieces = _createColorPieces(difficulty.gridSize);
|
||
|
||
// 打乱拼图
|
||
_shufflePieces(pieces, difficulty.gridSize);
|
||
|
||
// 创建游戏
|
||
_currentGame = PuzzleGame(
|
||
pieces: pieces,
|
||
difficulty: difficulty,
|
||
mode: mode,
|
||
emptyPosition: mode == GameMode.classic ? pieces.length - 1 : null,
|
||
);
|
||
|
||
// 开始计时
|
||
_startTimer();
|
||
|
||
notifyListeners();
|
||
}
|
||
|
||
/// 创建颜色块拼图(用于测试)
|
||
List<PuzzlePiece> _createColorPieces(int gridSize) {
|
||
final pieces = <PuzzlePiece>[];
|
||
final colors = [
|
||
Colors.red,
|
||
Colors.blue,
|
||
Colors.green,
|
||
Colors.orange,
|
||
Colors.purple,
|
||
Colors.pink,
|
||
Colors.teal,
|
||
Colors.amber,
|
||
Colors.indigo,
|
||
Colors.cyan,
|
||
Colors.lime,
|
||
Colors.brown,
|
||
Colors.grey,
|
||
Colors.deepOrange,
|
||
Colors.lightBlue,
|
||
Colors.lightGreen,
|
||
Colors.yellow,
|
||
Colors.deepPurple,
|
||
Colors.blueGrey,
|
||
Colors.redAccent,
|
||
Colors.greenAccent,
|
||
Colors.blueAccent,
|
||
Colors.orangeAccent,
|
||
Colors.purpleAccent,
|
||
Colors.pinkAccent,
|
||
Colors.tealAccent,
|
||
Colors.amberAccent,
|
||
Colors.indigoAccent,
|
||
Colors.cyanAccent,
|
||
Colors.limeAccent,
|
||
Colors.black87,
|
||
Colors.black54,
|
||
Colors.black45,
|
||
Colors.black38,
|
||
Colors.black26,
|
||
Colors.black12,
|
||
];
|
||
|
||
for (int i = 0; i < gridSize * gridSize; i++) {
|
||
pieces.add(
|
||
PuzzlePiece(
|
||
id: i,
|
||
correctPosition: i,
|
||
currentPosition: i,
|
||
image: _createColorImage(colors[i % colors.length], i + 1),
|
||
),
|
||
);
|
||
}
|
||
|
||
return pieces;
|
||
}
|
||
|
||
/// 创建颜色图片
|
||
ImageProvider _createColorImage(Color color, int number) {
|
||
// 这里返回一个简单的颜色图片
|
||
// 实际实现中可以使用Canvas绘制带数字的颜色块
|
||
return NetworkImage(
|
||
'https://via.placeholder.com/100x100/${color.value.toRadixString(16).substring(2)}/FFFFFF?text=$number',
|
||
);
|
||
}
|
||
|
||
/// 打乱拼图
|
||
void _shufflePieces(List<PuzzlePiece> pieces, int gridSize) {
|
||
final random = math.Random();
|
||
|
||
// 执行多次随机交换
|
||
for (int i = 0; i < pieces.length * 5; i++) {
|
||
final index1 = random.nextInt(pieces.length);
|
||
final index2 = random.nextInt(pieces.length);
|
||
|
||
final temp = pieces[index1].currentPosition;
|
||
pieces[index1].currentPosition = pieces[index2].currentPosition;
|
||
pieces[index2].currentPosition = temp;
|
||
}
|
||
}
|
||
|
||
/// 移动拼图块
|
||
void movePiece(int pieceIndex) {
|
||
if (_currentGame == null || _currentGame!.isComplete) return;
|
||
|
||
final piece = _currentGame!.pieces[pieceIndex];
|
||
final gridSize = _currentGame!.gridSize;
|
||
|
||
if (_currentGame!.mode == GameMode.classic) {
|
||
// 滑动模式:只能移动到空格
|
||
if (!_canMoveToEmpty(piece.currentPosition, gridSize)) return;
|
||
|
||
final emptyPos = _currentGame!.emptyPosition!;
|
||
piece.currentPosition = emptyPos;
|
||
_currentGame = _currentGame!.copyWith(emptyPosition: pieceIndex);
|
||
}
|
||
|
||
// 增加步数
|
||
_currentGame = _currentGame!.copyWith(moves: _currentGame!.moves + 1);
|
||
|
||
// 检查是否完成
|
||
if (_currentGame!.checkComplete()) {
|
||
_completeGame();
|
||
}
|
||
|
||
notifyListeners();
|
||
}
|
||
|
||
/// 交换两个拼图块(交换模式)
|
||
void swapPieces(int index1, int index2) {
|
||
if (_currentGame == null || _currentGame!.isComplete) return;
|
||
if (_currentGame!.mode == GameMode.classic) return;
|
||
|
||
final piece1 = _currentGame!.pieces[index1];
|
||
final piece2 = _currentGame!.pieces[index2];
|
||
|
||
final temp = piece1.currentPosition;
|
||
piece1.currentPosition = piece2.currentPosition;
|
||
piece2.currentPosition = temp;
|
||
|
||
_currentGame = _currentGame!.copyWith(moves: _currentGame!.moves + 1);
|
||
|
||
if (_currentGame!.checkComplete()) {
|
||
_completeGame();
|
||
}
|
||
|
||
notifyListeners();
|
||
}
|
||
|
||
/// 检查是否可以移动到空格
|
||
bool _canMoveToEmpty(int position, int gridSize) {
|
||
final emptyPos = _currentGame!.emptyPosition!;
|
||
final row = position ~/ gridSize;
|
||
final col = position % gridSize;
|
||
final emptyRow = emptyPos ~/ gridSize;
|
||
final emptyCol = emptyPos % gridSize;
|
||
|
||
// 检查是否相邻
|
||
return (row == emptyRow && (col - emptyCol).abs() == 1) ||
|
||
(col == emptyCol && (row - emptyRow).abs() == 1);
|
||
}
|
||
|
||
/// 开始计时
|
||
void _startTimer() {
|
||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||
if (_currentGame != null && !_currentGame!.isComplete) {
|
||
_currentGame = _currentGame!.copyWith(
|
||
elapsedTime: _currentGame!.elapsedTime + const Duration(seconds: 1),
|
||
);
|
||
notifyListeners();
|
||
}
|
||
});
|
||
}
|
||
|
||
/// 完成游戏
|
||
void _completeGame() {
|
||
_timer?.cancel();
|
||
_currentGame = _currentGame!.copyWith(isComplete: true);
|
||
|
||
// 保存记录
|
||
final record = GameRecord(
|
||
imageId: 'color_test',
|
||
difficulty: _currentGame!.difficulty,
|
||
time: _currentGame!.elapsedTime,
|
||
moves: _currentGame!.moves,
|
||
stars: _currentGame!.getStarRating(),
|
||
completedAt: DateTime.now(),
|
||
);
|
||
|
||
_records.add(record);
|
||
}
|
||
|
||
/// 重新开始游戏
|
||
void restartGame() {
|
||
if (_currentGame == null) return;
|
||
|
||
_timer?.cancel();
|
||
_shufflePieces(_currentGame!.pieces, _currentGame!.gridSize);
|
||
|
||
_currentGame = _currentGame!.copyWith(
|
||
moves: 0,
|
||
elapsedTime: Duration.zero,
|
||
isComplete: false,
|
||
);
|
||
|
||
_startTimer();
|
||
notifyListeners();
|
||
}
|
||
|
||
/// 使用提示
|
||
void useHint() {
|
||
if (_currentGame == null || _currentGame!.isComplete) return;
|
||
|
||
// 简单提示:找到第一个不在正确位置的块
|
||
for (int i = 0; i < _currentGame!.pieces.length; i++) {
|
||
final piece = _currentGame!.pieces[i];
|
||
if (!piece.isCorrect) {
|
||
// 这里可以添加高亮显示逻辑
|
||
print('提示:块 ${piece.id} 应该在位置 ${piece.correctPosition}');
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_timer?.cancel();
|
||
super.dispose();
|
||
}
|
||
}
|