import { _decorator, Component, Node, ProgressBar, Label, Vec3, Prefab, instantiate, find, UITransform, BoxCollider2D, RigidBody2D, ERigidBody2DType } from 'cc'; const { ccclass, property } = _decorator; // 前向声明EnemyInstance类型,避免循环引用 class EnemyInstanceType { public health: number; public maxHealth: number; public speed: number; public attackPower: number; public movingDirection: number; public targetY: number; public changeDirectionTime: number; public controller: any; public node: Node; public updateHealthDisplay: () => void; public takeDamage: (damage: number) => void; } @ccclass('EnemyController') export class EnemyController extends Component { // 敌人预制体 @property({ type: Prefab, tooltip: '拖拽Enemy预制体到这里' }) public enemyPrefab: Prefab = null; // 敌人生成参数 @property({ tooltip: '敌人生成间隔(秒)' }) public spawnInterval: number = 3; // 敌人属性 @property({ tooltip: '敌人移动速度' }) public enemySpeed: number = 50; @property({ tooltip: '敌人攻击力' }) public attackPower: number = 10; @property({ tooltip: '敌人生命值' }) public health: number = 30; // 墙体属性 @property({ tooltip: '墙体初始血量' }) public wallHealth: number = 1200; @property({ type: Node, tooltip: '墙体血量显示节点' }) public wallHealthNode: Node = null; // 游戏区域边界 - 改为public,让敌人实例可以访问 public gameBounds = { left: 0, right: 0, top: 0, bottom: 0 }; // 活跃的敌人列表 private activeEnemies: Node[] = []; // 游戏是否已开始 private gameStarted: boolean = false; // 墙体节点 private wallNodes: Node[] = []; start() { // 获取游戏区域边界 this.calculateGameBounds(); // 查找墙体节点 this.findWallNodes(); // 初始化墙体血量显示 this.initWallHealthDisplay(); // 确保enemyContainer节点存在 this.ensureEnemyContainer(); } // 计算游戏区域边界 calculateGameBounds() { // 获取GameArea节点 const gameArea = find('Canvas/GameLevelUI/GameArea'); if (!gameArea) { console.error('找不到GameArea节点'); return; } const gameAreaUI = gameArea.getComponent(UITransform); if (!gameAreaUI) { console.error('GameArea节点没有UITransform组件'); return; } // 获取GameArea的尺寸 const areaWidth = gameAreaUI.width; const areaHeight = gameAreaUI.height; // 获取GameArea的世界坐标位置 const worldPos = gameArea.worldPosition; // 计算GameArea的世界坐标边界 this.gameBounds.left = worldPos.x - areaWidth / 2; this.gameBounds.right = worldPos.x + areaWidth / 2; this.gameBounds.bottom = worldPos.y - areaHeight / 2; this.gameBounds.top = worldPos.y + areaHeight / 2; console.log('GameArea Bounds:', this.gameBounds); } // 查找墙体节点 findWallNodes() { // 查找上下左右四个墙体节点 const gameArea = find('Canvas/GameLevelUI/GameArea'); if (gameArea) { const topFence = gameArea.getChildByName('TopFence'); const bottomFence = gameArea.getChildByName('BottomFence'); const leftFence = gameArea.getChildByName('JiguangL'); const rightFence = gameArea.getChildByName('JiguangR'); if (topFence) { this.wallNodes.push(topFence); } if (bottomFence) { this.wallNodes.push(bottomFence); } if (leftFence) this.wallNodes.push(leftFence); if (rightFence) this.wallNodes.push(rightFence); console.log(`找到 ${this.wallNodes.length} 个墙体节点`); } } // 初始化墙体血量显示 initWallHealthDisplay() { if (!this.wallHealthNode) { // 尝试查找墙体血量显示节点 this.wallHealthNode = find('Canvas/GameLevelUI/HeartNode'); } if (this.wallHealthNode) { // 更新墙体血量显示 this.updateWallHealthDisplay(); } else { console.warn('未设置墙体血量显示节点'); } } // 更新墙体血量显示 updateWallHealthDisplay() { if (!this.wallHealthNode) return; // 查找Label组件 const label = this.wallHealthNode.getComponent(Label); if (label) { label.string = this.wallHealth.toString(); } } // 确保enemyContainer节点存在 ensureEnemyContainer() { let enemyContainer = find('Canvas/GameLevelUI/enemyContainer'); // 如果节点不存在,创建一个 if (!enemyContainer) { // 获取GameLevelUI节点 const gameLevelUI = find('Canvas/GameLevelUI'); if (!gameLevelUI) { console.error('找不到GameLevelUI节点,无法创建enemyContainer'); return; } // 创建enemyContainer节点 enemyContainer = new Node('enemyContainer'); gameLevelUI.addChild(enemyContainer); // 确保enemyContainer有UITransform组件 if (!enemyContainer.getComponent(UITransform)) { const uiTransform = enemyContainer.addComponent(UITransform); uiTransform.width = 1000; uiTransform.height = 1000; } console.log('已创建enemyContainer节点'); } } // 游戏开始 startGame() { this.gameStarted = true; // 确保enemyContainer节点存在 this.ensureEnemyContainer(); // 开始生成敌人 this.schedule(this.spawnEnemy, this.spawnInterval); console.log('开始生成敌人'); } // 游戏结束 stopGame() { this.gameStarted = false; // 停止生成敌人 this.unschedule(this.spawnEnemy); // 清除所有敌人 this.clearAllEnemies(); console.log('停止生成敌人'); } // 生成敌人 spawnEnemy() { if (!this.gameStarted || !this.enemyPrefab) return; // 随机决定从上方还是下方生成 const fromTop = Math.random() > 0.5; // 实例化敌人 const enemy = instantiate(this.enemyPrefab); enemy.name = 'Enemy'; // 确保敌人节点名称为Enemy // 添加到场景中 const enemyContainer = find('Canvas/GameLevelUI/enemyContainer'); if (!enemyContainer) { console.error('找不到enemyContainer节点'); return; } enemyContainer.addChild(enemy); // 设置敌人位置 const xPos = this.gameBounds.left + Math.random() * (this.gameBounds.right - this.gameBounds.left); const yPos = fromTop ? this.gameBounds.top + 100 : this.gameBounds.bottom - 100; // 将世界坐标转换为相对于enemyContainer的本地坐标 const localPos = enemyContainer.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(xPos, yPos, 0)); enemy.position = localPos; // 设置敌人属性 - 直接使用组件而不是自定义属性 const enemyComp = enemy.addComponent('EnemyInstance') as any; enemyComp.health = this.health; enemyComp.maxHealth = this.health; enemyComp.speed = this.enemySpeed; enemyComp.attackPower = this.attackPower; enemyComp.movingDirection = Math.random() > 0.5 ? 1 : -1; // 随机初始移动方向 enemyComp.targetY = fromTop ? this.gameBounds.top - 50 : this.gameBounds.bottom + 50; // 目标Y位置 enemyComp.changeDirectionTime = 0; // 下次改变方向的时间 enemyComp.controller = this; // 设置对控制器的引用 // 更新敌人血量显示 enemyComp.updateHealthDisplay(); // 添加到活跃敌人列表 this.activeEnemies.push(enemy); console.log(`生成敌人,当前共有 ${this.activeEnemies.length} 个敌人`); } // 清除所有敌人 clearAllEnemies() { for (const enemy of this.activeEnemies) { if (enemy && enemy.isValid) { enemy.destroy(); } } this.activeEnemies = []; } // 获取所有活跃的敌人 getActiveEnemies(): Node[] { // 过滤掉已经无效的敌人 this.activeEnemies = this.activeEnemies.filter(enemy => enemy && enemy.isValid); return this.activeEnemies; } // 敌人受到伤害 damageEnemy(enemy: Node, damage: number) { if (!enemy || !enemy.isValid) return; // 获取敌人组件 const enemyComp = enemy.getComponent('EnemyInstance') as any; if (!enemyComp) return; // 减少敌人血量 enemyComp.takeDamage(damage); // 检查敌人是否死亡 if (enemyComp.health <= 0) { // 从活跃敌人列表中移除 const index = this.activeEnemies.indexOf(enemy); if (index !== -1) { this.activeEnemies.splice(index, 1); } // 销毁敌人 enemy.destroy(); console.log(`敌人被消灭,剩余 ${this.activeEnemies.length} 个敌人`); } } // 墙体受到伤害 damageWall(damage: number) { // 减少墙体血量 this.wallHealth -= damage; // 更新墙体血量显示 this.updateWallHealthDisplay(); // 检查墙体是否被摧毁 if (this.wallHealth <= 0) { // 游戏结束 this.gameOver(); } } // 游戏结束 gameOver() { // 停止游戏 this.stopGame(); // 通知GameManager游戏结束 const gameManager = find('Canvas').getComponent('GameManager'); if (gameManager) { (gameManager as any).gameOver(); } console.log('游戏结束,墙体被摧毁'); } update(dt: number) { if (!this.gameStarted) return; // 更新所有敌人 for (let i = this.activeEnemies.length - 1; i >= 0; i--) { const enemy = this.activeEnemies[i]; if (!enemy || !enemy.isValid) { this.activeEnemies.splice(i, 1); continue; } // 敌人更新由各自的组件处理 // 不再需要检查敌人是否到达墙体,因为敌人到达游戏区域后会自动攻击 // 敌人的攻击逻辑已经在EnemyInstance中处理 } } }