Parcourir la source

返回主界面

181404010226 il y a 6 mois
Parent
commit
5004f3b07d

Fichier diff supprimé car celui-ci est trop grand
+ 316 - 317
assets/Scenes/GameLevel.scene


+ 12 - 1
assets/scripts/CombatSystem/BlockManager.ts

@@ -43,7 +43,7 @@ export class BlockManager extends Component {
     @property({
         tooltip: '游戏开始后方块移动的冷却时间(秒)'
     })
-    public blockMoveCooldown: number = 10;
+    public blockMoveCooldown: number = 1;
     
     // 玩家金币数量
     private playerCoins: number = 699;
@@ -987,9 +987,20 @@ export class BlockManager extends Component {
         const worldPosition = new Vec3();
         block.getWorldPosition(worldPosition);
         
+        // 移除旧的触摸事件监听器
+        block.off(Node.EventType.TOUCH_START);
+        block.off(Node.EventType.TOUCH_MOVE);
+        block.off(Node.EventType.TOUCH_END);
+        block.off(Node.EventType.TOUCH_CANCEL);
+        
         block.removeFromParent();
         this.placedBlocksContainer.addChild(block);
         block.setWorldPosition(worldPosition);
+        
+        // 重新设置触摸事件监听器
+        this.setupDragEvents(block);
+        
+        console.log(`方块 ${block.name} 已移动到PlacedBlocks容器,并重新设置了触摸事件`);
     }
     
     // 根据武器配置选择合适的预制体

+ 8 - 8
assets/scripts/Core/PhysicsManager.ts

@@ -22,14 +22,14 @@ export class PhysicsManager extends BaseSingleton {
         // 设置物理系统的重力为零(因为是2D平面游戏)
         PhysicsSystem2D.instance.gravity = new Vec2(0, 0);
         
-        // 调试绘制
-        PhysicsSystem2D.instance.debugDrawFlags = this.debugDraw ?
-            (EPhysics2DDrawFlags.Aabb |
-             EPhysics2DDrawFlags.Pair |
-             EPhysics2DDrawFlags.CenterOfMass |
-             EPhysics2DDrawFlags.Joint |
-             EPhysics2DDrawFlags.Shape) :
-            EPhysics2DDrawFlags.None;
+        // // // 调试绘制
+        // PhysicsSystem2D.instance.debugDrawFlags = this.debugDraw ?
+        //     (EPhysics2DDrawFlags.Aabb |
+        //      EPhysics2DDrawFlags.Pair |
+        //      EPhysics2DDrawFlags.CenterOfMass |
+        //      EPhysics2DDrawFlags.Joint |
+        //      EPhysics2DDrawFlags.Shape) :
+        //     EPhysics2DDrawFlags.None;
     }
 
     /**

+ 237 - 42
assets/scripts/LevelSystem/GameManager.ts

@@ -1,6 +1,7 @@
 import { _decorator, Component, Node, Prefab, instantiate, Vec3, find, director, Canvas, UITransform, Button, Label, EPhysics2DDrawFlags, sys } from 'cc';
 import { LevelManager } from './LevelManager';
 import { LevelConfigManager } from './LevelConfigManager';
+import { SaveDataManager } from './SaveDataManager';
 import { ShopManager } from '../ShopSystem/ShopManager';
 import { ConfigManager } from '../Core/ConfigManager';
 import { EnemyController } from '../CombatSystem/EnemyController';
@@ -108,6 +109,7 @@ export class GameManager extends Component {
     private enemyController: EnemyController = null;
     private levelManager: LevelManager = null;
     private levelConfigManager: LevelConfigManager = null;
+    private saveDataManager: SaveDataManager = null;
     private shopManager: ShopManager = null;
     private configManager: ConfigManager = null;
     private enemySpawningStarted: boolean = false;
@@ -115,6 +117,10 @@ export class GameManager extends Component {
     private currentWave: number = 1;
     private currentWaveEnemyCount: number = 0;
     private currentWaveTotalEnemies: number = 0; // 当前波次总敌人数
+    
+    // 游戏计时器
+    private gameStartTime: number = 0;
+    private gameEndTime: number = 0;
 
     // 游戏区域的边界
     private gameBounds = {
@@ -168,6 +174,11 @@ export class GameManager extends Component {
             this.checkTimer = 0;
             this.checkGameState();
         }
+        
+        // 检查自动保存
+        if (this.saveDataManager) {
+            this.saveDataManager.checkAutoSave();
+        }
     }
 
     // === 物理系统初始化 ===
@@ -180,14 +191,6 @@ export class GameManager extends Component {
             pm = physicsNode.addComponent(PhysicsManager);
         }
 
-        const physics = pm.getSystem();
-
-        // 额外调试配置(可根据需要在编辑器暴露开关)
-        physics.debugDrawFlags = EPhysics2DDrawFlags.Aabb |
-                                 EPhysics2DDrawFlags.Pair |
-                                 EPhysics2DDrawFlags.CenterOfMass |
-                                 EPhysics2DDrawFlags.Joint |
-                                 EPhysics2DDrawFlags.Shape;
     }
 
     // === 管理器初始化 ===
@@ -197,6 +200,10 @@ export class GameManager extends Component {
         this.configManager = ConfigManager.getInstance();
         this.levelConfigManager = LevelConfigManager.getInstance();
         this.enemyController = EnemyController.getInstance() || null;
+        
+        // 初始化存档管理器
+        this.saveDataManager = SaveDataManager.getInstance();
+        this.saveDataManager.initialize();
     }
 
     // === 游戏状态初始化 ===
@@ -491,32 +498,124 @@ export class GameManager extends Component {
     // === 游戏失败回调 ===
     private onGameDefeat() {
         console.log('处理游戏失败逻辑');
+        this.gameEndTime = Date.now();
+        
+        // 记录游戏失败到存档
+        if (this.saveDataManager) {
+            const currentLevel = this.saveDataManager.getCurrentLevel();
+            this.saveDataManager.failLevel(currentLevel);
+            
+            // 更新统计数据
+            this.saveDataManager.updateStatistic('totalTimePlayed', this.getGameDuration());
+        }
     }
 
     // === 游戏成功回调 ===
     private onGameSuccess() {
         console.log('处理游戏成功逻辑');
+        this.gameEndTime = Date.now();
+        
         this.giveReward();
         this.onLevelComplete();
     }
 
     // === 给予奖励 ===
     private giveReward() {
-        if (!this.shopManager) return;
+        if (!this.saveDataManager) return;
 
-        const baseReward = 100;
+        const currentLevel = this.saveDataManager.getCurrentLevel();
+        const baseReward = currentLevel * 50;
         const healthBonus = Math.floor(this.currentHealth * 0.1);
-        const totalReward = baseReward + healthBonus;
+        const timeBonus = this.calculateTimeBonus();
+        const totalCoins = baseReward + healthBonus + timeBonus;
         
-        this.shopManager.addCoins(totalReward);
+        // 给予金币奖励
+        this.saveDataManager.addCoins(totalCoins, `level_${currentLevel}_complete`);
+        
+        // 如果是首次完成,给予额外奖励
+        if (!this.saveDataManager.isLevelCompleted(currentLevel)) {
+            const firstClearBonus = currentLevel * 25;
+            this.saveDataManager.addCoins(firstClearBonus, `level_${currentLevel}_first_clear`);
+        }
+        
+        console.log(`🎉 关卡奖励:金币 +${totalCoins},健康奖励 +${healthBonus},时间奖励 +${timeBonus}`);
     }
 
     // === 处理关卡完成 ===
     private onLevelComplete(score: number = 0, stars: number = 1) {
+        if (!this.saveDataManager) return;
+        
+        const currentLevel = this.saveDataManager.getCurrentLevel();
+        const gameTime = this.getGameDuration();
+        
+        // 计算得分(基于剩余血量、用时等)
+        const calculatedScore = this.calculateScore();
+        const finalScore = Math.max(score, calculatedScore);
+        
+        // 计算星级(基于表现)
+        const calculatedStars = this.calculateStars();
+        const finalStars = Math.max(stars, calculatedStars);
+        
+        // 记录关卡完成到存档
+        this.saveDataManager.completeLevel(currentLevel, finalScore, gameTime, finalStars);
+        
+        // 更新统计数据
+        this.saveDataManager.updateStatistic('totalTimePlayed', gameTime);
+        this.saveDataManager.updateStatistic('totalEnemiesDefeated', this.totalEnemiesSpawned);
+        
+        console.log(`🏆 关卡 ${currentLevel} 完成!得分: ${finalScore}, 星级: ${finalStars}, 用时: ${gameTime}秒`);
+        
+        // 兼容原有的LevelManager
         if (this.levelManager) {
-            const currentLevel = this.levelManager.getCurrentLevel();
-            this.levelManager.completeLevel(currentLevel, score, stars);
+            this.levelManager.completeLevel(currentLevel, finalScore, finalStars);
+        }
+    }
+    
+    // === 计算游戏时长 ===
+    private getGameDuration(): number {
+        if (this.gameStartTime === 0) return 0;
+        const endTime = this.gameEndTime || Date.now();
+        return Math.floor((endTime - this.gameStartTime) / 1000);
+    }
+    
+    // === 计算时间奖励 ===
+    private calculateTimeBonus(): number {
+        const gameTime = this.getGameDuration();
+        if (gameTime === 0) return 0;
+        
+        // 时间越短奖励越多,最多额外50%奖励
+        const maxTime = 300; // 5分钟
+        const timeRatio = Math.max(0, (maxTime - gameTime) / maxTime);
+        const baseReward = this.saveDataManager.getCurrentLevel() * 50;
+        return Math.floor(baseReward * timeRatio * 0.5);
+    }
+    
+    // === 计算得分 ===
+    private calculateScore(): number {
+        const currentLevel = this.saveDataManager?.getCurrentLevel() || 1;
+        const baseScore = currentLevel * 1000;
+        const healthScore = this.currentHealth * 10;
+        const enemyScore = this.totalEnemiesSpawned * 50;
+        const timeScore = this.calculateTimeBonus();
+        
+        return baseScore + healthScore + enemyScore + timeScore;
+    }
+    
+    // === 计算星级 ===
+    private calculateStars(): number {
+        const healthRatio = this.currentHealth / this.initialHealth;
+        const gameTime = this.getGameDuration();
+        
+        // 基于血量剩余和用时计算星级
+        if (healthRatio >= 0.8 && gameTime <= 120) {
+            return 3; // 3星:血量80%以上,2分钟内完成
+        } else if (healthRatio >= 0.5 && gameTime <= 300) {
+            return 2; // 2星:血量50%以上,5分钟内完成
+        } else if (healthRatio > 0) {
+            return 1; // 1星:只要完成就有1星
         }
+        
+        return 1;
     }
 
     // === 设置UI按钮 ===
@@ -602,16 +701,49 @@ export class GameManager extends Component {
     }
 
     // === 按钮点击事件处理 ===
-    private onNextLevelClick() {
-        if (this.levelManager) {
-            const currentLevel = this.levelManager.getCurrentLevel();
-            const nextLevel = currentLevel + 1;
-            
-            if (this.levelManager.isLevelUnlocked(nextLevel)) {
-                this.levelManager.setCurrentLevel(nextLevel);
-                this.restartCurrentLevel();
-            }
+    private async onNextLevelClick() {
+        if (!this.saveDataManager) {
+            console.warn('SaveDataManager 未初始化');
+            return;
+        }
+
+        const currentLevel = this.saveDataManager.getCurrentLevel();
+        const nextLevel = currentLevel + 1;
+
+        if (!this.saveDataManager.isLevelUnlocked(nextLevel)) {
+            console.log('下一关卡尚未解锁');
+            return;
         }
+
+        // 设置当前关卡为下一关
+        this.saveDataManager.getPlayerData().currentLevel = nextLevel;
+        this.saveDataManager.savePlayerData();
+
+        // 隐藏结算面板
+        if (this.gameSuccessUI) this.gameSuccessUI.active = false;
+        if (this.gameDefeatUI) this.gameDefeatUI.active = false;
+
+        // 停止并清理敌人
+        if (this.enemyController) {
+            this.enemyController.stopGame();
+            this.enemyController.clearAllEnemies();
+        }
+
+        // 重置方块、子弹等(通过 BlockManager)
+        const blockManager = find('Canvas/GameLevelUI')?.getComponent('BlockManager');
+        if (blockManager) {
+            if (blockManager['clearBlocks']) blockManager['clearBlocks']();
+            if (blockManager['onGameReset']) blockManager['onGameReset']();
+        }
+
+        // 重置内部状态
+        this.restartGame();
+
+        // 加载并应用新关卡配置
+        await this.loadCurrentLevelConfig();
+
+        // 直接开始游戏(如果需要再次确认,可移除此行)
+        this.startGame();
     }
 
     private onRestartClick() {
@@ -619,19 +751,44 @@ export class GameManager extends Component {
     }
 
     private onMainMenuClick() {
+        // 保存数据
+        if (this.saveDataManager) {
+            this.saveDataManager.savePlayerData(true);
+        }
+
+        // 隐藏结算面板
+        if (this.gameSuccessUI) this.gameSuccessUI.active = false;
+        if (this.gameDefeatUI) this.gameDefeatUI.active = false;
+
+        // 停止并清理游戏内容
+        if (this.enemyController) {
+            this.enemyController.stopGame();
+            this.enemyController.clearAllEnemies();
+        }
         this.restartGame();
+
+        // UI 切换:隐藏关卡界面,显示主界面
+        const mainUI = find('Canvas/MainUI');
+        const gameLevelUI = find('Canvas/GameLevelUI');
+        if (mainUI) mainUI.active = true;
+        if (gameLevelUI) gameLevelUI.active = false;
+
+        console.log('返回主界面');
     }
 
     private onShopClick() {
-        // 可以在这里实现商店界面逻辑
+        console.log('打开商店');
     }
 
     private onReviveClick() {
-        const reviveCost = 5;
-        
-        if (this.shopManager && this.shopManager.getGems() >= reviveCost) {
-            if (this.shopManager.spendGems(reviveCost)) {
+        // 消费钻石复活
+        if (this.saveDataManager) {
+            const reviveCost = 10; // 复活需要10钻石
+            if (this.saveDataManager.spendDiamonds(reviveCost)) {
                 this.revivePlayer();
+                console.log(`💎 消费 ${reviveCost} 钻石复活`);
+            } else {
+                console.log('钻石不足,无法复活');
             }
         }
     }
@@ -676,12 +833,20 @@ export class GameManager extends Component {
     }
 
     public startGame() {
-        if (this.gameStarted) return;
-        
         this.gameStarted = true;
+        this.gameStartTime = Date.now();
+        this.gameEndTime = 0;
         this.currentState = GameState.PLAYING;
-
+        
+        // 通知BlockManager游戏开始
+        const blockManager = find('Canvas/GameLevelUI')?.getComponent('BlockManager');
+        if (blockManager && blockManager['onGameStart']) {
+            blockManager['onGameStart']();
+        }
+        
         this.spawnBall();
+        
+        console.log('🎮 游戏开始!');
 
         if (this.enemyController) {
             this.enemyController.startGame();
@@ -732,8 +897,20 @@ export class GameManager extends Component {
     }
 
     public restartGame() {
-        this.initializeGameState();
-        this.resumeGame();
+        this.currentState = GameState.PLAYING;
+        this.gameStarted = false;
+        this.gameStartTime = 0;
+        this.gameEndTime = 0;
+        this.currentHealth = this.initialHealth;
+        this.totalEnemiesSpawned = 0;
+        this.currentWave = 1;
+        this.currentWaveEnemyCount = 0;
+        
+        // 通知BlockManager游戏重置
+        const blockManager = find('Canvas/GameLevelUI')?.getComponent('BlockManager');
+        if (blockManager && blockManager['onGameReset']) {
+            blockManager['onGameReset']();
+        }
     }
 
     public isGameOver(): boolean {
@@ -856,12 +1033,16 @@ export class GameManager extends Component {
 
     // === 加载当前关卡配置 ===
     public async loadCurrentLevelConfig() {
-        if (!this.levelManager || !this.levelConfigManager) {
+        if (!this.levelConfigManager) {
             return null;
         }
 
         try {
-            const currentLevel = this.levelManager.getCurrentLevel();
+            // 优先使用存档系统的关卡信息
+            const currentLevel = this.saveDataManager ? 
+                this.saveDataManager.getCurrentLevel() : 
+                (this.levelManager ? this.levelManager.getCurrentLevel() : 1);
+                
             console.log(`加载关卡 ${currentLevel} 配置`);
             
             const levelConfig = await this.levelConfigManager.getLevelConfig(currentLevel);
@@ -922,18 +1103,32 @@ export class GameManager extends Component {
 
     // === 获取当前关卡信息 ===
     public async getCurrentLevelInfo() {
-        if (!this.levelManager) {
-            return null;
-        }
-
-        const currentLevel = this.levelManager.getCurrentLevel();
-        const levelData = this.levelManager.getLevelData(currentLevel);
+        const currentLevel = this.saveDataManager ? 
+            this.saveDataManager.getCurrentLevel() : 
+            (this.levelManager ? this.levelManager.getCurrentLevel() : 1);
+            
+        const levelProgress = this.saveDataManager ? 
+            this.saveDataManager.getLevelProgress(currentLevel) : null;
+            
+        const levelData = this.levelManager ? 
+            this.levelManager.getLevelData(currentLevel) : null;
+            
         const levelConfig = await this.loadCurrentLevelConfig();
 
         return {
             level: currentLevel,
+            maxUnlockedLevel: this.saveDataManager ? 
+                this.saveDataManager.getMaxUnlockedLevel() : 
+                (this.levelManager ? this.levelManager.getMaxUnlockedLevel() : 1),
+            progress: levelProgress,
             data: levelData,
-            config: levelConfig
+            config: levelConfig,
+            playerData: this.saveDataManager ? {
+                coins: this.saveDataManager.getCoins(),
+                diamonds: this.saveDataManager.getDiamonds(),
+                gems: this.saveDataManager.getGems(),
+                playerLevel: this.saveDataManager.getPlayerLevel()
+            } : null
         };
     }
 

+ 384 - 0
assets/scripts/LevelSystem/MainUIController.ts

@@ -0,0 +1,384 @@
+import { _decorator, Component, Node, Label, Button, find } from 'cc';
+import { SaveDataManager } from './SaveDataManager';
+import { GameManager } from './GameManager';
+const { ccclass, property } = _decorator;
+
+/**
+ * 主界面控制器
+ * 负责显示玩家信息和处理主界面交互
+ */
+@ccclass('MainUIController')
+export class MainUIController extends Component {
+    
+    @property({
+        type: Node,
+        tooltip: '玩家等级显示节点'
+    })
+    public playerLevelLabel: Node = null;
+    
+    @property({
+        type: Node,
+        tooltip: '当前关卡显示节点'
+    })
+    public currentLevelLabel: Node = null;
+    
+    @property({
+        type: Node,
+        tooltip: '金币显示节点'
+    })
+    public coinsLabel: Node = null;
+    
+    @property({
+        type: Node,
+        tooltip: '钻石显示节点'
+    })
+    public diamondsLabel: Node = null;
+    
+    @property({
+        type: Node,
+        tooltip: '宝石显示节点'
+    })
+    public gemsLabel: Node = null;
+    
+    @property({
+        type: Node,
+        tooltip: '战斗按钮节点'
+    })
+    public battleButton: Node = null;
+    
+    @property({
+        type: Node,
+        tooltip: '商店按钮节点'
+    })
+    public shopButton: Node = null;
+    
+    @property({
+        type: Node,
+        tooltip: '设置按钮节点'
+    })
+    public settingsButton: Node = null;
+    
+    private saveDataManager: SaveDataManager = null;
+    
+    start() {
+        // 初始化存档管理器
+        this.saveDataManager = SaveDataManager.getInstance();
+        this.saveDataManager.initialize();
+        
+        // 自动查找UI节点(如果没有手动拖拽设置)
+        this.findUINodes();
+        
+        // 更新UI显示
+        this.updateUI();
+        
+        // 设置按钮事件
+        this.setupButtons();
+        
+        console.log('🏠 主界面初始化完成');
+        console.log('存档摘要:', this.saveDataManager.getSaveSummary());
+    }
+    
+    /**
+     * 自动查找UI节点
+     */
+    private findUINodes() {
+        if (!this.playerLevelLabel) {
+            this.playerLevelLabel = find('Canvas/MainUI/PlayerInfo/LevelLabel');
+        }
+        
+        if (!this.currentLevelLabel) {
+            this.currentLevelLabel = find('Canvas/MainUI/LevelInfo/CurrentLevelLabel');
+        }
+        
+        if (!this.coinsLabel) {
+            this.coinsLabel = find('Canvas/MainUI/Currency/CoinsLabel');
+        }
+        
+        if (!this.diamondsLabel) {
+            this.diamondsLabel = find('Canvas/MainUI/Currency/DiamondsLabel');
+        }
+        
+        if (!this.gemsLabel) {
+            this.gemsLabel = find('Canvas/MainUI/Currency/GemsLabel');
+        }
+        
+        if (!this.battleButton) {
+            this.battleButton = find('Canvas/MainUI/BattleButtonNode');
+        }
+        
+        if (!this.shopButton) {
+            this.shopButton = find('Canvas/MainUI/ShopButton');
+        }
+        
+        if (!this.settingsButton) {
+            this.settingsButton = find('Canvas/MainUI/SettingsButton');
+        }
+    }
+    
+    /**
+     * 更新UI显示
+     */
+    public updateUI() {
+        if (!this.saveDataManager) return;
+        
+        // 更新玩家等级显示
+        if (this.playerLevelLabel) {
+            const label = this.playerLevelLabel.getComponent(Label);
+            if (label) {
+                const playerLevel = this.saveDataManager.getPlayerLevel();
+                label.string = `Lv.${playerLevel}`;
+            }
+        }
+        
+        // 更新当前关卡显示
+        if (this.currentLevelLabel) {
+            const label = this.currentLevelLabel.getComponent(Label);
+            if (label) {
+                const currentLevel = this.saveDataManager.getCurrentLevel();
+                const maxUnlocked = this.saveDataManager.getMaxUnlockedLevel();
+                label.string = `关卡 ${currentLevel} (最高 ${maxUnlocked})`;
+            }
+        }
+        
+        // 更新货币显示
+        this.updateCurrencyDisplay();
+        
+        // 更新按钮状态
+        this.updateButtonStates();
+    }
+    
+    /**
+     * 更新货币显示
+     */
+    private updateCurrencyDisplay() {
+        if (!this.saveDataManager) return;
+        
+        // 金币
+        if (this.coinsLabel) {
+            const label = this.coinsLabel.getComponent(Label);
+            if (label) {
+                const coins = this.saveDataManager.getCoins();
+                label.string = this.formatNumber(coins);
+            }
+        }
+        
+        // 钻石
+        if (this.diamondsLabel) {
+            const label = this.diamondsLabel.getComponent(Label);
+            if (label) {
+                const diamonds = this.saveDataManager.getDiamonds();
+                label.string = this.formatNumber(diamonds);
+            }
+        }
+        
+        // 宝石
+        if (this.gemsLabel) {
+            const label = this.gemsLabel.getComponent(Label);
+            if (label) {
+                const gems = this.saveDataManager.getGems();
+                label.string = this.formatNumber(gems);
+            }
+        }
+    }
+    
+    /**
+     * 更新按钮状态
+     */
+    private updateButtonStates() {
+        // 这里可以根据玩家状态启用/禁用某些按钮
+        // 例如:如果没有解锁某些功能,可以禁用相应按钮
+    }
+    
+    /**
+     * 设置按钮事件
+     */
+    private setupButtons() {
+        // 战斗按钮
+        if (this.battleButton) {
+            const button = this.battleButton.getComponent(Button);
+            if (button) {
+                button.node.on(Button.EventType.CLICK, this.onBattleButtonClick, this);
+            }
+        }
+        
+        // 商店按钮
+        if (this.shopButton) {
+            const button = this.shopButton.getComponent(Button);
+            if (button) {
+                button.node.on(Button.EventType.CLICK, this.onShopButtonClick, this);
+            }
+        }
+        
+        // 设置按钮
+        if (this.settingsButton) {
+            const button = this.settingsButton.getComponent(Button);
+            if (button) {
+                button.node.on(Button.EventType.CLICK, this.onSettingsButtonClick, this);
+            }
+        }
+    }
+    
+    /**
+     * 战斗按钮点击事件
+     */
+    private onBattleButtonClick() {
+        console.log('🎮 进入战斗!');
+        // 保存数据
+        if (this.saveDataManager) {
+            this.saveDataManager.savePlayerData();
+        }
+
+        // 切换 UI:隐藏主界面,显示关卡界面
+        const mainUI = find('Canvas/MainUI');
+        const gameLevelUI = find('Canvas/GameLevelUI');
+        if (mainUI) mainUI.active = false;
+        if (gameLevelUI) gameLevelUI.active = true;
+
+        // 重置并加载关卡
+        const gmNode = find('Canvas/GameLevelUI/GameManager');
+        if (gmNode) {
+            const gm = gmNode.getComponent(GameManager);
+            if (gm) {
+                gm.restartGame();          // 清理上一局数据
+                gm.loadCurrentLevelConfig(); // 加载当前(或下一)关配置
+            }
+        }
+    }
+    
+    /**
+     * 商店按钮点击事件
+     */
+    private onShopButtonClick() {
+        console.log('🛒 打开商店');
+        // UI 切换:隐藏主界面,显示商城界面(如果存在)
+        const mainUI = find('Canvas/MainUI');
+        const shopUI = find('Canvas/ShopUI');
+        if (mainUI) mainUI.active = false;
+        if (shopUI) {
+            shopUI.active = true;
+        } else {
+            console.warn('未找到商城界面节点 Canvas/ShopUI');
+        }
+    }
+    
+    /**
+     * 设置按钮点击事件
+     */
+    private onSettingsButtonClick() {
+        console.log('⚙️ 打开设置');
+        // 这里可以打开设置界面
+    }
+    
+    /**
+     * 显示当前关卡信息(调试用)
+     */
+    private showCurrentLevelInfo() {
+        if (!this.saveDataManager) return;
+        
+        const currentLevel = this.saveDataManager.getCurrentLevel();
+        const progress = this.saveDataManager.getLevelProgress(currentLevel);
+        const isCompleted = this.saveDataManager.isLevelCompleted(currentLevel);
+        const isUnlocked = this.saveDataManager.isLevelUnlocked(currentLevel);
+        
+        console.log('=== 当前关卡信息 ===');
+        console.log(`关卡: ${currentLevel}`);
+        console.log(`已解锁: ${isUnlocked}`);
+        console.log(`已完成: ${isCompleted}`);
+        
+        if (progress) {
+            console.log(`最佳得分: ${progress.bestScore}`);
+            console.log(`最佳时间: ${progress.bestTime}秒`);
+            console.log(`星级: ${progress.stars}`);
+            console.log(`尝试次数: ${progress.attempts}`);
+        }
+    }
+    
+    /**
+     * 格式化数字显示
+     */
+    private formatNumber(num: number): string {
+        if (num >= 1000000) {
+            return (num / 1000000).toFixed(1) + 'M';
+        } else if (num >= 1000) {
+            return (num / 1000).toFixed(1) + 'K';
+        }
+        return num.toString();
+    }
+    
+    /**
+     * 添加货币(用于测试)
+     */
+    public addTestCoins(amount: number = 1000) {
+        if (this.saveDataManager) {
+            this.saveDataManager.addCoins(amount, 'test');
+            this.updateUI();
+        }
+    }
+    
+    /**
+     * 添加钻石(用于测试)
+     */
+    public addTestDiamonds(amount: number = 100) {
+        if (this.saveDataManager) {
+            this.saveDataManager.addDiamonds(amount, 'test');
+            this.updateUI();
+        }
+    }
+    
+    /**
+     * 解锁关卡(用于测试)
+     */
+    public unlockLevel(level: number) {
+        if (this.saveDataManager) {
+            const playerData = this.saveDataManager.getPlayerData();
+            if (level > playerData.maxUnlockedLevel) {
+                playerData.maxUnlockedLevel = level;
+                this.saveDataManager.savePlayerData();
+                this.updateUI();
+                console.log(`🔓 解锁关卡 ${level}`);
+            }
+        }
+    }
+    
+    /**
+     * 重置存档(用于测试)
+     */
+    public resetSaveData() {
+        if (this.saveDataManager) {
+            this.saveDataManager.resetAllData();
+            this.updateUI();
+            console.log('🔄 存档已重置');
+        }
+    }
+    
+    /**
+     * 获取存档管理器(供其他脚本使用)
+     */
+    public getSaveDataManager(): SaveDataManager {
+        return this.saveDataManager;
+    }
+    
+    onDestroy() {
+        // 清理按钮事件
+        if (this.battleButton) {
+            const button = this.battleButton.getComponent(Button);
+            if (button) {
+                button.node.off(Button.EventType.CLICK, this.onBattleButtonClick, this);
+            }
+        }
+        
+        if (this.shopButton) {
+            const button = this.shopButton.getComponent(Button);
+            if (button) {
+                button.node.off(Button.EventType.CLICK, this.onShopButtonClick, this);
+            }
+        }
+        
+        if (this.settingsButton) {
+            const button = this.settingsButton.getComponent(Button);
+            if (button) {
+                button.node.off(Button.EventType.CLICK, this.onSettingsButtonClick, this);
+            }
+        }
+    }
+} 

+ 9 - 0
assets/scripts/LevelSystem/MainUIController.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "725f5db8-abb6-4a81-8702-b08eb87709fd",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 287 - 0
assets/scripts/LevelSystem/README_SaveSystem.md

@@ -0,0 +1,287 @@
+# 游戏存档系统使用说明
+
+## 概述
+
+本存档系统为Pong游戏提供完整的玩家进度保存和管理功能,记录玩家的关卡进度、货币、道具、统计数据等信息。
+
+## 主要功能
+
+### 1. 玩家数据管理
+- **基本信息**:玩家ID、姓名、创建时间、游戏时长等
+- **等级系统**:玩家等级、经验值、升级奖励
+- **货币系统**:金币、钻石、宝石的获得和消费
+- **关卡进度**:当前关卡、最高解锁关卡、各关卡完成情况
+
+### 2. 关卡进度记录
+- 关卡完成状态
+- 最佳得分和用时
+- 星级评价
+- 尝试次数
+- 首次通关时间
+
+### 3. 道具和装备系统
+- 武器收集和升级
+- 道具背包管理
+- 材料存储
+
+### 4. 统计数据
+- 游戏次数、胜负记录
+- 总得分、击败敌人数量
+- 游戏时长、连胜记录等
+
+### 5. 设置管理
+- 音效、音乐设置
+- 画质、语言设置
+- 自动保存等功能设置
+
+## 使用方法
+
+### 基本使用
+
+```typescript
+// 获取存档管理器实例
+const saveManager = SaveDataManager.getInstance();
+saveManager.initialize();
+
+// 获取玩家信息
+const playerLevel = saveManager.getPlayerLevel();
+const currentLevel = saveManager.getCurrentLevel();
+const coins = saveManager.getCoins();
+
+// 完成关卡
+saveManager.completeLevel(levelId, score, time, stars);
+
+// 添加货币
+saveManager.addCoins(amount, 'level_complete');
+saveManager.addDiamonds(amount, 'daily_reward');
+```
+
+### 在GameManager中集成
+
+```typescript
+// 在GameManager中初始化
+private saveDataManager: SaveDataManager = null;
+
+start() {
+    this.saveDataManager = SaveDataManager.getInstance();
+    this.saveDataManager.initialize();
+}
+
+// 游戏成功时
+private onGameSuccess() {
+    const currentLevel = this.saveDataManager.getCurrentLevel();
+    const score = this.calculateScore();
+    const time = this.getGameDuration();
+    const stars = this.calculateStars();
+    
+    this.saveDataManager.completeLevel(currentLevel, score, time, stars);
+}
+
+// 游戏失败时
+private onGameDefeat() {
+    const currentLevel = this.saveDataManager.getCurrentLevel();
+    this.saveDataManager.failLevel(currentLevel);
+}
+```
+
+### 在主界面显示玩家信息
+
+```typescript
+// 在MainUIController中使用
+export class MainUIController extends Component {
+    private saveDataManager: SaveDataManager = null;
+    
+    start() {
+        this.saveDataManager = SaveDataManager.getInstance();
+        this.saveDataManager.initialize();
+        this.updateUI();
+    }
+    
+    updateUI() {
+        // 更新玩家等级显示
+        const playerLevel = this.saveDataManager.getPlayerLevel();
+        this.playerLevelLabel.string = `Lv.${playerLevel}`;
+        
+        // 更新货币显示
+        const coins = this.saveDataManager.getCoins();
+        this.coinsLabel.string = coins.toString();
+    }
+}
+```
+
+## 数据结构
+
+### PlayerData
+```typescript
+interface PlayerData {
+    // 基本信息
+    playerId: string;
+    playerName: string;
+    createTime: number;
+    lastPlayTime: number;
+    totalPlayTime: number;
+    
+    // 等级和经验
+    playerLevel: number;
+    experience: number;
+    experienceToNext: number;
+    
+    // 货币系统
+    coins: number;
+    diamonds: number;
+    gems: number;
+    
+    // 关卡进度
+    currentLevel: number;
+    maxUnlockedLevel: number;
+    levelProgress: { [levelId: number]: LevelProgress };
+    
+    // 道具和装备
+    inventory: InventoryData;
+    
+    // 统计数据
+    statistics: GameStatistics;
+    
+    // 设置
+    settings: PlayerSettings;
+}
+```
+
+### LevelProgress
+```typescript
+interface LevelProgress {
+    levelId: number;
+    completed: boolean;
+    bestScore: number;
+    bestTime: number;
+    stars: number;
+    attempts: number;
+    firstClearTime: number;
+    lastPlayTime: number;
+    rewards: RewardData[];
+}
+```
+
+## API参考
+
+### 基本信息获取
+- `getPlayerLevel()`: 获取玩家等级
+- `getCurrentLevel()`: 获取当前关卡
+- `getMaxUnlockedLevel()`: 获取最高解锁关卡
+- `getCoins()`: 获取金币数量
+- `getDiamonds()`: 获取钻石数量
+- `getGems()`: 获取宝石数量
+
+### 关卡管理
+- `completeLevel(levelId, score, time, stars)`: 完成关卡
+- `failLevel(levelId)`: 关卡失败
+- `getLevelProgress(levelId)`: 获取关卡进度
+- `isLevelUnlocked(levelId)`: 检查关卡是否解锁
+- `isLevelCompleted(levelId)`: 检查关卡是否完成
+
+### 货币管理
+- `addCoins(amount, source)`: 添加金币
+- `spendCoins(amount)`: 消费金币
+- `addDiamonds(amount, source)`: 添加钻石
+- `spendDiamonds(amount)`: 消费钻石
+- `addGems(amount, source)`: 添加宝石
+
+### 经验和等级
+- `addExperience(amount)`: 添加经验值
+- 自动处理升级和升级奖励
+
+### 道具管理
+- `addWeapon(weaponId, rarity)`: 添加武器
+- `addItem(itemId, count)`: 添加道具
+- `useItem(itemId, count)`: 使用道具
+
+### 数据保存和加载
+- `savePlayerData(force)`: 保存玩家数据
+- `checkAutoSave()`: 检查自动保存
+- `resetAllData()`: 重置所有数据
+- `exportSaveData()`: 导出存档数据
+- `importSaveData(dataString)`: 导入存档数据
+
+### 设置管理
+- `updateSetting(key, value)`: 更新设置
+- `getSetting(key)`: 获取设置值
+
+## 游戏流程集成
+
+### 1. 游戏启动
+```typescript
+// 在游戏启动时初始化存档系统
+const saveManager = SaveDataManager.getInstance();
+saveManager.initialize();
+```
+
+### 2. 主界面显示
+```typescript
+// 显示玩家信息
+const playerLevel = saveManager.getPlayerLevel();
+const currentLevel = saveManager.getCurrentLevel();
+const coins = saveManager.getCoins();
+```
+
+### 3. 进入关卡
+```typescript
+// 获取当前关卡信息
+const currentLevel = saveManager.getCurrentLevel();
+const isUnlocked = saveManager.isLevelUnlocked(currentLevel);
+```
+
+### 4. 游戏进行中
+```typescript
+// 记录游戏统计数据
+saveManager.updateStatistic('totalShotsfired', 1);
+saveManager.updateStatistic('totalEnemiesDefeated', 1);
+```
+
+### 5. 关卡完成
+```typescript
+// 记录关卡完成
+const score = calculateScore();
+const time = getGameDuration();
+const stars = calculateStars();
+saveManager.completeLevel(currentLevel, score, time, stars);
+
+// 给予奖励
+saveManager.addCoins(baseReward, 'level_complete');
+```
+
+### 6. 关卡失败
+```typescript
+// 记录关卡失败
+saveManager.failLevel(currentLevel);
+```
+
+### 7. 返回主界面
+```typescript
+// 保存数据
+saveManager.savePlayerData(true);
+```
+
+## 注意事项
+
+1. **单例模式**:SaveDataManager使用单例模式,确保全局只有一个实例
+2. **自动保存**:系统会定期自动保存,避免频繁的手动保存
+3. **数据备份**:系统会自动创建备份,防止数据丢失
+4. **版本兼容**:支持数据结构的版本迁移和兼容
+5. **错误处理**:包含完整的错误处理和恢复机制
+
+## 调试功能
+
+系统提供了多个调试方法:
+- `getSaveSummary()`: 获取存档摘要信息
+- `exportSaveData()`: 导出存档数据用于调试
+- `resetAllData()`: 重置所有数据用于测试
+
+## 扩展性
+
+系统设计具有良好的扩展性,可以轻松添加:
+- 新的货币类型
+- 更多的统计数据
+- 额外的玩家设置
+- 新的道具和装备类型
+
+通过修改相应的接口定义即可扩展功能,无需大幅修改现有代码。 

+ 11 - 0
assets/scripts/LevelSystem/README_SaveSystem.md.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "1.0.1",
+  "importer": "text",
+  "imported": true,
+  "uuid": "d7265617-8389-404d-8aa2-b1d9ff0dc652",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 878 - 0
assets/scripts/LevelSystem/SaveDataManager.ts

@@ -0,0 +1,878 @@
+import { _decorator, sys } from 'cc';
+const { ccclass, property } = _decorator;
+
+/**
+ * 玩家数据结构
+ */
+export interface PlayerData {
+    // 基本信息
+    playerId: string;
+    playerName: string;
+    createTime: number;
+    lastPlayTime: number;
+    totalPlayTime: number;
+    
+    // 等级和经验
+    playerLevel: number;
+    experience: number;
+    experienceToNext: number;
+    
+    // 货币系统
+    coins: number;           // 金币
+    diamonds: number;        // 钻石
+    gems: number;           // 宝石
+    
+    // 关卡进度
+    currentLevel: number;
+    maxUnlockedLevel: number;
+    levelProgress: { [levelId: number]: LevelProgress };
+    
+    // 道具和装备
+    inventory: InventoryData;
+    
+    // 统计数据
+    statistics: GameStatistics;
+    
+    // 设置
+    settings: PlayerSettings;
+}
+
+/**
+ * 关卡进度数据
+ */
+export interface LevelProgress {
+    levelId: number;
+    completed: boolean;
+    bestScore: number;
+    bestTime: number;
+    stars: number;
+    attempts: number;
+    firstClearTime: number;
+    lastPlayTime: number;
+    rewards: RewardData[];
+}
+
+/**
+ * 背包数据
+ */
+export interface InventoryData {
+    weapons: { [weaponId: string]: WeaponData };
+    items: { [itemId: string]: ItemData };
+    materials: { [materialId: string]: number };
+    capacity: number;
+    usedSlots: number;
+}
+
+/**
+ * 武器数据
+ */
+export interface WeaponData {
+    weaponId: string;
+    level: number;
+    experience: number;
+    rarity: string;
+    obtainTime: number;
+    upgradeCount: number;
+    isEquipped: boolean;
+}
+
+/**
+ * 道具数据
+ */
+export interface ItemData {
+    itemId: string;
+    count: number;
+    obtainTime: number;
+    lastUsedTime: number;
+}
+
+/**
+ * 奖励数据
+ */
+export interface RewardData {
+    type: 'coins' | 'diamonds' | 'gems' | 'weapon' | 'item' | 'experience';
+    id?: string;
+    amount: number;
+    obtainTime: number;
+    source: string; // 获得来源:level_complete, daily_reward, shop_purchase等
+}
+
+/**
+ * 游戏统计数据
+ */
+export interface GameStatistics {
+    totalGamesPlayed: number;
+    totalWins: number;
+    totalLosses: number;
+    totalScore: number;
+    totalEnemiesDefeated: number;
+    totalShotsfired: number;
+    totalDamageDealt: number;
+    totalTimePlayed: number;
+    highestLevel: number;
+    consecutiveWins: number;
+    bestWinStreak: number;
+    favoriteWeapon: string;
+    weaponsUnlocked: number;
+    itemsCollected: number;
+}
+
+/**
+ * 玩家设置
+ */
+export interface PlayerSettings {
+    soundEnabled: boolean;
+    musicEnabled: boolean;
+    soundVolume: number;
+    musicVolume: number;
+    vibrationEnabled: boolean;
+    autoSaveEnabled: boolean;
+    language: string;
+    graphics: 'low' | 'medium' | 'high';
+}
+
+/**
+ * 存档管理器
+ * 负责玩家数据的保存、加载和管理
+ */
+@ccclass('SaveDataManager')
+export class SaveDataManager {
+    private static instance: SaveDataManager = null;
+    
+    private playerData: PlayerData = null;
+    private initialized: boolean = false;
+    private autoSaveInterval: number = 30; // 自动保存间隔(秒)
+    private lastSaveTime: number = 0;
+    
+    // 存档文件键名
+    private readonly SAVE_KEY = 'pong_game_save_data';
+    private readonly BACKUP_KEY = 'pong_game_save_data_backup';
+    private readonly SETTINGS_KEY = 'pong_game_settings';
+    
+    private constructor() {
+        // 私有构造函数,确保单例模式
+    }
+    
+    public static getInstance(): SaveDataManager {
+        if (SaveDataManager.instance === null) {
+            SaveDataManager.instance = new SaveDataManager();
+        }
+        return SaveDataManager.instance;
+    }
+    
+    /**
+     * 初始化存档管理器
+     */
+    public initialize(): void {
+        if (this.initialized) return;
+        
+        this.loadPlayerData();
+        this.initialized = true;
+        
+        console.log('✅ 存档管理器初始化完成');
+        console.log(`玩家等级: ${this.playerData.playerLevel}`);
+        console.log(`当前关卡: ${this.playerData.currentLevel}`);
+        console.log(`金币: ${this.playerData.coins}`);
+        console.log(`钻石: ${this.playerData.diamonds}`);
+    }
+    
+    /**
+     * 加载玩家数据
+     */
+    private loadPlayerData(): void {
+        try {
+            const savedData = sys.localStorage.getItem(this.SAVE_KEY);
+            
+            if (savedData) {
+                const data = JSON.parse(savedData);
+                this.playerData = this.validateAndMigrateData(data);
+                this.playerData.lastPlayTime = Date.now();
+                console.log('✅ 存档数据加载成功');
+            } else {
+                this.createNewPlayerData();
+                console.log('🆕 创建新的玩家存档');
+            }
+        } catch (error) {
+            console.error('❌ 存档数据加载失败,尝试加载备份:', error);
+            this.loadBackupData();
+        }
+    }
+    
+    /**
+     * 加载备份数据
+     */
+    private loadBackupData(): void {
+        try {
+            const backupData = sys.localStorage.getItem(this.BACKUP_KEY);
+            
+            if (backupData) {
+                const data = JSON.parse(backupData);
+                this.playerData = this.validateAndMigrateData(data);
+                this.playerData.lastPlayTime = Date.now();
+                console.log('✅ 备份数据加载成功');
+            } else {
+                this.createNewPlayerData();
+                console.log('🆕 备份数据不存在,创建新存档');
+            }
+        } catch (error) {
+            console.error('❌ 备份数据加载失败,创建新存档:', error);
+            this.createNewPlayerData();
+        }
+    }
+    
+    /**
+     * 创建新的玩家数据
+     */
+    private createNewPlayerData(): void {
+        this.playerData = {
+            playerId: this.generatePlayerId(),
+            playerName: 'Player',
+            createTime: Date.now(),
+            lastPlayTime: Date.now(),
+            totalPlayTime: 0,
+            
+            playerLevel: 1,
+            experience: 0,
+            experienceToNext: 100,
+            
+            coins: 1000,        // 初始金币
+            diamonds: 50,       // 初始钻石
+            gems: 0,
+            
+            currentLevel: 1,
+            maxUnlockedLevel: 1,
+            levelProgress: {},
+            
+            inventory: {
+                weapons: {},
+                items: {},
+                materials: {},
+                capacity: 50,
+                usedSlots: 0
+            },
+            
+            statistics: {
+                totalGamesPlayed: 0,
+                totalWins: 0,
+                totalLosses: 0,
+                totalScore: 0,
+                totalEnemiesDefeated: 0,
+                totalShotsfired: 0,
+                totalDamageDealt: 0,
+                totalTimePlayed: 0,
+                highestLevel: 1,
+                consecutiveWins: 0,
+                bestWinStreak: 0,
+                favoriteWeapon: '',
+                weaponsUnlocked: 0,
+                itemsCollected: 0
+            },
+            
+            settings: {
+                soundEnabled: true,
+                musicEnabled: true,
+                soundVolume: 0.8,
+                musicVolume: 0.6,
+                vibrationEnabled: true,
+                autoSaveEnabled: true,
+                language: 'zh-CN',
+                graphics: 'medium'
+            }
+        };
+        
+        this.savePlayerData();
+    }
+    
+    /**
+     * 验证和迁移数据(用于版本兼容)
+     */
+    private validateAndMigrateData(data: any): PlayerData {
+        // 确保所有必要字段存在
+        const defaultData = this.createDefaultPlayerData();
+        
+        return {
+            ...defaultData,
+            ...data,
+            // 确保嵌套对象也被正确合并
+            inventory: { ...defaultData.inventory, ...data.inventory },
+            statistics: { ...defaultData.statistics, ...data.statistics },
+            settings: { ...defaultData.settings, ...data.settings }
+        };
+    }
+    
+    /**
+     * 创建默认玩家数据模板
+     */
+    private createDefaultPlayerData(): PlayerData {
+        return {
+            playerId: this.generatePlayerId(),
+            playerName: 'Player',
+            createTime: Date.now(),
+            lastPlayTime: Date.now(),
+            totalPlayTime: 0,
+            playerLevel: 1,
+            experience: 0,
+            experienceToNext: 100,
+            coins: 1000,
+            diamonds: 50,
+            gems: 0,
+            currentLevel: 1,
+            maxUnlockedLevel: 1,
+            levelProgress: {},
+            inventory: {
+                weapons: {},
+                items: {},
+                materials: {},
+                capacity: 50,
+                usedSlots: 0
+            },
+            statistics: {
+                totalGamesPlayed: 0,
+                totalWins: 0,
+                totalLosses: 0,
+                totalScore: 0,
+                totalEnemiesDefeated: 0,
+                totalShotsfired: 0,
+                totalDamageDealt: 0,
+                totalTimePlayed: 0,
+                highestLevel: 1,
+                consecutiveWins: 0,
+                bestWinStreak: 0,
+                favoriteWeapon: '',
+                weaponsUnlocked: 0,
+                itemsCollected: 0
+            },
+            settings: {
+                soundEnabled: true,
+                musicEnabled: true,
+                soundVolume: 0.8,
+                musicVolume: 0.6,
+                vibrationEnabled: true,
+                autoSaveEnabled: true,
+                language: 'zh-CN',
+                graphics: 'medium'
+            }
+        };
+    }
+    
+    /**
+     * 保存玩家数据
+     */
+    public savePlayerData(force: boolean = false): void {
+        if (!this.playerData) return;
+        
+        const currentTime = Date.now();
+        
+        // 检查是否需要保存(避免频繁保存)
+        if (!force && currentTime - this.lastSaveTime < 5000) {
+            return;
+        }
+        
+        try {
+            // 更新最后保存时间
+            this.playerData.lastPlayTime = currentTime;
+            
+            // 创建备份
+            const currentData = sys.localStorage.getItem(this.SAVE_KEY);
+            if (currentData) {
+                sys.localStorage.setItem(this.BACKUP_KEY, currentData);
+            }
+            
+            // 保存当前数据
+            const dataToSave = JSON.stringify(this.playerData);
+            sys.localStorage.setItem(this.SAVE_KEY, dataToSave);
+            
+            this.lastSaveTime = currentTime;
+            console.log('💾 玩家数据保存成功');
+        } catch (error) {
+            console.error('❌ 玩家数据保存失败:', error);
+        }
+    }
+    
+    /**
+     * 自动保存检查
+     */
+    public checkAutoSave(): void {
+        if (!this.playerData || !this.playerData.settings.autoSaveEnabled) return;
+        
+        const currentTime = Date.now();
+        if (currentTime - this.lastSaveTime > this.autoSaveInterval * 1000) {
+            this.savePlayerData();
+        }
+    }
+    
+    // === 玩家基本信息管理 ===
+    
+    public getPlayerData(): PlayerData {
+        return this.playerData;
+    }
+    
+    public getPlayerLevel(): number {
+        return this.playerData?.playerLevel || 1;
+    }
+    
+    public getCurrentLevel(): number {
+        return this.playerData?.currentLevel || 1;
+    }
+    
+    public getMaxUnlockedLevel(): number {
+        return this.playerData?.maxUnlockedLevel || 1;
+    }
+    
+    public getCoins(): number {
+        return this.playerData?.coins || 0;
+    }
+    
+    public getDiamonds(): number {
+        return this.playerData?.diamonds || 0;
+    }
+    
+    public getGems(): number {
+        return this.playerData?.gems || 0;
+    }
+    
+    // === 关卡进度管理 ===
+    
+    /**
+     * 完成关卡
+     */
+    public completeLevel(levelId: number, score: number, time: number, stars: number): void {
+        if (!this.playerData) return;
+        
+        // 更新关卡进度
+        if (!this.playerData.levelProgress[levelId]) {
+            this.playerData.levelProgress[levelId] = {
+                levelId: levelId,
+                completed: false,
+                bestScore: 0,
+                bestTime: 0,
+                stars: 0,
+                attempts: 0,
+                firstClearTime: 0,
+                lastPlayTime: 0,
+                rewards: []
+            };
+        }
+        
+        const progress = this.playerData.levelProgress[levelId];
+        progress.attempts += 1;
+        progress.lastPlayTime = Date.now();
+        
+        // 首次完成
+        if (!progress.completed) {
+            progress.completed = true;
+            progress.firstClearTime = Date.now();
+            
+            // 解锁下一关
+            if (levelId === this.playerData.maxUnlockedLevel) {
+                this.playerData.maxUnlockedLevel = levelId + 1;
+            }
+        }
+        
+        // 更新最佳记录
+        if (score > progress.bestScore) {
+            progress.bestScore = score;
+        }
+        
+        if (time > 0 && (progress.bestTime === 0 || time < progress.bestTime)) {
+            progress.bestTime = time;
+        }
+        
+        if (stars > progress.stars) {
+            progress.stars = stars;
+        }
+        
+        // 更新统计数据
+        this.playerData.statistics.totalGamesPlayed += 1;
+        this.playerData.statistics.totalWins += 1;
+        this.playerData.statistics.totalScore += score;
+        this.playerData.statistics.consecutiveWins += 1;
+        
+        if (this.playerData.statistics.consecutiveWins > this.playerData.statistics.bestWinStreak) {
+            this.playerData.statistics.bestWinStreak = this.playerData.statistics.consecutiveWins;
+        }
+        
+        if (levelId > this.playerData.statistics.highestLevel) {
+            this.playerData.statistics.highestLevel = levelId;
+        }
+        
+        // 给予经验值
+        this.addExperience(score / 10 + stars * 20);
+        
+        // 计算并给予奖励
+        this.giveCompletionRewards(levelId, stars);
+        
+        this.savePlayerData();
+        
+        console.log(`🎉 关卡 ${levelId} 完成!得分: ${score}, 星级: ${stars}`);
+    }
+    
+    /**
+     * 关卡失败
+     */
+    public failLevel(levelId: number): void {
+        if (!this.playerData) return;
+        
+        // 更新关卡进度
+        if (!this.playerData.levelProgress[levelId]) {
+            this.playerData.levelProgress[levelId] = {
+                levelId: levelId,
+                completed: false,
+                bestScore: 0,
+                bestTime: 0,
+                stars: 0,
+                attempts: 0,
+                firstClearTime: 0,
+                lastPlayTime: 0,
+                rewards: []
+            };
+        }
+        
+        const progress = this.playerData.levelProgress[levelId];
+        progress.attempts += 1;
+        progress.lastPlayTime = Date.now();
+        
+        // 更新统计数据
+        this.playerData.statistics.totalGamesPlayed += 1;
+        this.playerData.statistics.totalLosses += 1;
+        this.playerData.statistics.consecutiveWins = 0;
+        
+        this.savePlayerData();
+        
+        console.log(`💔 关卡 ${levelId} 失败`);
+    }
+    
+    /**
+     * 获取关卡进度
+     */
+    public getLevelProgress(levelId: number): LevelProgress | null {
+        return this.playerData?.levelProgress[levelId] || null;
+    }
+    
+    /**
+     * 检查关卡是否已解锁
+     */
+    public isLevelUnlocked(levelId: number): boolean {
+        return levelId <= (this.playerData?.maxUnlockedLevel || 1);
+    }
+    
+    /**
+     * 检查关卡是否已完成
+     */
+    public isLevelCompleted(levelId: number): boolean {
+        const progress = this.getLevelProgress(levelId);
+        return progress?.completed || false;
+    }
+    
+    // === 货币管理 ===
+    
+    /**
+     * 添加金币
+     */
+    public addCoins(amount: number, source: string = 'unknown'): boolean {
+        if (!this.playerData || amount <= 0) return false;
+        
+        this.playerData.coins += amount;
+        this.addReward('coins', '', amount, source);
+        
+        console.log(`💰 获得金币 +${amount} (来源: ${source})`);
+        return true;
+    }
+    
+    /**
+     * 消费金币
+     */
+    public spendCoins(amount: number): boolean {
+        if (!this.playerData || amount <= 0 || this.playerData.coins < amount) {
+            return false;
+        }
+        
+        this.playerData.coins -= amount;
+        console.log(`💸 消费金币 -${amount}`);
+        return true;
+    }
+    
+    /**
+     * 添加钻石
+     */
+    public addDiamonds(amount: number, source: string = 'unknown'): boolean {
+        if (!this.playerData || amount <= 0) return false;
+        
+        this.playerData.diamonds += amount;
+        this.addReward('diamonds', '', amount, source);
+        
+        console.log(`💎 获得钻石 +${amount} (来源: ${source})`);
+        return true;
+    }
+    
+    /**
+     * 消费钻石
+     */
+    public spendDiamonds(amount: number): boolean {
+        if (!this.playerData || amount <= 0 || this.playerData.diamonds < amount) {
+            return false;
+        }
+        
+        this.playerData.diamonds -= amount;
+        console.log(`💸 消费钻石 -${amount}`);
+        return true;
+    }
+    
+    /**
+     * 添加宝石
+     */
+    public addGems(amount: number, source: string = 'unknown'): boolean {
+        if (!this.playerData || amount <= 0) return false;
+        
+        this.playerData.gems += amount;
+        this.addReward('gems', '', amount, source);
+        
+        console.log(`💜 获得宝石 +${amount} (来源: ${source})`);
+        return true;
+    }
+    
+    // === 经验和等级管理 ===
+    
+    /**
+     * 添加经验值
+     */
+    public addExperience(amount: number): boolean {
+        if (!this.playerData || amount <= 0) return false;
+        
+        this.playerData.experience += amount;
+        
+        // 检查是否升级
+        while (this.playerData.experience >= this.playerData.experienceToNext) {
+            this.levelUp();
+        }
+        
+        console.log(`⭐ 获得经验值 +${amount}`);
+        return true;
+    }
+    
+    /**
+     * 玩家升级
+     */
+    private levelUp(): void {
+        this.playerData.experience -= this.playerData.experienceToNext;
+        this.playerData.playerLevel += 1;
+        
+        // 计算下一级所需经验值
+        this.playerData.experienceToNext = this.calculateExperienceToNext(this.playerData.playerLevel);
+        
+        // 升级奖励
+        const coinReward = this.playerData.playerLevel * 100;
+        const diamondReward = Math.floor(this.playerData.playerLevel / 5);
+        
+        this.addCoins(coinReward, 'level_up');
+        if (diamondReward > 0) {
+            this.addDiamonds(diamondReward, 'level_up');
+        }
+        
+        console.log(`🎉 玩家升级到 ${this.playerData.playerLevel} 级!`);
+        console.log(`奖励:金币 +${coinReward}, 钻石 +${diamondReward}`);
+    }
+    
+    /**
+     * 计算升级所需经验值
+     */
+    private calculateExperienceToNext(level: number): number {
+        return 100 + (level - 1) * 50;
+    }
+    
+    // === 道具和武器管理 ===
+    
+    /**
+     * 添加武器
+     */
+    public addWeapon(weaponId: string, rarity: string = 'common'): boolean {
+        if (!this.playerData) return false;
+        
+        if (!this.playerData.inventory.weapons[weaponId]) {
+            this.playerData.inventory.weapons[weaponId] = {
+                weaponId: weaponId,
+                level: 1,
+                experience: 0,
+                rarity: rarity,
+                obtainTime: Date.now(),
+                upgradeCount: 0,
+                isEquipped: false
+            };
+            
+            this.playerData.statistics.weaponsUnlocked += 1;
+            this.addReward('weapon', weaponId, 1, 'drop');
+            
+            console.log(`⚔️ 获得武器: ${weaponId} (${rarity})`);
+            return true;
+        }
+        
+        return false;
+    }
+    
+    /**
+     * 添加道具
+     */
+    public addItem(itemId: string, count: number = 1): boolean {
+        if (!this.playerData || count <= 0) return false;
+        
+        if (!this.playerData.inventory.items[itemId]) {
+            this.playerData.inventory.items[itemId] = {
+                itemId: itemId,
+                count: 0,
+                obtainTime: Date.now(),
+                lastUsedTime: 0
+            };
+        }
+        
+        this.playerData.inventory.items[itemId].count += count;
+        this.playerData.statistics.itemsCollected += count;
+        this.addReward('item', itemId, count, 'drop');
+        
+        console.log(`📦 获得道具: ${itemId} x${count}`);
+        return true;
+    }
+    
+    /**
+     * 使用道具
+     */
+    public useItem(itemId: string, count: number = 1): boolean {
+        if (!this.playerData || count <= 0) return false;
+        
+        const item = this.playerData.inventory.items[itemId];
+        if (!item || item.count < count) {
+            return false;
+        }
+        
+        item.count -= count;
+        item.lastUsedTime = Date.now();
+        
+        if (item.count === 0) {
+            delete this.playerData.inventory.items[itemId];
+        }
+        
+        console.log(`🔧 使用道具: ${itemId} x${count}`);
+        return true;
+    }
+    
+    // === 奖励管理 ===
+    
+    /**
+     * 添加奖励记录
+     */
+    private addReward(type: RewardData['type'], id: string, amount: number, source: string): void {
+        if (!this.playerData) return;
+        
+        const reward: RewardData = {
+            type: type,
+            id: id,
+            amount: amount,
+            obtainTime: Date.now(),
+            source: source
+        };
+        
+        // 这里可以添加到全局奖励历史记录中
+        // 暂时不实现,避免数据过大
+    }
+    
+    /**
+     * 给予关卡完成奖励
+     */
+    private giveCompletionRewards(levelId: number, stars: number): void {
+        // 基础金币奖励
+        const baseCoins = levelId * 50;
+        const starBonus = stars * 25;
+        const totalCoins = baseCoins + starBonus;
+        
+        this.addCoins(totalCoins, `level_${levelId}_complete`);
+        
+        // 钻石奖励(3星才给)
+        if (stars >= 3) {
+            const diamonds = Math.max(1, Math.floor(levelId / 3));
+            this.addDiamonds(diamonds, `level_${levelId}_perfect`);
+        }
+        
+        // 特殊关卡额外奖励
+        if (levelId % 10 === 0) {
+            this.addGems(1, `level_${levelId}_milestone`);
+        }
+    }
+    
+    // === 统计数据更新 ===
+    
+    public updateStatistic(key: keyof GameStatistics, value: number): void {
+        if (!this.playerData) return;
+        
+        if (typeof this.playerData.statistics[key] === 'number') {
+            (this.playerData.statistics[key] as number) += value;
+        }
+    }
+    
+    // === 设置管理 ===
+    
+    public updateSetting<K extends keyof PlayerSettings>(key: K, value: PlayerSettings[K]): void {
+        if (!this.playerData) return;
+        
+        this.playerData.settings[key] = value;
+        this.savePlayerData();
+    }
+    
+    public getSetting<K extends keyof PlayerSettings>(key: K): PlayerSettings[K] {
+        return this.playerData?.settings[key];
+    }
+    
+    // === 工具方法 ===
+    
+    /**
+     * 生成唯一玩家ID
+     */
+    private generatePlayerId(): string {
+        return `player_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+    }
+    
+    /**
+     * 重置所有数据
+     */
+    public resetAllData(): void {
+        sys.localStorage.removeItem(this.SAVE_KEY);
+        sys.localStorage.removeItem(this.BACKUP_KEY);
+        this.createNewPlayerData();
+        console.log('🔄 所有存档数据已重置');
+    }
+    
+    /**
+     * 导出存档数据(用于调试)
+     */
+    public exportSaveData(): string {
+        return JSON.stringify(this.playerData, null, 2);
+    }
+    
+    /**
+     * 导入存档数据(用于调试)
+     */
+    public importSaveData(dataString: string): boolean {
+        try {
+            const data = JSON.parse(dataString);
+            this.playerData = this.validateAndMigrateData(data);
+            this.savePlayerData(true);
+            console.log('✅ 存档数据导入成功');
+            return true;
+        } catch (error) {
+            console.error('❌ 存档数据导入失败:', error);
+            return false;
+        }
+    }
+    
+    /**
+     * 获取存档摘要信息
+     */
+    public getSaveSummary(): string {
+        if (!this.playerData) return '无存档数据';
+        
+        return `玩家等级: ${this.playerData.playerLevel} | ` +
+               `当前关卡: ${this.playerData.currentLevel} | ` +
+               `最高关卡: ${this.playerData.maxUnlockedLevel} | ` +
+               `金币: ${this.playerData.coins} | ` +
+               `钻石: ${this.playerData.diamonds} | ` +
+               `游戏次数: ${this.playerData.statistics.totalGamesPlayed}`;
+    }
+} 

+ 9 - 0
assets/scripts/LevelSystem/SaveDataManager.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "6640bcc1-6bb0-4c50-905a-e2f11288f95f",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff