| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359 |
- import { _decorator, Component, Node, Prefab, instantiate, Vec3, find, director, Canvas, UITransform, Button, Label, ProgressBar, 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';
- import EventBus, { GameEvents } from '../Core/EventBus';
- import { PhysicsManager } from '../Core/PhysicsManager';
- import { BallController } from '../CombatSystem/BallController';
- import { BlockManager } from '../CombatSystem/BlockManager';
- import { LevelSessionManager } from '../Core/LevelSessionManager';
- import { GameStartMove } from '../Animations/GameStartMove';
- import { GameBlockSelection } from '../CombatSystem/BlockSelection/GameBlockSelection';
- import { BlockTag } from '../CombatSystem/BlockSelection/BlockTag';
- import { GamePause } from '../CombatSystem/GamePause';
- const { ccclass, property } = _decorator;
- /**
- * 游戏状态枚举
- */
- enum GameState {
- PLAYING = 'playing',
- SUCCESS = 'success',
- DEFEAT = 'defeat',
- PAUSED = 'paused',
- BLOCK_SELECTION = 'block_selection'
- }
- /**
- * 增强版游戏管理器
- * 整合了游戏启动、状态管理、UI控制等功能
- */
- @ccclass('GameManager')
- export class GameManager extends Component {
-
- // === 原GameManager属性 ===
- @property({
- type: Node,
- tooltip: '拖拽BallController节点到这里'
- })
- public ballController: Node = null;
- @property({
- type: Node,
- tooltip: '拖拽GameBlockSelection节点到这里'
- })
- public gameBlockSelection: Node = null;
- @property({
- type: Node,
- tooltip: '拖拽GameArea节点到这里'
- })
- public gameArea: Node = null;
- @property({
- type: Node,
- tooltip: '拖拽EnemyController节点到这里'
- })
- public enemyManager: Node = null;
- // === 游戏状态管理属性 ===
- @property({
- type: Node,
- tooltip: '血量显示节点 (HeartLabeld)'
- })
- public heartLabelNode: Node = null;
- @property({
- type: Node,
- tooltip: '游戏成功UI节点 (GameSuccess)'
- })
- public gameSuccessUI: Node = null;
- @property({
- type: Node,
- tooltip: '游戏失败UI节点 (GameDefeat)'
- })
- public gameDefeatUI: Node = null;
- // === 能量与技能选择 UI ===
- @property({
- type: Node,
- tooltip: '拖拽 EnergyBar (ProgressBar) 节点到这里'
- })
- public energyBarNode: Node = null;
- @property({
- type: Node,
- tooltip: '拖拽 SelectSkillUI 节点到这里'
- })
- public selectSkillUI: Node = null;
- // === 游戏配置属性 ===
- // 墙体基础血量由存档决定,不再通过属性面板设置
- private wallHealth: number = 100;
- @property({
- tooltip: '初始血量'
- })
- public initialHealth: number = 100;
- @property({
- tooltip: '状态检查间隔(秒)'
- })
- public checkInterval: number = 1.0;
- // === 私有属性 ===
- private gameStarted: boolean = false;
- private currentHealth: number = 100;
- private currentState: GameState = GameState.PLAYING;
- private checkTimer: number = 0;
- private heartLabel: Label = null;
- 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;
- private totalEnemiesSpawned: number = 0;
- private currentWave: number = 1;
- private currentWaveEnemyCount: number = 0;
- private currentWaveTotalEnemies: number = 0; // 当前波次总敌人数
- private levelWaves: any[] = []; // 关卡波次配置
- private levelTotalEnemies: number = 0; // 本关卡总敌人数
- private enemiesKilled: number = 0; // 已击杀敌人数量
-
- // 游戏计时器
- private gameStartTime: number = 0;
- private gameEndTime: number = 0;
- // 游戏区域的边界
- private gameBounds = {
- left: 0,
- right: 0,
- top: 0,
- bottom: 0
- };
- private preparingNextWave = false;
- // 能量系统
- private energyPoints: number = 0;
- private readonly ENERGY_MAX: number = 5;
- private energyBar: ProgressBar = null;
- // GameBlockSelection组件
- private blockSelectionComponent: GameBlockSelection = null;
- private pendingSkillSelection: boolean = false;
- start() {
- // 初始化物理系统
- this.initPhysicsSystem();
-
- // 初始化管理器
- this.initializeManagers();
- // 提前初始化本局数据,确保 BlockManager 在 start 时能拿到正确金币
- if (!LevelSessionManager.inst.runtime) {
- LevelSessionManager.inst.initialize(
- this.saveDataManager?.getCurrentLevel() || 1,
- this.wallHealth
- );
- }
-
- // 计算游戏区域边界
- this.calculateGameBounds();
-
- // 初始化游戏状态
- this.initializeGameState();
-
- // 查找UI节点
- this.findUINodes();
-
- // 查找敌人控制器
- this.findEnemyController();
-
- // 初始化墙体血量显示
- this.initWallHealthDisplay();
-
- // 设置敌人控制器
- this.setupEnemyController();
-
- // 设置UI按钮
- this.setupUIButtons();
-
- // 初始化GameBlockSelection组件
- this.initGameBlockSelection();
-
- // 加载当前关卡配置
- this.loadCurrentLevelConfig();
- // 监听GamePause状态变化事件
- this.setupGamePauseEventListeners();
- }
- /**
- * 设置GamePause事件监听器
- */
- private setupGamePauseEventListeners() {
- const eventBus = EventBus.getInstance();
-
- // 监听游戏成功事件
- eventBus.on(GameEvents.GAME_SUCCESS, this.onGameSuccessEvent, this);
-
- // 监听游戏失败事件
- eventBus.on(GameEvents.GAME_DEFEAT, this.onGameDefeatEvent, this);
-
- // 监听敌人被击杀事件
- eventBus.on('ENEMY_KILLED', this.onEnemyKilledEvent, this);
- }
- /**
- * 处理游戏成功事件
- */
- private onGameSuccessEvent() {
- console.log('[GameManager] 接收到游戏成功事件,执行成功处理');
-
- // 显示游戏成功UI
- if (this.gameSuccessUI) {
- this.gameSuccessUI.active = true;
- }
- // 执行游戏成功逻辑
- this.onGameSuccess();
- }
- /**
- * 处理游戏失败事件
- */
- private onGameDefeatEvent() {
- console.log('[GameManager] 接收到游戏失败事件,执行失败处理');
-
- // 显示游戏失败UI
- if (this.gameDefeatUI) {
- this.gameDefeatUI.active = true;
- }
- // 执行游戏失败逻辑
- this.onGameDefeat();
- }
- /**
- * 处理敌人被击杀事件
- */
- private onEnemyKilledEvent() {
- // 如果游戏已经结束,不执行后续逻辑
- const gamePause = GamePause.getInstance();
- if (gamePause.isGameOver()) {
- console.warn('[GameManager] 游戏已结束状态下onEnemyKilledEvent被调用!当前状态:', gamePause.getCurrentState());
- return;
- }
-
- this.enemiesKilled++;
- // 当前波击杀 +1
- this.currentWaveEnemyCount++;
- const remaining = this.currentWaveTotalEnemies - this.currentWaveEnemyCount;
- console.log(`[GameManager] 敌人被消灭,当前波剩余敌人: ${remaining}/${this.currentWaveTotalEnemies}, 总击杀: ${this.enemiesKilled}`);
-
- // 先检查是否波次结束,如果结束则先设置状态
- if (remaining <= 0) {
- // 当前波结束
- if (this.currentWave < (this.levelWaves?.length || 1)) {
- // 还有下一波,先设置状态为方块选择,防止能量满时直接弹出技能选择
- this.currentState = GameState.BLOCK_SELECTION;
- console.log(`[GameManager] 当前波结束,准备显示下一波(${this.currentWave + 1}/${this.levelWaves?.length || 1})选择UI`);
- this.showNextWavePrompt();
- } else {
- // 最后一波也结束
- console.log('[GameManager] 最后一波结束,触发游戏胜利');
- this.triggerGameSuccess();
- }
- }
- // 增加能量点(在状态设置之后)
- this.incrementEnergy();
- }
- // === 暂停游戏 ===
- private pauseGame() {
- // 使用GamePause统一管理暂停逻辑
- const gamePause = GamePause.getInstance();
- if (gamePause) {
- gamePause.pauseGame();
- }
- }
- // === 恢复游戏 ===
- public resumeGame() {
- // 使用GamePause统一管理恢复逻辑
- const gamePause = GamePause.getInstance();
- if (gamePause) {
- gamePause.resumeGame();
- }
- if (this.gameSuccessUI) {
- this.gameSuccessUI.active = false;
- }
- if (this.gameDefeatUI) {
- this.gameDefeatUI.active = false;
- }
- }
- update(deltaTime: number) {
- if (this.currentState !== GameState.PLAYING) {
- return;
- }
- // 更新检查计时器
- this.checkTimer += deltaTime;
-
- if (this.checkTimer >= this.checkInterval) {
- this.checkTimer = 0;
- this.checkGameState();
- }
-
- // 检查自动保存
- if (this.saveDataManager) {
- this.saveDataManager.checkAutoSave();
- }
- }
- // === 物理系统初始化 ===
- private initPhysicsSystem() {
- // 确保 PhysicsManager 单例存在
- let pm = PhysicsManager.getInstance();
- if (!pm) {
- const physicsNode = new Node('PhysicsManager');
- director.getScene()?.addChild(physicsNode);
- pm = physicsNode.addComponent(PhysicsManager);
- }
- }
- // === 管理器初始化 ===
- private initializeManagers() {
- this.levelManager = LevelManager.getInstance();
- // this.shopManager = ShopManager.getInstance();
- this.configManager = ConfigManager.getInstance();
- this.levelConfigManager = LevelConfigManager.getInstance();
- this.enemyController = EnemyController.getInstance() || null;
-
- // 初始化存档管理器
- this.saveDataManager = SaveDataManager.getInstance();
- this.saveDataManager.initialize();
- // 从存档读取墙体基础血量
- const pd = this.saveDataManager.getPlayerData();
- if (pd && typeof pd.wallBaseHealth === 'number') {
- this.wallHealth = pd.wallBaseHealth;
- }
- }
- // === 游戏状态初始化 ===
- private initializeGameState() {
- this.currentHealth = this.initialHealth;
- this.currentState = GameState.PLAYING;
- this.checkTimer = 0;
- this.enemySpawningStarted = false;
- this.totalEnemiesSpawned = 0;
- this.currentWave = 1;
- this.currentWaveEnemyCount = 0;
- this.currentWaveTotalEnemies = 0; // 当前波次总敌人数
-
- // UI 初始化移交给 EnemyController
- }
- // === 计算游戏区域边界 ===
- private calculateGameBounds() {
- const canvas = find('Canvas');
- if (!canvas) {
- return;
- }
- const canvasUI = canvas.getComponent(UITransform);
- if (!canvasUI) {
- return;
- }
- const screenWidth = canvasUI.width;
- const screenHeight = canvasUI.height;
- const worldPos = canvas.worldPosition;
- this.gameBounds.left = worldPos.x - screenWidth / 2;
- this.gameBounds.right = worldPos.x + screenWidth / 2;
- this.gameBounds.bottom = worldPos.y - screenHeight / 2;
- this.gameBounds.top = worldPos.y + screenHeight / 2;
- }
- // === 查找UI节点 ===
- private findUINodes() {
- // 查找血量显示节点
- if (!this.heartLabelNode) {
- this.heartLabelNode = find('Canvas/GameLevelUI/HeartNode/HeartLabeld');
- }
-
- if (this.heartLabelNode) {
- this.heartLabel = this.heartLabelNode.getComponent(Label);
- }
-
- // 查找游戏成功UI
- if (!this.gameSuccessUI) {
- this.gameSuccessUI = find('Canvas/GameSuccess');
- }
-
- if (this.gameSuccessUI) {
- this.gameSuccessUI.active = false;
- }
-
- // 查找游戏失败UI
- if (!this.gameDefeatUI) {
- this.gameDefeatUI = find('Canvas/GameDefeat');
- }
-
- if (this.gameDefeatUI) {
- this.gameDefeatUI.active = false;
- }
- // 查找能量条
- if (!this.energyBarNode) {
- this.energyBarNode = find('Canvas/GameLevelUI/EnergyBar');
- }
- if (this.energyBarNode) {
- this.energyBar = this.energyBarNode.getComponent(ProgressBar);
- if (this.energyBar) {
- this.energyBar.progress = 0;
- }
- }
- // 查找技能选择 UI
- if (!this.selectSkillUI) {
- this.selectSkillUI = find('Canvas/SelectSkillUI');
- }
- if (this.selectSkillUI) {
- this.selectSkillUI.active = false;
- }
- }
- // === 查找敌人控制器 ===
- private findEnemyController() {
- if (this.enemyManager) {
- this.enemyController = this.enemyManager.getComponent(EnemyController);
- }
-
- if (!this.enemyController) {
- const enemyNode = find('Canvas/GameLevelUI/EnemyController');
- if (enemyNode) {
- this.enemyController = enemyNode.getComponent(EnemyController);
- }
- }
- }
- // === 初始化墙体血量显示 ===
- private initWallHealthDisplay() {
- if (this.heartLabelNode && this.heartLabel) {
- this.heartLabel.string = this.wallHealth.toString();
- }
-
- // 让 EnemyController 自行查找/刷新血量 UI
- if (this.enemyController.initWallHealthDisplay) {
- this.enemyController.initWallHealthDisplay();
- }
- }
- // === 设置敌人控制器 ===
- private setupEnemyController() {
- if (!this.enemyManager) {
- const gameLevelUI = find('Canvas/GameLevelUI');
- if (!gameLevelUI) {
- console.error('找不到GameLevelUI节点,无法创建EnemyController');
- return;
- }
-
- this.enemyManager = new Node('EnemyController');
- gameLevelUI.addChild(this.enemyManager);
- }
-
- if (!this.enemyController) {
- this.enemyController = this.enemyManager.addComponent(EnemyController);
- }
- // 无论 EnemyController 是否新建,都注入墙体血量
- this.enemyController.wallHealth = this.wallHealth;
- this.enemyController.updateWallHealthDisplay?.();
- }
- // === 游戏状态检查 ===
- private checkGameState() {
- // 更新血量
- this.updateHealthFromUI();
-
- if (this.currentHealth <= 0) {
- this.triggerGameDefeat();
- return;
- }
- // 检查是否全部击败
- if (this.checkAllEnemiesDefeated()) {
- this.triggerGameSuccess();
- return;
- }
- }
- // === 从UI更新血量 ===
- private updateHealthFromUI() {
- if (this.heartLabel) {
- const healthText = this.heartLabel.string;
- const healthMatch = healthText.match(/\d+/);
- if (healthMatch) {
- const newHealth = parseInt(healthMatch[0]);
- if (newHealth !== this.currentHealth) {
- this.currentHealth = newHealth;
- }
- }
- }
- }
- // === 检查所有敌人是否被击败 ===
- private checkAllEnemiesDefeated(): boolean {
- if (!this.enemyController) {
- return false;
- }
- // 检查敌人是否已开始生成(避免开局就胜利)
- if (!this.enemySpawningStarted) {
- if (this.enemyController.isGameStarted && this.enemyController.isGameStarted()) {
- this.enemySpawningStarted = true;
- } else {
- return false;
- }
- }
- // 获取当前敌人数量
- const currentEnemyCount = this.enemyController.getCurrentEnemyCount ?
- this.enemyController.getCurrentEnemyCount() : 0;
- // 如果关卡总敌人数已知,以击杀数为准判定胜利
- if (this.levelTotalEnemies > 0) {
- // 当击杀数达到或超过总敌数且场上没有存活敌人时胜利
- return this.enemiesKilled >= this.levelTotalEnemies && currentEnemyCount === 0;
- }
- // 否则退化到旧逻辑:依赖于是否曾经生成过敌人
- // 更新已生成敌人总数(记录曾经达到的最大值)
- if (currentEnemyCount > this.totalEnemiesSpawned) {
- this.totalEnemiesSpawned = currentEnemyCount;
- }
- const shouldCheckVictory = this.enemySpawningStarted &&
- currentEnemyCount === 0 &&
- this.totalEnemiesSpawned > 0;
- return shouldCheckVictory;
- }
- // === 触发游戏失败 ===
- private triggerGameDefeat() {
- // 使用GamePause统一管理游戏状态
- const gamePause = GamePause.getInstance();
- gamePause.triggerGameDefeat();
- }
- // === 触发游戏成功 ===
- private triggerGameSuccess() {
- // 使用GamePause统一管理游戏状态
- const gamePause = GamePause.getInstance();
- gamePause.triggerGameSuccess();
- }
- // === 游戏失败回调 ===
- private onGameDefeat() {
- this.gameEndTime = Date.now();
-
- // 记录游戏失败到存档
- if (this.saveDataManager) {
- const currentLevel = this.saveDataManager.getCurrentLevel();
- this.saveDataManager.failLevel(currentLevel);
-
- // 更新统计数据
- this.saveDataManager.updateStatistic('totalTimePlayed', this.getGameDuration());
- }
- }
- // === 游戏成功回调 ===
- private onGameSuccess() {
- this.gameEndTime = Date.now();
-
- this.giveReward();
- this.onLevelComplete();
- }
- // === 给予奖励 ===
- private giveReward() {
- if (!this.saveDataManager) return;
- const currentLevel = this.saveDataManager.getCurrentLevel();
- const baseReward = currentLevel * 50;
- const healthBonus = Math.floor(this.currentHealth * 0.1);
- const timeBonus = this.calculateTimeBonus();
- const totalCoins = baseReward + healthBonus + timeBonus;
-
- // 给予金币奖励
- this.saveDataManager.addCoins(totalCoins, `level_${currentLevel}_complete`);
-
- // 如果是首次完成,给予额外奖励
- if (!this.saveDataManager.isLevelCompleted(currentLevel)) {
- const firstClearBonus = currentLevel * 25;
- this.saveDataManager.addCoins(firstClearBonus, `level_${currentLevel}_first_clear`);
- }
- }
- // === 处理关卡完成 ===
- 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);
-
- // 兼容原有的LevelManager
- if (this.levelManager) {
- 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按钮 ===
- private setupUIButtons() {
- this.setupSuccessUIButtons();
- this.setupDefeatUIButtons();
- }
- // === 设置成功界面按钮 ===
- private setupSuccessUIButtons() {
- if (this.gameSuccessUI) {
- const nextLevelBtn = this.gameSuccessUI.getChildByName('NextLevelBtn');
- const restartBtn = this.gameSuccessUI.getChildByName('RestartBtn');
- const mainMenuBtn = this.gameSuccessUI.getChildByName('MainMenuBtn');
- const shopBtn = this.gameSuccessUI.getChildByName('ShopBtn');
- if (nextLevelBtn) {
- const button = nextLevelBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onRestartClick, this);
- }
- }
- if (restartBtn) {
- const button = restartBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onRestartClick, this);
- }
- }
- if (mainMenuBtn) {
- const button = mainMenuBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onMainMenuClick, this);
- }
- }
- if (shopBtn) {
- const button = shopBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onShopClick, this);
- }
- }
- }
- }
- // === 设置失败界面按钮 ===
- private setupDefeatUIButtons() {
- if (this.gameDefeatUI) {
- const restartBtn = this.gameDefeatUI.getChildByName('RestartBtn');
- const mainMenuBtn = this.gameDefeatUI.getChildByName('MainMenuBtn');
- const shopBtn = this.gameDefeatUI.getChildByName('ShopBtn');
- const reviveBtn = this.gameDefeatUI.getChildByName('ReviveBtn');
- if (restartBtn) {
- const button = restartBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onRestartClick, this);
- }
- }
- if (mainMenuBtn) {
- const button = mainMenuBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onMainMenuClick, this);
- }
- }
- if (shopBtn) {
- const button = shopBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onShopClick, this);
- }
- }
- if (reviveBtn) {
- const button = reviveBtn.getComponent(Button);
- if (button) {
- button.node.on(Button.EventType.CLICK, this.onReviveClick, this);
- }
- }
- }
- }
- // === 按钮点击事件处理 ===
- private onRestartClick() {
- this.restartGame();
- }
-
- private onMainMenuClick() {
- // 隐藏游戏界面,显示主界面
- const gameLevelUI = find('Canvas/GameLevelUI');
- const mainUI = find('Canvas/MainUI');
- if (gameLevelUI) gameLevelUI.active = false;
- if (mainUI) mainUI.active = true;
-
- // 更新主界面
- const mainUIController = mainUI?.getComponent('MainUIController' as any);
- if (mainUIController && typeof (mainUIController as any).updateUI === 'function') {
- (mainUIController as any).updateUI();
- }
- }
-
- private onShopClick() {
- // 打开商店界面
- const gameLevelUI = find('Canvas/GameLevelUI');
- const shopUI = find('Canvas/ShopUI');
- if (gameLevelUI) gameLevelUI.active = false;
- if (shopUI) shopUI.active = true;
- }
-
- private onReviveClick() {
- const reviveCost = 10; // 复活消耗的钻石数量
-
- if (this.saveDataManager && this.saveDataManager.spendDiamonds(reviveCost)) {
- this.revivePlayer();
- }
- }
- // === 复活玩家 ===
- private revivePlayer() {
- this.setHealth(50);
- this.restartGame();
- }
- // === 重新开始当前关卡 ===
- private restartCurrentLevel() {
- this.restartGame();
- }
- // === 原GameManager方法 ===
- // onConfirmButtonClicked方法已移除,逻辑已整合到handleConfirmAction中
-
- private preservePlacedBlocks() {
- const blockController = find('Canvas/GameLevelUI/BlockController');
-
- if (blockController) {
- const blockManager = blockController.getComponent('BlockManager') as any;
-
- if (blockManager) {
- blockManager.onGameStart();
- }
- }
- }
- public startGame() {
- if (this.gameStarted) return;
-
- this.gameStarted = true;
- this.gameStartTime = Date.now();
- this.currentState = GameState.PLAYING;
-
- // 开始生成球
- this.spawnBall();
-
- // 启动状态检查
- this.checkTimer = 0;
-
- // 设置UI按钮事件
- this.setupUIButtons();
- // 第一波提示UI后再开始生成敌人
- if (this.enemyController && this.enemyController.showStartWavePromptUI) {
- this.enemyController.showStartWavePromptUI();
- } else {
- this.forceStartEnemySpawning();
- }
- LevelSessionManager.inst.initialize(
- SaveDataManager.getInstance().getCurrentLevel(),
- this.wallHealth
- );
- }
-
- private spawnBall() {
- if (!this.ballController) return;
-
- const ballControllerComponent = this.ballController.getComponent(BallController);
- if (ballControllerComponent) {
- ballControllerComponent.startBall();
- }
- }
- public gameOver() {
- this.triggerGameDefeat();
- }
- // === 公共方法 ===
- public setHealth(health: number) {
- this.currentHealth = Math.max(0, health);
- }
- public takeDamage(damage: number) {
- this.currentHealth = Math.max(0, this.currentHealth - damage);
-
- if (this.currentHealth <= 0) {
- this.triggerGameDefeat();
- }
- }
- public getCurrentState(): GameState {
- return this.currentState;
- }
- public restartGame() {
- this.currentState = GameState.PLAYING;
- this.gameStarted = false;
- this.gameStartTime = 0;
- this.gameEndTime = 0;
- this.currentHealth = this.initialHealth;
- this.totalEnemiesSpawned = 0;
- this.enemiesKilled = 0;
- this.currentWave = 1;
- this.currentWaveEnemyCount = 0;
- // 重置GamePause状态
- const gamePause = GamePause.getInstance();
- gamePause.resetGameState();
- // 重置能量条
- this.energyPoints = 0;
- if (this.energyBar) {
- this.energyBar.progress = 0;
- }
- if (this.selectSkillUI) {
- this.selectSkillUI.active = false;
- }
-
- // 关闭胜利/失败界面,确保重新进入时是正常状态
- if (this.gameSuccessUI) {
- this.gameSuccessUI.active = false;
- }
- if (this.gameDefeatUI) {
- this.gameDefeatUI.active = false;
- }
-
- // 通知BlockManager游戏重置
- const blockMgrNode = find('Canvas/GameLevelUI/BlockController');
- const blockManager = blockMgrNode?.getComponent(BlockManager);
- if (blockManager) {
- blockManager.onGameReset?.();
- }
-
- // 清空关卡剩余敌人,不触发敌人死亡事件
- if (this.enemyController && this.enemyController.clearAllEnemies) {
- this.enemyController.clearAllEnemies(false);
- }
-
- // 重置墙体血量显示
- this.initWallHealthDisplay();
-
- // 初始化本局数据(金币45等)
- LevelSessionManager.inst.clear();
- LevelSessionManager.inst.initialize(
- this.saveDataManager.getCurrentLevel(),
- this.wallHealth
- );
- // 刷新方块金币显示(如果 BlockManager 已存在)
- if (blockManager) {
- blockManager.updateCoinDisplay?.();
- }
- }
- public isGameOver(): boolean {
- // 统一使用GamePause来判断游戏是否结束
- const gamePause = GamePause.getInstance();
- return gamePause.isGameOver();
- }
- public forceGameSuccess() {
- this.triggerGameSuccess();
- }
- public forceGameDefeat() {
- this.triggerGameDefeat();
- }
- // === 获取EnemyController组件 ===
- public getEnemyController() {
- return this.enemyController;
- }
- // === 调试方法 ===
- public getEnemyStatus() {
- if (!this.enemyController) return;
-
- const currentCount = this.enemyController.getCurrentEnemyCount();
- const gameStarted = this.enemyController.isGameStarted();
-
- const activeEnemies = this.enemyController.getActiveEnemies?.() || [];
-
- if (activeEnemies.length > 0) {
- for (let index = 0; index < activeEnemies.length; index++) {
- const enemy = activeEnemies[index];
- if (enemy?.isValid) {
- // 查看敌人状态
- } else {
- // 无效敌人节点
- }
- }
- }
- }
-
- public forceStartEnemySpawning() {
- if (this.enemyController) {
- this.enemyController.startGame();
- }
- }
-
- public setTotalEnemiesSpawned(count: number) {
- this.totalEnemiesSpawned = count;
- }
-
- public testEnemyDetection() {
- // 测试敌人检测功能
- this.getEnemyStatus();
- }
-
- public testComponentAccess() {
- // 测试组件访问
- if (this.enemyController) {
- // 组件访问正常
- }
- }
-
- public testEnemyAttackWall() {
- if (!this.enemyController) return;
-
- const currentHealth = this.enemyController.getCurrentWallHealth();
- const testDamage = 50;
-
- this.enemyController.damageWall(testDamage);
-
- const newHealth = this.enemyController.getCurrentWallHealth();
- }
- onDestroy() {
- // 清理GamePause事件监听
- const eventBus = EventBus.getInstance();
- eventBus.off(GameEvents.GAME_SUCCESS, this.onGameSuccessEvent, this);
- eventBus.off(GameEvents.GAME_DEFEAT, this.onGameDefeatEvent, this);
- eventBus.off('ENEMY_KILLED', this.onEnemyKilledEvent, this);
- // 清理按钮事件监听
- if (this.gameSuccessUI) {
- const buttons = this.gameSuccessUI.getComponentsInChildren(Button);
- buttons.forEach(button => {
- button.node.off(Button.EventType.CLICK);
- });
- }
- if (this.gameDefeatUI) {
- const buttons = this.gameDefeatUI.getComponentsInChildren(Button);
- buttons.forEach(button => {
- button.node.off(Button.EventType.CLICK);
- });
- }
- }
- // === 加载当前关卡配置 ===
- public async loadCurrentLevelConfig() {
- if (!this.saveDataManager || !this.levelConfigManager) return;
-
- const currentLevel = this.saveDataManager.getCurrentLevel();
-
- try {
- const levelConfig = await this.levelConfigManager.getLevelConfig(currentLevel);
- if (levelConfig) {
- this.applyLevelConfig(levelConfig);
- } else {
- console.warn(`关卡 ${currentLevel} 配置加载失败`);
- }
- } catch (error) {
- console.error(`关卡 ${currentLevel} 配置加载错误:`, error);
- }
- }
-
- private applyLevelConfig(levelConfig: any) {
- // 应用关卡配置
-
- // 如果有武器配置,应用武器
- if (levelConfig.weapons && Array.isArray(levelConfig.weapons)) {
- // 应用武器配置
- }
-
- // 如果有波次配置,设置敌人波次
- if (levelConfig.waves && Array.isArray(levelConfig.waves)) {
- this.levelWaves = levelConfig.waves;
- this.currentWave = 1;
-
- // 计算本关卡总敌人数
- this.levelTotalEnemies = 0;
- for (const wave of this.levelWaves) {
- for (const enemy of wave.enemies || []) {
- this.levelTotalEnemies += enemy.count || 0;
- }
- }
-
- // 通知 EnemyController 初始化第一波数据及 UI
- if (this.enemyController) {
- const totalWaves = this.levelWaves.length;
- const firstWaveEnemies = this.levelWaves.length > 0 && this.levelWaves[0].enemies ?
- this.levelWaves[0].enemies.reduce((t: number, g: any) => t + (g.count || 0), 0) : 0;
- this.enemyController.startWave(1, totalWaves, firstWaveEnemies);
- // 同步 GameManager 当前波敌人数,避免剩余敌人数计算出错
- this.setCurrentWave(1, firstWaveEnemies);
- }
- }
- }
- // === 获取当前关卡信息 ===
- public async getCurrentLevelInfo() {
- 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,
- playerData: this.saveDataManager ? {
- coins: this.saveDataManager.getCoins(),
- diamonds: this.saveDataManager.getDiamonds(),
- gems: this.saveDataManager.getGems(),
- playerLevel: this.saveDataManager.getPlayerLevel()
- } : null
- };
- }
- // === 更新波次显示 ===
- private updateWaveDisplay() {
- // UI 更新交由 EnemyController 处理
- }
- // === 更新敌人数量显示 ===
- private updateEnemyCountDisplay() {
- // UI 更新交由 EnemyController 处理
- }
- // === 设置当前波次 ===
- public setCurrentWave(wave: number, enemyCount: number = 0) {
- this.currentWave = wave;
- this.currentWaveEnemyCount = 0; // 重置当前击杀数
- this.currentWaveTotalEnemies = enemyCount; // 设置该波次总敌人数
- if (this.enemyController) {
- const totalWaves = this.levelWaves?.length || 1;
- this.enemyController.startWave(wave, totalWaves, enemyCount);
- }
- }
- // === 更新当前波次敌人数量 ===
- public updateCurrentWaveEnemyCount(count: number) {
- this.currentWaveEnemyCount = count;
- }
- // === 获取当前波次 ===
- public getCurrentWave(): number {
- return this.currentWave;
- }
- // === 获取当前波次敌人数量 ===
- public getCurrentWaveEnemyCount(): number {
- return this.currentWaveEnemyCount;
- }
- // === 获取当前波次总敌人数量 ===
- public getCurrentWaveTotalEnemies(): number {
- return this.currentWaveTotalEnemies;
- }
- // === 进入下一波 ===
- public nextWave() {
- this.currentWave++;
- // 根据关卡配置获取下一波敌人数
- let enemyTotal = 0;
- if (this.levelWaves && this.levelWaves.length >= this.currentWave) {
- const waveCfg = this.levelWaves[this.currentWave - 1];
- if (waveCfg && waveCfg.enemies) {
- enemyTotal = waveCfg.enemies.reduce((t: number, g: any) => t + (g.count || 0), 0);
- }
- }
- this.setCurrentWave(this.currentWave, enemyTotal);
- }
- /** 显示下一波提示并在短暂延迟后开始下一波 */
- private showNextWavePrompt() {
- this.showBlockSelectionForNextWave(); // 使用新的方法
- }
- // 显示方块选择UI用于下一波
- private showBlockSelectionForNextWave() {
- // 如果游戏已经结束,不显示方块选择UI
- if (this.isGameOver()) {
- const gamePause = GamePause.getInstance();
- console.warn('[GameManager] 游戏已经结束(胜利或失败),不显示下一波方块选择UI!当前状态:', gamePause.getCurrentState());
- return;
- }
-
- if (this.blockSelectionComponent) {
- this.blockSelectionComponent.showBlockSelection(true);
- this.preparingNextWave = true;
- // 状态已在onEnemyKilledEvent中设置,这里不需要重复设置
- // this.currentState = GameState.BLOCK_SELECTION;
-
- // 使用GamePause来暂停游戏
- const gamePause = GamePause.getInstance();
- if (gamePause) {
- gamePause.pauseGame();
- }
- }
- }
- /** 敌人被消灭时由 EnemyController 调用 */
- public onEnemyKilled() {
- // 直接调用GamePause来处理
- const gamePause = GamePause.getInstance();
- gamePause.onEnemyKilled();
- }
- /** 每击杀敌人调用,能量 +1,并更新进度条。满值时弹出技能选择界面 */
- private incrementEnergy() {
- this.energyPoints = Math.min(this.energyPoints + 1, this.ENERGY_MAX);
- this.updateEnergyBar();
- if (this.energyPoints >= this.ENERGY_MAX) {
- this.onEnergyFull();
- }
- }
- /** 更新能量条显示 */
- private updateEnergyBar() {
- if (this.energyBar) {
- this.energyBar.progress = this.energyPoints / this.ENERGY_MAX;
- }
- }
- /** 能量满时触发 */
- private onEnergyFull() {
- console.log(`[GameManager] onEnergyFull 被调用,当前状态: ${this.currentState}, pendingSkillSelection: ${this.pendingSkillSelection}`);
-
- if (this.currentState === GameState.BLOCK_SELECTION) {
- this.pendingSkillSelection = true;
- console.log('[GameManager] 当前处于方块选择状态,暂存技能选择请求');
- return;
- }
-
- if (this.selectSkillUI && !this.selectSkillUI.active) {
- console.log('[GameManager] 直接弹出技能选择UI');
- // 暂停游戏后再弹出 UI
- this.pauseGame();
- this.selectSkillUI.active = true;
- }
- }
- /** 供外部调用:重置能量值并刷新显示 */
- public resetEnergy() {
- this.energyPoints = 0;
- this.updateEnergyBar();
- }
- /* ========= 墙体血量 / 等级相关 ========= */
- private wallHpMap: Record<number, number> = {
- 1: 100,
- 2: 1000,
- 3: 1200,
- 4: 1500,
- 5: 2000
- };
- /** 根据等级获取墙体血量 */
- public getWallHealthByLevel(level: number): number {
- return this.wallHpMap[level] || (100 + (level - 1) * 200);
- }
- /** 获取当前墙壁等级 */
- public getCurrentWallLevel(): number {
- return this.saveDataManager?.getPlayerData().playerLevel || 1;
- }
- /** 获取当前墙体血量 */
- public getCurrentWallHealth(): number {
- return this.saveDataManager?.getPlayerData().wallBaseHealth || this.getWallHealthByLevel(1);
- }
- /** 升级墙体等级,返回升级后信息,失败返回null */
- public upgradeWallLevel(): { currentLevel: number; currentHp: number; nextLevel: number; nextHp: number } | null {
- if (!this.saveDataManager) return null;
- const pd = this.saveDataManager.getPlayerData();
- const curLvl = pd.playerLevel || 1;
- if (curLvl >= 5) return null; // 已达最高级
- const newLvl = curLvl + 1;
- const newHp = this.getWallHealthByLevel(newLvl);
- pd.playerLevel = newLvl;
- pd.wallBaseHealth = newHp;
- this.saveDataManager.savePlayerData(true);
- // 更新内存中的数值
- this.wallHealth = newHp;
- if (this.enemyController) {
- this.enemyController.wallHealth = newHp;
- this.enemyController.updateWallHealthDisplay?.();
- }
- return {
- currentLevel: newLvl,
- currentHp: newHp,
- nextLevel: newLvl + 1,
- nextHp: this.getWallHealthByLevel(newLvl + 1)
- };
- }
- // 初始化GameBlockSelection组件
- private initGameBlockSelection() {
- if (this.gameBlockSelection) {
- this.blockSelectionComponent = this.gameBlockSelection.getComponent(GameBlockSelection);
- if (this.blockSelectionComponent) {
- // 设置确认回调
- this.blockSelectionComponent.setConfirmCallback(() => {
- this.handleConfirmAction();
- });
- }
- }
- }
- // 处理确认操作(替代原来的onConfirmButtonClicked)
- private handleConfirmAction() {
- if (this.preparingNextWave) {
- this.preparingNextWave = false;
- this.currentState = GameState.PLAYING;
-
- this.enemyController.showStartWavePromptUI(); // 弹 startWaveUI 后自动 startGame()
- this.nextWave(); // 更新 wave 计数 & total
-
- // 方块选择结束后,如果有待弹出技能选择,则弹出
- if (this.pendingSkillSelection) {
- this.pendingSkillSelection = false;
- console.log('[GameManager] 检测到待弹出技能选择,现在弹出技能选择UI');
- if (this.selectSkillUI && !this.selectSkillUI.active) {
- this.pauseGame();
- this.selectSkillUI.active = true;
- }
- }
- return;
- }
- // ---------- 首波逻辑(原有代码) ----------
- this.startGame();
- }
- }
|