import { _decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, Vec2, UITransform, find, Rect, Label, Color, Size, Sprite, SpriteFrame, resources, Button } from 'cc'; import { ConfigManager, WeaponConfig } from '../Core/ConfigManager'; const { ccclass, property } = _decorator; @ccclass('BlockManager') export class BlockManager extends Component { // 预制体数组,存储5个预制体 @property([Prefab]) public blockPrefabs: Prefab[] = []; // 网格容器节点 @property({ type: Node, tooltip: '拖拽GridContainer节点到这里' }) public gridContainer: Node = null; // 方块容器节点(kuang) @property({ type: Node, tooltip: '拖拽kuang节点到这里' }) public kuangContainer: Node = null; // 金币标签节点 @property({ type: Node, tooltip: '拖拽CoinLabel节点到这里' }) public coinLabelNode: Node = null; // 已放置方块容器节点 @property({ type: Node, tooltip: '拖拽PlacedBlocks节点到这里(Canvas/GameLevelUI/PlacedBlocks)' }) public placedBlocksContainer: Node = null; // 游戏是否已开始 public gameStarted: boolean = false; // 方块移动冷却时间(秒) @property({ tooltip: '游戏开始后方块移动的冷却时间(秒)' }) public blockMoveCooldown: number = 1; // 玩家金币数量 private playerCoins: number = 69999; // 方块价格标签映射 private blockPriceMap: Map = new Map(); // 已经生成的块 private blocks: Node[] = []; // 当前拖拽的块 private currentDragBlock: Node | null = null; // 拖拽起始位置 private startPos = new Vec2(); // 块的起始位置 private blockStartPos: Vec3 = new Vec3(); // 网格占用情况,用于控制台输出 private gridOccupationMap: number[][] = []; // 网格行数和列数 private readonly GRID_ROWS = 6; private readonly GRID_COLS = 11; // 是否已初始化网格信息 private gridInitialized = false; // 存储网格节点信息 private gridNodes: Node[][] = []; // 网格间距 private gridSpacing = 54; // 不参与占用的节点名称列表 private readonly NON_BLOCK_NODES: string[] = ['Weapon', 'Price']; // 临时保存方块的原始占用格子 private tempRemovedOccupiedGrids: { block: Node, occupiedGrids: { row: number, col: number }[] }[] = []; // 方块原始位置(在kuang中的位置) private originalPositions: Map = new Map(); // 方块当前所在的区域 private blockLocations: Map = new Map(); // 方块移动冷却状态管理 private blockCooldowns: Map = new Map(); // 存储每个方块的冷却结束时间 private globalCooldownEndTime: number = 0; // 全局冷却结束时间 // 配置管理器 private configManager: ConfigManager = null; // 方块武器配置映射 private blockWeaponConfigs: Map = new Map(); // 刷新方块按钮节点(ann003) @property({ type: Node, tooltip: '拖拽BlockSelectionUI/diban/ann003按钮节点到这里' }) public refreshButton: Node = null; // 检查方块是否可以移动(冷却检查) private canMoveBlock(block: Node): boolean { if (!this.gameStarted) { // 游戏未开始(备战阶段),可以自由移动 return true; } const currentTime = Date.now() / 1000; // 转换为秒 // 检查全局冷却 if (currentTime < this.globalCooldownEndTime) { const remainingTime = Math.ceil(this.globalCooldownEndTime - currentTime); return false; } return true; } // 设置方块移动冷却 private setBlockCooldown(block: Node) { if (!this.gameStarted) { // 游戏未开始,不设置冷却 return; } const currentTime = Date.now() / 1000; // 转换为秒 const cooldownEndTime = currentTime + this.blockMoveCooldown; // 设置全局冷却 this.globalCooldownEndTime = cooldownEndTime; } // 清除所有冷却(游戏重置时调用) public clearAllCooldowns() { this.blockCooldowns.clear(); this.globalCooldownEndTime = 0; } start() { // 获取配置管理器 this.configManager = ConfigManager.getInstance(); if (!this.configManager) { console.error('无法获取ConfigManager实例'); } // 如果没有指定GridContainer,尝试找到它 if (!this.gridContainer) { this.gridContainer = find('Canvas/GameLevelUI/GameArea/GridContainer'); if (!this.gridContainer) { console.error('找不到GridContainer节点'); return; } } // 如果没有指定kuangContainer,尝试找到它 if (!this.kuangContainer) { this.kuangContainer = find('Canvas/GameLevelUI/BlockSelectionUI/diban/kuang'); if (!this.kuangContainer) { console.error('找不到kuang节点'); return; } } // 如果没有指定coinLabelNode,尝试找到它 if (!this.coinLabelNode) { this.coinLabelNode = find('Canvas/GameLevelUI/CoinNode/CoinLabel'); if (!this.coinLabelNode) { console.error('找不到CoinLabel节点'); return; } } // 如果没有指定placedBlocksContainer,尝试找到它 if (!this.placedBlocksContainer) { this.placedBlocksContainer = find('Canvas/GameLevelUI/PlacedBlocks'); } // 确保有PlacedBlocks节点用于存放已放置的方块 this.ensurePlacedBlocksNode(); // 初始化玩家金币显示 this.updateCoinDisplay(); // 初始化网格信息 this.initGridInfo(); // 初始化网格占用情况 this.initGridOccupationMap(); if (this.refreshButton) { const btn = this.refreshButton.getComponent(Button); if (btn) { this.refreshButton.on(Button.EventType.CLICK, this.onRefreshButtonClicked, this); } else { // 兼容没有 Button 组件的情况 this.refreshButton.on(Node.EventType.TOUCH_END, this.onRefreshButtonClicked, this); } } // 等待配置加载完成后生成方块 this.scheduleOnce(() => { this.generateRandomBlocksInKuang(); }, 0.5); } // 确保有PlacedBlocks节点 ensurePlacedBlocksNode() { // 如果已经通过拖拽设置了节点,直接使用 if (this.placedBlocksContainer && this.placedBlocksContainer.isValid) { return; } // 尝试查找节点 this.placedBlocksContainer = find('Canvas/GameLevelUI/PlacedBlocks'); if (this.placedBlocksContainer) { return; } // 如果找不到,创建新节点 const gameLevelUI = find('Canvas/GameLevelUI'); if (!gameLevelUI) { console.error('找不到GameLevelUI节点,无法创建PlacedBlocks'); return; } this.placedBlocksContainer = new Node('PlacedBlocks'); gameLevelUI.addChild(this.placedBlocksContainer); if (!this.placedBlocksContainer.getComponent(UITransform)) { this.placedBlocksContainer.addComponent(UITransform); } console.log('已在GameLevelUI下创建PlacedBlocks节点'); } // 初始化网格信息 initGridInfo() { if (!this.gridContainer || this.gridInitialized) return; this.gridNodes = []; for (let row = 0; row < this.GRID_ROWS; row++) { this.gridNodes[row] = []; } for (let i = 0; i < this.gridContainer.children.length; i++) { const grid = this.gridContainer.children[i]; if (grid.name.startsWith('Grid_')) { const parts = grid.name.split('_'); if (parts.length === 3) { const row = parseInt(parts[1]); const col = parseInt(parts[2]); if (row >= 0 && row < this.GRID_ROWS && col >= 0 && col < this.GRID_COLS) { this.gridNodes[row][col] = grid; } } } } if (this.GRID_ROWS > 1 && this.GRID_COLS > 0) { if (this.gridNodes[0][0] && this.gridNodes[1][0]) { const pos1 = this.gridNodes[0][0].position; const pos2 = this.gridNodes[1][0].position; this.gridSpacing = Math.abs(pos2.y - pos1.y); } } this.gridInitialized = true; } // 初始化网格占用情况 initGridOccupationMap() { this.gridOccupationMap = []; for (let row = 0; row < this.GRID_ROWS; row++) { const rowArray: number[] = []; for (let col = 0; col < this.GRID_COLS; col++) { rowArray.push(0); } this.gridOccupationMap.push(rowArray); } } // 在kuang下随机生成三个方块 private generateRandomBlocksInKuang() { this.clearBlocks(); // 检查配置管理器是否可用 if (!this.configManager || !this.configManager.isConfigLoaded()) { console.warn('配置管理器未初始化或配置未加载完成,延迟生成方块'); this.scheduleOnce(() => { this.generateRandomBlocksInKuang(); }, 1.0); return; } if (this.blockPrefabs.length === 0) { console.error('没有可用的预制体'); return; } const kuangNode = this.kuangContainer; if (!kuangNode) { console.error('找不到kuang节点'); return; } const offsets = [ new Vec3(-200, 0, 0), new Vec3(0, 0, 0), new Vec3(200, 0, 0) ]; const dbNodes = [ kuangNode.getChildByName('db01'), kuangNode.getChildByName('db02'), kuangNode.getChildByName('db03') ]; console.log('开始在kuang容器中生成随机武器方块'); for (let i = 0; i < 3; i++) { // 获取随机武器配置 const weaponConfig = this.configManager.getRandomWeapon(); if (!weaponConfig) { console.error(`无法获取第 ${i + 1} 个武器配置`); continue; } // 基于武器配置选择合适的预制体 const prefab = this.selectPrefabForWeapon(weaponConfig); if (!prefab) { console.error(`无法为武器 ${weaponConfig.name} 选择合适的预制体`); continue; } const block = instantiate(prefab); kuangNode.addChild(block); block.position = offsets[i]; // 设置方块名称 block.name = `WeaponBlock_${weaponConfig.id}`; // 保存武器配置到方块 this.blockWeaponConfigs.set(block, weaponConfig); block['weaponConfig'] = weaponConfig; block['weaponId'] = weaponConfig.id; this.originalPositions.set(block, offsets[i].clone()); this.blockLocations.set(block, 'kuang'); this.blocks.push(block); if (dbNodes[i]) { const priceNode = dbNodes[i].getChildByName('Price'); if (priceNode) { this.blockPriceMap.set(block, priceNode); priceNode.active = true; // 根据武器稀有度设置价格 this.setBlockPriceByRarity(priceNode, weaponConfig.rarity); } this.associateDbNodeWithBlock(block, dbNodes[i]); } // 设置方块的武器外观 this.setupBlockWeaponVisual(block, weaponConfig); this.setupDragEvents(block); } this.updateCoinDisplay(); } // 将db节点与方块关联 associateDbNodeWithBlock(block: Node, dbNode: Node) { block['dbNode'] = dbNode; block.on(Node.EventType.TRANSFORM_CHANGED, () => { if (dbNode && block.parent) { const location = this.blockLocations.get(block); if (location === 'grid') { dbNode.active = false; return; } dbNode.active = true; const worldPos = block.parent.getComponent(UITransform).convertToWorldSpaceAR(block.position); const localPos = dbNode.parent.getComponent(UITransform).convertToNodeSpaceAR(worldPos); dbNode.position = new Vec3(localPos.x, localPos.y - 80, localPos.z); } }); } // 更新金币显示 updateCoinDisplay() { if (this.coinLabelNode) { const label = this.coinLabelNode.getComponent(Label); if (label) { label.string = this.playerCoins.toString(); } } } // 获取方块价格 getBlockPrice(block: Node): number { const priceNode = this.blockPriceMap.get(block); if (priceNode) { const label = priceNode.getComponent(Label); if (label) { const price = parseInt(label.string); if (!isNaN(price)) { return price; } } } return 50; } // 隐藏价格标签 hidePriceLabel(block: Node) { const priceNode = this.blockPriceMap.get(block); if (priceNode) { priceNode.active = false; } } // 显示价格标签 showPriceLabel(block: Node) { const priceNode = this.blockPriceMap.get(block); if (priceNode) { priceNode.active = true; } } // 扣除玩家金币 deductPlayerCoins(amount: number): boolean { if (this.playerCoins >= amount) { this.playerCoins -= amount; this.updateCoinDisplay(); return true; } return false; } // 归还玩家金币 refundPlayerCoins(amount: number) { this.playerCoins += amount; this.updateCoinDisplay(); } // 设置拖拽事件 setupDragEvents(block: Node) { block.on(Node.EventType.TOUCH_START, (event: EventTouch) => { if (this.gameStarted && this.blockLocations.get(block) === 'grid') { if (!this.canMoveBlock(block)) { return; } } this.currentDragBlock = block; this.startPos = event.getUILocation(); this.blockStartPos.set(block.position); this.currentDragBlock['startLocation'] = this.blockLocations.get(block); block.setSiblingIndex(block.parent.children.length - 1); this.tempStoreBlockOccupiedGrids(block); }, this); block.on(Node.EventType.TOUCH_MOVE, (event: EventTouch) => { if (this.gameStarted && this.blockLocations.get(block) === 'grid') { if (!this.canMoveBlock(block)) { return; } } if (!this.currentDragBlock) return; const location = event.getUILocation(); const deltaX = location.x - this.startPos.x; const deltaY = location.y - this.startPos.y; this.currentDragBlock.position = new Vec3( this.blockStartPos.x + deltaX, this.blockStartPos.y + deltaY, this.blockStartPos.z ); }, this); block.on(Node.EventType.TOUCH_END, (event: EventTouch) => { if (this.gameStarted && this.blockLocations.get(block) === 'grid') { if (!this.canMoveBlock(block)) { return; } } if (this.currentDragBlock) { this.handleBlockDrop(event); // 如果成功移动且游戏已开始,设置冷却 if (this.gameStarted && this.blockLocations.get(this.currentDragBlock) === 'grid') { this.setBlockCooldown(this.currentDragBlock); } this.currentDragBlock = null; } }, this); block.on(Node.EventType.TOUCH_CANCEL, () => { if (this.currentDragBlock) { this.returnBlockToOriginalPosition(); this.currentDragBlock = null; } }, this); } // 处理方块放下 handleBlockDrop(event: EventTouch) { const touchPos = event.getUILocation(); const startLocation = this.currentDragBlock['startLocation']; if (this.isInKuangArea(touchPos)) { this.returnBlockToKuang(startLocation); } else if (this.tryPlaceBlockToGrid(this.currentDragBlock)) { this.handleSuccessfulPlacement(startLocation); } else { this.returnBlockToOriginalPosition(); } } // 返回方块到kuang区域 returnBlockToKuang(startLocation: string) { const originalPos = this.originalPositions.get(this.currentDragBlock); if (originalPos) { const kuangNode = this.kuangContainer; if (kuangNode && this.currentDragBlock.parent !== kuangNode) { this.currentDragBlock.removeFromParent(); kuangNode.addChild(this.currentDragBlock); } this.currentDragBlock.position = originalPos.clone(); } this.restoreBlockOccupiedGrids(this.currentDragBlock); this.blockLocations.set(this.currentDragBlock, 'kuang'); this.showPriceLabel(this.currentDragBlock); if (startLocation === 'grid') { const price = this.getBlockPrice(this.currentDragBlock); this.refundPlayerCoins(price); this.currentDragBlock['placedBefore'] = false; } const dbNode = this.currentDragBlock['dbNode']; if (dbNode) { dbNode.active = true; this.currentDragBlock.emit(Node.EventType.TRANSFORM_CHANGED); } } // 处理成功放置 handleSuccessfulPlacement(startLocation: string) { const price = this.getBlockPrice(this.currentDragBlock); if (startLocation === 'grid') { this.clearTempStoredOccupiedGrids(this.currentDragBlock); this.blockLocations.set(this.currentDragBlock, 'grid'); this.hidePriceLabel(this.currentDragBlock); const dbNode = this.currentDragBlock['dbNode']; if (dbNode) { dbNode.active = false; } // 立即将方块移动到PlacedBlocks节点下,不等游戏开始 this.moveBlockToPlacedBlocks(this.currentDragBlock); // 如果游戏已开始,添加锁定视觉提示 if (this.gameStarted) { this.addLockedVisualHint(this.currentDragBlock); } } else { if (this.deductPlayerCoins(price)) { this.clearTempStoredOccupiedGrids(this.currentDragBlock); this.blockLocations.set(this.currentDragBlock, 'grid'); this.hidePriceLabel(this.currentDragBlock); const dbNode = this.currentDragBlock['dbNode']; if (dbNode) { dbNode.active = false; } this.currentDragBlock['placedBefore'] = true; // 立即将方块移动到PlacedBlocks节点下,不等游戏开始 this.moveBlockToPlacedBlocks(this.currentDragBlock); // 如果游戏已开始,添加锁定视觉提示 if (this.gameStarted) { this.addLockedVisualHint(this.currentDragBlock); } } else { this.returnBlockToOriginalPosition(); } } } // 返回方块到原位置 returnBlockToOriginalPosition() { const currentLocation = this.blockLocations.get(this.currentDragBlock); if (currentLocation === 'kuang') { const originalPos = this.originalPositions.get(this.currentDragBlock); if (originalPos) { this.currentDragBlock.position = originalPos.clone(); } } else { this.currentDragBlock.position = this.blockStartPos.clone(); } this.restoreBlockOccupiedGrids(this.currentDragBlock); this.showPriceLabel(this.currentDragBlock); const dbNode = this.currentDragBlock['dbNode']; if (dbNode) { dbNode.active = true; this.currentDragBlock.emit(Node.EventType.TRANSFORM_CHANGED); } } // 检查是否在kuang区域内 isInKuangArea(touchPos: Vec2): boolean { if (!this.kuangContainer) return false; const kuangTransform = this.kuangContainer.getComponent(UITransform); if (!kuangTransform) return false; const kuangBoundingBox = new Rect( this.kuangContainer.worldPosition.x - kuangTransform.width * kuangTransform.anchorX, this.kuangContainer.worldPosition.y - kuangTransform.height * kuangTransform.anchorY, kuangTransform.width, kuangTransform.height ); return kuangBoundingBox.contains(new Vec2(touchPos.x, touchPos.y)); } // 临时保存方块占用的网格 tempStoreBlockOccupiedGrids(block: Node) { const occupiedGrids = block['occupiedGrids']; if (!occupiedGrids || occupiedGrids.length === 0) return; this.tempRemovedOccupiedGrids.push({ block: block, occupiedGrids: [...occupiedGrids] }); for (const grid of occupiedGrids) { if (grid.row >= 0 && grid.row < this.GRID_ROWS && grid.col >= 0 && grid.col < this.GRID_COLS) { this.gridOccupationMap[grid.row][grid.col] = 0; } } block['occupiedGrids'] = []; } // 恢复方块原来的占用状态 restoreBlockOccupiedGrids(block: Node) { const index = this.tempRemovedOccupiedGrids.findIndex(item => item.block === block); if (index === -1) return; const savedItem = this.tempRemovedOccupiedGrids[index]; for (const grid of savedItem.occupiedGrids) { if (grid.row >= 0 && grid.row < this.GRID_ROWS && grid.col >= 0 && grid.col < this.GRID_COLS) { this.gridOccupationMap[grid.row][grid.col] = 1; } } block['occupiedGrids'] = [...savedItem.occupiedGrids]; this.tempRemovedOccupiedGrids.splice(index, 1); } // 清除临时保存的占用状态 clearTempStoredOccupiedGrids(block: Node) { const index = this.tempRemovedOccupiedGrids.findIndex(item => item.block === block); if (index === -1) return; this.tempRemovedOccupiedGrids.splice(index, 1); } // 尝试将方块放置到网格中 tryPlaceBlockToGrid(block: Node): boolean { if (!this.gridContainer || !this.gridInitialized) return false; let b1Node = block; if (block.name !== 'B1') { b1Node = block.getChildByName('B1'); if (!b1Node) { return false; } } const b1WorldPos = b1Node.parent.getComponent(UITransform).convertToWorldSpaceAR(b1Node.position); const gridPos = this.gridContainer.getComponent(UITransform).convertToNodeSpaceAR(b1WorldPos); const gridSize = this.gridContainer.getComponent(UITransform).contentSize; const halfWidth = gridSize.width / 2; const halfHeight = gridSize.height / 2; const tolerance = this.gridSpacing * 0.5; if (gridPos.x < -halfWidth - tolerance || gridPos.x > halfWidth + tolerance || gridPos.y < -halfHeight - tolerance || gridPos.y > halfHeight + tolerance) { return false; } const nearestGrid = this.findNearestGridNode(gridPos); if (!nearestGrid) { return false; } return this.tryPlaceBlockToSpecificGrid(block, nearestGrid); } // 找到最近的网格节点 findNearestGridNode(position: Vec3): Node { if (!this.gridContainer || !this.gridInitialized) return null; let nearestNode: Node = null; let minDistance = Number.MAX_VALUE; for (let row = 0; row < this.GRID_ROWS; row++) { for (let col = 0; col < this.GRID_COLS; col++) { const grid = this.gridNodes[row][col]; if (grid) { const distance = Vec3.distance(position, grid.position); if (distance < minDistance) { minDistance = distance; nearestNode = grid; } } } } if (minDistance > this.gridSpacing * 2) { return null; } return nearestNode; } // 尝试将方块放置到指定的网格节点 tryPlaceBlockToSpecificGrid(block: Node, targetGrid: Node): boolean { let b1Node = block; if (block.name !== 'B1') { b1Node = block.getChildByName('B1'); if (!b1Node) { return false; } } if (!this.canPlaceBlockAt(block, targetGrid)) { return false; } const gridCenterWorldPos = this.gridContainer.getComponent(UITransform).convertToWorldSpaceAR(targetGrid.position); const targetWorldPos = gridCenterWorldPos.clone(); const b1LocalPos = b1Node.position.clone(); let rootTargetWorldPos; if (b1Node === block) { rootTargetWorldPos = targetWorldPos.clone(); } else { rootTargetWorldPos = new Vec3( targetWorldPos.x - b1LocalPos.x, targetWorldPos.y - b1LocalPos.y, targetWorldPos.z ); } const rootTargetLocalPos = block.parent.getComponent(UITransform).convertToNodeSpaceAR(rootTargetWorldPos); block.position = rootTargetLocalPos; this.markOccupiedPositions(block, targetGrid); return true; } // 检查方块是否可以放置在指定位置 canPlaceBlockAt(block: Node, targetGrid: Node): boolean { if (!this.gridInitialized) return false; const targetRowCol = this.getGridRowCol(targetGrid); if (!targetRowCol) return false; const parts = this.getBlockParts(block); for (const part of parts) { const row = targetRowCol.row - part.y; const col = targetRowCol.col + part.x; if (row < 0 || row >= this.GRID_ROWS || col < 0 || col >= this.GRID_COLS) { return false; } if (this.gridOccupationMap[row][col] === 1) { return false; } } return true; } // 获取网格行列索引 getGridRowCol(gridNode: Node): { row: number, col: number } | null { if (!gridNode || !gridNode.name.startsWith('Grid_')) return null; const parts = gridNode.name.split('_'); if (parts.length === 3) { const row = parseInt(parts[1]); const col = parseInt(parts[2]); if (row >= 0 && row < this.GRID_ROWS && col >= 0 && col < this.GRID_COLS) { return { row, col }; } } return null; } // 获取方块的所有部分节点及其相对坐标 getBlockParts(block: Node): { node: Node, x: number, y: number }[] { const parts: { node: Node, x: number, y: number }[] = []; parts.push({ node: block, x: 0, y: 0 }); this.findBlockParts(block, parts, 0, 0); return parts; } // 递归查找方块的所有部分 findBlockParts(node: Node, result: { node: Node, x: number, y: number }[], parentX: number, parentY: number) { for (let i = 0; i < node.children.length; i++) { const child = node.children[i]; if (this.NON_BLOCK_NODES.indexOf(child.name) !== -1) { continue; } let x = parentX; let y = parentY; const match = child.name.match(/^\((-?\d+),(-?\d+)\)$/); if (match) { x = parseInt(match[1]); y = parseInt(match[2]); result.push({ node: child, x, y }); } else if (child.name.startsWith('B')) { const relativeX = Math.round(child.position.x / this.gridSpacing); const relativeY = -Math.round(child.position.y / this.gridSpacing); x = parentX + relativeX; y = parentY + relativeY; result.push({ node: child, x, y }); } this.findBlockParts(child, result, x, y); } } // 标记方块占用的格子 markOccupiedPositions(block: Node, targetGrid: Node) { if (!this.gridInitialized) return; const targetRowCol = this.getGridRowCol(targetGrid); if (!targetRowCol) return; const parts = this.getBlockParts(block); block['occupiedGrids'] = []; for (const part of parts) { const row = targetRowCol.row - part.y; const col = targetRowCol.col + part.x; if (row >= 0 && row < this.GRID_ROWS && col >= 0 && col < this.GRID_COLS) { this.gridOccupationMap[row][col] = 1; block['occupiedGrids'] = block['occupiedGrids'] || []; block['occupiedGrids'].push({ row, col }); } } } // 清除方块 clearBlocks() { const blocksToRemove = []; for (const block of this.blocks) { if (block.isValid) { const location = this.blockLocations.get(block); if (location === 'kuang') { blocksToRemove.push(block); } } } for (const block of blocksToRemove) { const dbNode = block['dbNode']; if (dbNode && dbNode.isValid) { block.off(Node.EventType.TRANSFORM_CHANGED); const kuangNode = this.kuangContainer; if (kuangNode) { const dbName = dbNode.name; if (!kuangNode.getChildByName(dbName)) { dbNode.parent = kuangNode; } } } const index = this.blocks.indexOf(block); if (index !== -1) { this.blocks.splice(index, 1); } this.originalPositions.delete(block); this.blockLocations.delete(block); this.blockPriceMap.delete(block); // 清理武器配置映射 this.blockWeaponConfigs.delete(block); block.destroy(); } } // 游戏开始时调用 onGameStart() { this.gameStarted = true; for (const block of this.blocks) { if (block.isValid) { const location = this.blockLocations.get(block); if (location === 'grid') { this.hidePriceLabel(block); const dbNode = block['dbNode']; if (dbNode) { dbNode.active = false; } this.moveBlockToPlacedBlocks(block); this.addLockedVisualHint(block); } } } } // 游戏重置时调用 onGameReset() { this.gameStarted = false; this.clearAllCooldowns(); } // 添加视觉提示,表明方块已锁定 addLockedVisualHint(block: Node) { const children = block.children; for (let i = 0; i < children.length; i++) { const child = children[i]; if (this.NON_BLOCK_NODES.indexOf(child.name) !== -1) { continue; } child.setScale(new Vec3(0.95, 0.95, 1)); } } // 将方块移动到PlacedBlocks节点下 moveBlockToPlacedBlocks(block: Node) { if (!this.placedBlocksContainer) { console.error('PlacedBlocks容器未设置'); return; } if (!this.placedBlocksContainer.isValid) { console.error('PlacedBlocks容器已失效'); return; } 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); } // 根据武器配置选择合适的预制体 private selectPrefabForWeapon(weaponConfig: WeaponConfig): Prefab | null { if (this.blockPrefabs.length === 0) { return null; } // 根据武器类型或稀有度选择预制体 // 这里可以根据实际需求来选择不同的预制体 // 目前简单地随机选择一个预制体 const randomIndex = Math.floor(Math.random() * this.blockPrefabs.length); return this.blockPrefabs[randomIndex]; } // 根据稀有度设置方块价格 private setBlockPriceByRarity(priceNode: Node, rarity: string) { const label = priceNode.getComponent(Label); if (!label) { return; } let price: number; switch (rarity) { case 'common': price = 50; break; case 'uncommon': price = 100; break; case 'rare': price = 200; break; case 'epic': price = 350; break; case 'legendary': price = 500; break; default: price = 50; } label.string = price.toString(); } // 设置方块的武器外观 private setupBlockWeaponVisual(block: Node, weaponConfig: WeaponConfig) { // 设置方块的稀有度颜色 this.setBlockRarityColor(block, weaponConfig.rarity); // 加载武器图标 this.loadWeaponIcon(block, weaponConfig); } // 设置方块稀有度颜色 private setBlockRarityColor(block: Node, rarity: string) { const sprite = block.getComponent(Sprite); if (!sprite) { return; } // 根据稀有度设置颜色 let color: Color; switch (rarity) { case 'common': color = new Color(255, 255, 255); // 白色 break; case 'uncommon': color = new Color(0, 255, 0); // 绿色 break; case 'rare': color = new Color(0, 100, 255); // 蓝色 break; case 'epic': color = new Color(160, 32, 240); // 紫色 break; case 'legendary': color = new Color(255, 165, 0); // 橙色 break; default: color = new Color(255, 255, 255); // 默认白色 } sprite.color = color; } // 加载武器图标 private loadWeaponIcon(block: Node, weaponConfig: WeaponConfig) { // 根据预制体结构:WeaponBlock -> B1 -> Weapon const b1Node = block.getChildByName('B1'); if (!b1Node) { console.warn('找不到B1节点'); return; } const weaponNode = b1Node.getChildByName('Weapon'); if (!weaponNode) { console.warn('找不到Weapon节点'); return; } const weaponSprite = weaponNode.getComponent(Sprite); if (!weaponSprite) { console.warn('Weapon节点上没有Sprite组件'); return; } // 获取武器配置中的图片路径 const spriteConfig = weaponConfig.visualConfig?.weaponSprites; if (!spriteConfig) { console.warn(`武器 ${weaponConfig.name} 没有配置图片信息`); return; } // 选择合适的图片路径(这里默认使用1x1) const spritePath = spriteConfig['1x1'] || spriteConfig['1x2'] || spriteConfig['2x1'] || spriteConfig['2x2']; if (!spritePath) { console.warn(`武器 ${weaponConfig.name} 没有可用的图片路径`); return; } // 正确的SpriteFrame子资源路径 const spriteFramePath = `${spritePath}/spriteFrame`; // 加载SpriteFrame子资源 resources.load(spriteFramePath, SpriteFrame, (err, spriteFrame) => { if (err) { console.warn(`加载武器图片失败: ${spriteFramePath}`, err); return; } if (weaponSprite && spriteFrame) { weaponSprite.spriteFrame = spriteFrame; } }); } // 根据方块获取武器配置 public getBlockWeaponConfig(block: Node): WeaponConfig | null { return this.blockWeaponConfigs.get(block) || block['weaponConfig'] || null; } // 获取方块的武器ID public getBlockWeaponId(block: Node): string | null { const weaponConfig = this.getBlockWeaponConfig(block); return weaponConfig ? weaponConfig.id : null; } // 刷新方块 - 重新生成三个新的武器方块 public refreshBlocks() { this.generateRandomBlocksInKuang(); } // 刷新按钮点击回调 private onRefreshButtonClicked() { this.refreshBlocks(); } }