132 lines
4.0 KiB
TypeScript
132 lines
4.0 KiB
TypeScript
|
|
import { sys } from "cc";
|
|||
|
|
import { LevelConfig } from "./LevelBuilder";
|
|||
|
|
import { BoardShapeName } from "./BoardShape";
|
|||
|
|
|
|||
|
|
export class LevelManager {
|
|||
|
|
private static _instance: LevelManager;
|
|||
|
|
public static get instance() {
|
|||
|
|
if (!this._instance) this._instance = new LevelManager();
|
|||
|
|
return this._instance;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private levelIndex: number = 0;
|
|||
|
|
private unlockedLevels: number = 1; // 已解锁关卡数
|
|||
|
|
private STORAGE_KEY = "MY_GAME_PROGRESS";
|
|||
|
|
private TUTORIAL_KEY = "TUTORIAL_COMPLETED";
|
|||
|
|
|
|||
|
|
// 预设关卡配置表(可以继续扩展) //rectangle L_shape T_shape cross_shape
|
|||
|
|
private levels: LevelConfig[] = [
|
|||
|
|
{ currentShape: "rectangle", blockSize: 100, tileTypes: 5 },
|
|||
|
|
{ currentShape: "L_shape", blockSize: 90, tileTypes: 4 },
|
|||
|
|
{ currentShape: "T_shape", blockSize: 80, tileTypes: 3 },
|
|||
|
|
{ currentShape: "cross_shape", blockSize: 70, tileTypes: 3 },
|
|||
|
|
{ currentShape: "diamond", blockSize: 80, tileTypes: 4 },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
constructor() {
|
|||
|
|
this.loadProgress();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public isTutorialCompleted(): boolean {
|
|||
|
|
return sys.localStorage.getItem(this.TUTORIAL_KEY) === "true";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public setTutorialCompleted() {
|
|||
|
|
sys.localStorage.setItem(this.TUTORIAL_KEY, "true");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public getTutorialLevel(): LevelConfig {
|
|||
|
|
return {
|
|||
|
|
isTutorial: true,
|
|||
|
|
tileTypes: 2,
|
|||
|
|
blockSize: 120,
|
|||
|
|
fixedBoard: [
|
|||
|
|
[0, 0, -1],
|
|||
|
|
[1, -1, 1]
|
|||
|
|
]
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public getCurrentLevel(): LevelConfig {
|
|||
|
|
if (!this.isTutorialCompleted()) {
|
|||
|
|
return this.getTutorialLevel();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (this.levelIndex < this.levels.length) {
|
|||
|
|
return this.levels[this.levelIndex];
|
|||
|
|
}
|
|||
|
|
console.log('随机关卡')
|
|||
|
|
return this.generateRandomLevel(this.levelIndex + 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public nextLevel(): LevelConfig | null {
|
|||
|
|
if (!this.isTutorialCompleted()) {
|
|||
|
|
this.setTutorialCompleted();
|
|||
|
|
this.levelIndex = 0;
|
|||
|
|
this.saveProgress();
|
|||
|
|
return this.getCurrentLevel();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.levelIndex++;
|
|||
|
|
this.saveProgress();
|
|||
|
|
return this.getCurrentLevel();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public reset() {
|
|||
|
|
this.levelIndex = 0;
|
|||
|
|
this.unlockedLevels = 1;
|
|||
|
|
this.saveProgress();
|
|||
|
|
// 重置时是否重置教学?通常不用,除非显式清除数据
|
|||
|
|
// sys.localStorage.removeItem(this.TUTORIAL_KEY);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 本地存储进度 */
|
|||
|
|
private saveProgress() {
|
|||
|
|
const data = {
|
|||
|
|
levelIndex: this.levelIndex,
|
|||
|
|
unlockedLevels: this.unlockedLevels,
|
|||
|
|
};
|
|||
|
|
sys.localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 读取本地存储 */
|
|||
|
|
private loadProgress() {
|
|||
|
|
const json = sys.localStorage.getItem(this.STORAGE_KEY);
|
|||
|
|
if (json) {
|
|||
|
|
try {
|
|||
|
|
const data = JSON.parse(json);
|
|||
|
|
this.levelIndex = data.levelIndex ?? 0;
|
|||
|
|
this.unlockedLevels = data.unlockedLevels ?? 1;
|
|||
|
|
|
|||
|
|
// 如果是老玩家(已解锁超过1关),跳过教学
|
|||
|
|
if (this.unlockedLevels > 1 && !this.isTutorialCompleted()) {
|
|||
|
|
this.setTutorialCompleted();
|
|||
|
|
}
|
|||
|
|
} catch (e) {
|
|||
|
|
console.warn("进度解析失败, 重置进度");
|
|||
|
|
this.reset();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private generateRandomLevel(id: number): LevelConfig {
|
|||
|
|
const allShapes: BoardShapeName[] = ["rectangle", "L_shape", "T_shape", "cross_shape", "diamond"];
|
|||
|
|
|
|||
|
|
// 随机选一个形状
|
|||
|
|
const shape = allShapes[Math.floor(Math.random() * allShapes.length)];
|
|||
|
|
|
|||
|
|
// 随机决定方块种类 (6~12)
|
|||
|
|
const tileTypes = 5;
|
|||
|
|
// const tileTypes = 6 + Math.floor(Math.random() * 7);
|
|||
|
|
|
|||
|
|
// 随机大小 (70~100)
|
|||
|
|
const blockSize = 70 + Math.floor(Math.random() * 31);
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
currentShape: shape,
|
|||
|
|
tileTypes,
|
|||
|
|
blockSize,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|