import { _decorator, Component, Node, Button, Label, find } from 'cc'; import { LevelSessionManager } from '../../Core/LevelSessionManager'; import { BallController } from '../BallController'; import { BlockManager } from '../BlockManager'; import { BlockTag } from './BlockTag'; import { SkillManager } from '../SkillSelection/SkillManager'; import EventBus, { GameEvents } from '../../Core/EventBus'; const { ccclass, property } = _decorator; @ccclass('GameBlockSelection') export class GameBlockSelection extends Component { @property({ type: Node, tooltip: '拖拽diban/ann001按钮节点到这里' }) public addBallButton: Node = null; @property({ type: Node, tooltip: '拖拽diban/ann002按钮节点到这里' }) public addCoinButton: Node = null; @property({ type: Node, tooltip: '拖拽diban/ann003按钮节点到这里' }) public refreshButton: Node = null; @property({ type: Node, tooltip: '拖拽Canvas-001/TopArea/CoinNode/CoinLabel节点到这里' }) public coinLabelNode: Node = null; // 移除toastNode属性,改用事件机制 // @property({ // type: Node, // tooltip: '拖拽Canvas/Toast节点到这里' // }) // public toastNode: Node = null; @property({ type: Node, tooltip: '拖拽Canvas/GameLevelUI/BallController节点到这里' }) public ballControllerNode: Node = null; @property({ type: Node, tooltip: '拖拽Canvas/GameLevelUI/BlockController节点到这里' }) public blockManagerNode: Node = null; @property({ type: Node, tooltip: '拖拽Canvas/GameLevelUI/GameArea/GridContainer节点到这里' }) public gridContainer: Node = null; @property({ type: Node, tooltip: '拖拽confirm按钮节点到这里' }) public confirmButton: Node = null; @property({ type: Node, tooltip: '拖拽Canvas/GameLevelUI/InGameManager节点到这里' }) public inGameManagerNode: Node = null; @property({ type: Node, tooltip: '拖拽Canvas/Camera节点到这里' }) public cameraNode: Node = null; // 按钮费用配置 private readonly ADD_BALL_COST = 80; private readonly ADD_COIN_AMOUNT = 80; private readonly REFRESH_COST = 5; private session: LevelSessionManager = null; private ballController: BallController = null; private blockManager: BlockManager = null; // 回调函数,用于通知GameManager public onConfirmCallback: () => void = null; // 标记是否已初始化 private isInitialized: boolean = false; // 标记是否应该生成方块(只有在onBattle触发后才为true) private shouldGenerateBlocks: boolean = false; onEnable() { console.log('[GameBlockSelection] onEnable() 节点被激活'); // 如果还未初始化,则进行初始化 if (!this.isInitialized) { this.initializeComponent(); } } start() { console.log('[GameBlockSelection] start() 被调用'); // 如果还未初始化,则进行初始化 if (!this.isInitialized) { this.initializeComponent(); } } private initializeComponent() { console.log('[GameBlockSelection] initializeComponent() 开始初始化'); console.log('[GameBlockSelection] 组件节点名称:', this.node.name); console.log('[GameBlockSelection] 组件节点激活状态:', this.node.active); // 获取管理器实例 this.session = LevelSessionManager.inst; // 获取BallController if (this.ballControllerNode) { this.ballController = this.ballControllerNode.getComponent(BallController); } else { console.warn('BallController节点未绑定,请在Inspector中拖拽Canvas/GameLevelUI/BallController节点'); } // 获取BlockManager if (this.blockManagerNode) { this.blockManager = this.blockManagerNode.getComponent(BlockManager); } else { console.warn('BlockManager节点未绑定,请在Inspector中拖拽Canvas/GameLevelUI/BlockController节点'); } // 如果没有指定coinLabelNode,尝试找到它 if (!this.coinLabelNode) { this.coinLabelNode = find('Canvas-001/TopArea/CoinNode/CoinLabel'); } // 初始化金币显示 this.updateCoinDisplay(); // 绑定按钮事件 this.bindButtonEvents(); // 设置事件监听器 this.setupEventListeners(); // 标记为已初始化 this.isInitialized = true; console.log('GameBlockSelection.initializeComponent() 初始化完成'); } // 设置事件监听器 private setupEventListeners() { console.log('[GameBlockSelection] 开始设置事件监听器'); const eventBus = EventBus.getInstance(); console.log('[GameBlockSelection] EventBus实例获取结果:', !!eventBus); // 监听重置方块选择事件 eventBus.on(GameEvents.RESET_BLOCK_SELECTION, this.onResetBlockSelectionEvent, this); console.log('[GameBlockSelection] RESET_BLOCK_SELECTION事件监听器已设置'); // 监听显示方块选择事件 // 监听游戏开始事件,用于标记可以开始生成方块 eventBus.on(GameEvents.GAME_START, this.onGameStartEvent, this); console.log('[GameBlockSelection] GAME_START事件监听器已设置'); console.log('[GameBlockSelection] 事件监听器设置完成,组件节点:', this.node.name); console.log('[GameBlockSelection] 当前节点状态:', this.node.active); } // 处理重置方块选择事件 private onResetBlockSelectionEvent() { console.log('[GameBlockSelection] 接收到重置方块选择事件'); this.resetSelection(); } // 处理游戏开始事件 private onGameStartEvent() { console.log('[GameBlockSelection] 接收到游戏开始事件,允许生成方块'); this.shouldGenerateBlocks = true; } // 绑定按钮事件 private bindButtonEvents() { // 绑定新增小球按钮 if (this.addBallButton) { const btn = this.addBallButton.getComponent(Button); if (btn) { this.addBallButton.on(Button.EventType.CLICK, this.onAddBallClicked, this); } else { this.addBallButton.on(Node.EventType.TOUCH_END, this.onAddBallClicked, this); } } // 绑定增加金币按钮 if (this.addCoinButton) { const btn = this.addCoinButton.getComponent(Button); if (btn) { this.addCoinButton.on(Button.EventType.CLICK, this.onAddCoinClicked, this); } else { this.addCoinButton.on(Node.EventType.TOUCH_END, this.onAddCoinClicked, this); } } // 绑定刷新方块按钮 if (this.refreshButton) { const btn = this.refreshButton.getComponent(Button); if (btn) { this.refreshButton.on(Button.EventType.CLICK, this.onRefreshClicked, this); } else { this.refreshButton.on(Node.EventType.TOUCH_END, this.onRefreshClicked, this); } } // 绑定确认按钮 if (this.confirmButton) { const btn = this.confirmButton.getComponent(Button); if (btn) { this.confirmButton.on(Button.EventType.CLICK, this.onConfirmButtonClicked, this); } else { this.confirmButton.on(Node.EventType.TOUCH_END, this.onConfirmButtonClicked, this); } } } // 新增小球按钮点击 private onAddBallClicked() { // 应用便宜技能效果计算实际费用 const actualCost = this.getActualCost(this.ADD_BALL_COST); if (!this.canSpendCoins(actualCost)) { this.showInsufficientCoinsUI(); return; } // 扣除金币 if (this.session.spendCoins(actualCost)) { this.updateCoinDisplay(); // 通过事件系统创建新的小球 const eventBus = EventBus.getInstance(); eventBus.emit(GameEvents.BALL_CREATE_ADDITIONAL); console.log(`新增小球成功,扣除${actualCost}金币`); } } // 增加金币按钮点击 private onAddCoinClicked() { // 免费增加金币(模拟看广告获得奖励) const coinsToAdd = 80; // 免费获得的金币数量 this.session.addCoins(coinsToAdd); console.log(`通过观看广告免费获得${coinsToAdd}金币`); // 更新显示 this.updateCoinDisplay(); // 可以在这里添加播放奖励动画的逻辑 // MoneyAni.playReward(coinsToAdd, 0); } // 刷新方块按钮点击 private onRefreshClicked() { // 应用便宜技能效果计算实际费用 const actualCost = this.getActualCost(this.REFRESH_COST); if (!this.canSpendCoins(actualCost)) { this.showInsufficientCoinsUI(); return; } // 扣除金币 if (this.session.spendCoins(actualCost)) { this.updateCoinDisplay(); // 刷新方块 if (this.blockManager) { // 找到PlacedBlocks容器 const placedBlocksContainer = find('Canvas/GameLevelUI/PlacedBlocks'); if (placedBlocksContainer) { // 移除已放置方块的标签 BlockTag.removeTagsInContainer(placedBlocksContainer); } // 刷新方块 this.blockManager.refreshBlocks(); console.log(`刷新方块成功,扣除${actualCost}金币`); } else { console.error('找不到BlockManager,无法刷新方块'); } } } // 确认按钮点击 public onConfirmButtonClicked() { // 检查是否有上阵方块 const hasBlocks = this.hasPlacedBlocks(); console.log(`[GameBlockSelection] 检查上阵方块: ${hasBlocks ? '有' : '无'}`); if (!hasBlocks) { this.showNoPlacedBlocksToast(); return; } // 保存已放置的方块 this.preservePlacedBlocks(); // 清理kuang区域的方块(用户期望的行为) if (this.blockManager) { this.blockManager.clearBlocks(); console.log('[GameBlockSelection] 已清理kuang区域的方块'); } // 先回调通知GameManager,让它处理波次逻辑 if (this.onConfirmCallback) { this.onConfirmCallback(); } // 播放下滑diban动画,结束备战进入playing状态 this.playDibanSlideDownAnimation(); } // 播放diban下滑动画 private playDibanSlideDownAnimation() { console.log('[GameBlockSelection] 开始播放diban下滑动画'); // 使用装饰器属性获取Camera节点上的GameStartMove组件 if (!this.cameraNode) { console.warn('[GameBlockSelection] Camera节点未设置,请在Inspector中拖拽Canvas/Camera节点'); return; } const gameStartMove = this.cameraNode.getComponent('GameStartMove'); if (!gameStartMove) { console.warn('[GameBlockSelection] GameStartMove组件未找到'); return; } // 调用GameStartMove的下滑动画方法 (gameStartMove as any).slideDibanDownAndHide(300, 0.3); console.log('[GameBlockSelection] 已调用GameStartMove的diban下滑动画'); } // 保存已放置的方块(从GameManager迁移) private preservePlacedBlocks() { if (this.blockManager) { this.blockManager.onGameStart(); } } // 检查是否有足够金币 private canSpendCoins(amount: number): boolean { return this.session.getCoins() >= amount; } // 计算应用便宜技能效果后的实际费用 private getActualCost(baseCost: number): number { const skillManager = SkillManager.getInstance(); if (skillManager) { const cheaperSkillLevel = skillManager.getSkillLevel('cheaper_units'); return Math.ceil(SkillManager.calculateCheaperUnitsPrice(baseCost, cheaperSkillLevel)); } return baseCost; } // 更新金币显示 private updateCoinDisplay() { if (this.coinLabelNode) { const label = this.coinLabelNode.getComponent(Label); if (label) { const coins = this.session.getCoins(); label.string = coins.toString(); console.log(`[GameBlockSelection] 更新金币显示: ${coins}`); } else { console.warn('[GameBlockSelection] coinLabelNode缺少Label组件'); } } else { console.warn('[GameBlockSelection] coinLabelNode未找到'); } } // 显示金币不足UI private showInsufficientCoinsUI() { // 使用事件机制显示Toast EventBus.getInstance().emit(GameEvents.SHOW_TOAST, { message: '金币不足!', duration: 3.0 }); console.log('金币不足!'); } // === 公共方法:供GameManager调用 === // 生成方块选择(不再控制UI显示,只负责生成方块) public generateBlockSelection() { console.log('[GameBlockSelection] generateBlockSelection开始执行'); // 直接生成方块,不再依赖shouldGenerateBlocks标志 if (this.blockManager) { this.blockManager.refreshBlocks(); console.log('[GameBlockSelection] 生成新的随机方块'); } else { console.warn('[GameBlockSelection] BlockManager未找到,无法生成随机方块'); } // 触发进入备战状态事件 EventBus.getInstance().emit(GameEvents.ENTER_BATTLE_PREPARATION); console.log('[GameBlockSelection] 方块生成完成'); } // 设置确认回调 public setConfirmCallback(callback: () => void) { this.onConfirmCallback = callback; } // 重置方块选择状态 public resetSelection() { console.log('[GameBlockSelection] 重置方块选择状态'); // 重置方块生成标志,等待下次onBattle触发 this.shouldGenerateBlocks = false; console.log('[GameBlockSelection] 重置方块生成标志'); // 注意:不再直接调用blockManager.onGameReset(),因为StartGame.clearGameStates() // 已经通过RESET_BLOCK_MANAGER事件触发了BlockManager的重置,避免重复生成方块 console.log('[GameBlockSelection] BlockManager将通过事件系统自动重置'); // 清理所有方块标签 BlockTag.clearAllTags(); console.log('[GameBlockSelection] 方块标签已清理'); // 更新金币显示 this.updateCoinDisplay(); console.log('[GameBlockSelection] 金币显示已更新'); } // 检查是否有上阵方块 private hasPlacedBlocks(): boolean { // 优先使用BlockManager的方法检查 if (this.blockManager) { return this.blockManager.hasPlacedBlocks(); } // 备用方案:直接检查PlacedBlocks容器 const placedBlocksContainer = find('Canvas/GameLevelUI/PlacedBlocks'); if (!placedBlocksContainer) { console.warn('找不到PlacedBlocks容器'); return false; } // 检查容器中是否有子节点(方块) return placedBlocksContainer.children.length > 0; } // 显示没有上阵方块的Toast提示 private showNoPlacedBlocksToast() { console.log('[GameBlockSelection] 显示未上阵植物提示'); // 使用事件机制显示Toast EventBus.getInstance().emit(GameEvents.SHOW_TOAST, { message: '请至少上阵一个植物!', duration: 3.0 }); console.log('[GameBlockSelection] 请至少上阵一个植物!'); } onDestroy() { // 清理事件监听 const eventBus = EventBus.getInstance(); eventBus.off(GameEvents.RESET_BLOCK_SELECTION, this.onResetBlockSelectionEvent, this); eventBus.off(GameEvents.GAME_START, this.onGameStartEvent, this); } }