import { _decorator, Component, Node, ProgressBar, Label, Vec3, find, UITransform, Collider2D, Contact2DType, IPhysics2DContact, instantiate, resources, Prefab, JsonAsset, RigidBody2D, ERigidBody2DType, BoxCollider2D, CircleCollider2D } from 'cc'; import { sp } from 'cc'; import { DamageNumberAni } from '../Animations/DamageNumberAni'; import { HPBarAnimation } from '../Animations/HPBarAnimation'; import { EnemyComponent } from './EnemyComponent'; import { EnemyAudio } from '../AudioManager/EnemyAudios'; const { ccclass, property } = _decorator; // 前向声明EnemyController接口,避免循环引用 interface EnemyControllerType { gameBounds: { left: number; right: number; top: number; bottom: number; }; damageWall: (damage: number) => void; getComponent: (componentType: any) => any; } // 敌人状态枚举 enum EnemyState { MOVING, // 移动中 ATTACKING, // 攻击中 DEAD // 死亡 } // 单个敌人实例的组件 @ccclass('EnemyInstance') export class EnemyInstance extends Component { // 敌人属性(从配置文件读取) public health: number = 0; public maxHealth: number = 0; public speed: number = 0; public attackPower: number = 0; // 敌人配置ID public enemyId: string = ''; // 敌人配置数据 private enemyConfig: any = null; // 敌人配置数据库 private static enemyDatabase: any = null; // === 新增属性 === /** 是否从上方生成 */ public spawnFromTop: boolean = true; /** 目标 Fence 节点(TopFence / BottomFence) */ public targetFence: Node | null = null; // 移动相关属性 public movingDirection: number = 1; // 1: 向右, -1: 向左 public targetY: number = 0; // 目标Y位置 public changeDirectionTime: number = 0; // 下次改变方向的时间 // 摆动移动相关属性 private swayTime: number = 0; // 摆动时间累计 private basePosition: Vec3 = new Vec3(); // 基础位置(摆动的中心点) private swayOffset: Vec3 = new Vec3(); // 当前摆动偏移 // 攻击属性 public attackInterval: number = 0; // 攻击间隔(秒),从配置文件读取 private attackTimer: number = 0; // 对控制器的引用 public controller: EnemyControllerType = null; // 敌人当前状态 private state: EnemyState = EnemyState.MOVING; // 游戏区域中心 private gameAreaCenter: Vec3 = new Vec3(); // 碰撞的墙体 private collidedWall: Node = null; // 骨骼动画组件 private skeleton: sp.Skeleton | null = null; // 血条动画组件 private hpBarAnimation: HPBarAnimation | null = null; // 暂停状态标记 private isPaused: boolean = false; start() { // 初始化敌人 this.initializeEnemy(); } // 静态方法:加载敌人配置数据库 public static async loadEnemyDatabase(): Promise { if (EnemyInstance.enemyDatabase) return; return new Promise((resolve, reject) => { resources.load('data/enemies', JsonAsset, (err, jsonAsset) => { if (err) { console.error('[EnemyInstance] 加载敌人配置失败:', err); reject(err); return; } EnemyInstance.enemyDatabase = jsonAsset.json; resolve(); }); }); } // 设置敌人配置 public setEnemyConfig(enemyId: string): void { this.enemyId = enemyId; if (!EnemyInstance.enemyDatabase) { console.error('[EnemyInstance] 敌人配置数据库未加载'); return; } // 从数据库中查找敌人配置 // 修复:enemies.json是直接的数组结构,不需要.enemies包装 const enemies = EnemyInstance.enemyDatabase; this.enemyConfig = enemies.find((enemy: any) => enemy.id === enemyId); if (!this.enemyConfig) { console.error(`[EnemyInstance] 未找到敌人配置: ${enemyId}`); return; } // 应用配置到敌人属性 this.applyEnemyConfig(); } // 应用敌人配置到属性 private applyEnemyConfig(): void { if (!this.enemyConfig) return; // 从stats节点读取基础属性 const stats = this.enemyConfig.stats || {}; this.health = stats.health || 30; this.maxHealth = stats.maxHealth || this.health; // 从movement节点读取移动速度 const movement = this.enemyConfig.movement || {}; this.speed = movement.speed || 50; // 从combat节点读取攻击力 const combat = this.enemyConfig.combat || {}; this.attackPower = combat.attackDamage || 10; // 设置攻击间隔 this.attackInterval = combat.attackCooldown || 2.0; } // 获取敌人配置信息 public getEnemyConfig(): any { return this.enemyConfig; } // 获取敌人名称 public getEnemyName(): string { return this.enemyConfig?.name || '未知敌人'; } // 获取敌人类型 public getEnemyType(): string { return this.enemyConfig?.type || 'basic'; } // 获取敌人稀有度 public getEnemyRarity(): string { return this.enemyConfig?.rarity || 'common'; } // 获取金币奖励 public getGoldReward(): number { return this.enemyConfig?.goldReward || 1; } // 初始化敌人 private initializeEnemy() { // 确保血量正确设置 if (this.maxHealth > 0) { this.health = this.maxHealth; } this.state = EnemyState.MOVING; // 只有在攻击间隔未设置时才使用默认值 if (this.attackInterval <= 0) { this.attackInterval = 2.0; // 默认攻击间隔 } this.attackTimer = 0; // 初始化血条动画组件 this.initializeHPBarAnimation(); // 初始化骨骼动画组件 - 从EnemySprite子节点获取 const enemySprite = this.node.getChildByName('EnemySprite'); if (enemySprite) { this.skeleton = enemySprite.getComponent(sp.Skeleton); } else { console.error('[EnemyInstance] 未找到EnemySprite子节点,无法获取骨骼动画组件'); } this.playWalkAnimation(); // 计算游戏区域中心 this.calculateGameAreaCenter(); // 初始化碰撞检测 this.setupCollider(); } // 设置碰撞器 setupCollider() { // 从EnemySprite子节点获取碰撞器组件 const enemySprite = this.node.getChildByName('EnemySprite'); if (!enemySprite) { console.error('[EnemyInstance] 未找到EnemySprite子节点,无法设置碰撞器组件'); return; } // 检查EnemySprite节点是否有碰撞器 let collider = enemySprite.getComponent(Collider2D); if (!collider) { console.warn(`[EnemyInstance] 敌人节点 ${this.node.name} 的EnemySprite子节点没有碰撞器组件`); return; } // 确保有RigidBody2D组件,这对于碰撞检测是必需的 let rigidBody = enemySprite.getComponent(RigidBody2D); if (!rigidBody) { console.log(`[EnemyInstance] 为敌人EnemySprite节点添加RigidBody2D组件`); rigidBody = enemySprite.addComponent(RigidBody2D); } // 设置刚体属性 if (rigidBody) { rigidBody.type = ERigidBody2DType.Dynamic; // 动态刚体 rigidBody.enabledContactListener = true; // 启用碰撞监听 rigidBody.gravityScale = 0; // 不受重力影响 rigidBody.linearDamping = 0; // 无线性阻尼 rigidBody.angularDamping = 0; // 无角阻尼 rigidBody.allowSleep = false; // 不允许休眠 rigidBody.fixedRotation = true; // 固定旋转 } // 根据ContentSize自适应碰撞体大小 this.adaptColliderToContentSize(collider); // 设置碰撞事件监听 collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this); console.log(`[EnemyInstance] 敌人 ${this.node.name} 碰撞器设置完成,碰撞器启用: ${collider.enabled}, 刚体启用: ${rigidBody?.enabled}`); } /** * 根据ContentSize自适应碰撞体大小 */ private adaptColliderToContentSize(collider: Collider2D): void { // 从EnemySprite子节点获取UITransform组件 const enemySprite = this.node.getChildByName('EnemySprite'); if (!enemySprite) { console.error('[EnemyInstance] 未找到EnemySprite子节点,无法获取UITransform组件'); return; } const uiTransform = enemySprite.getComponent(UITransform); if (!uiTransform) { console.warn(`[EnemyInstance] EnemySprite节点没有UITransform组件,无法自适应碰撞体大小`); return; } const contentSize = uiTransform.contentSize; console.log(`[EnemyInstance] 敌人 ${this.node.name} ContentSize: ${contentSize.width} x ${contentSize.height}`); // 根据碰撞器类型设置大小 if (collider instanceof BoxCollider2D) { // 方形碰撞器:直接使用ContentSize const boxCollider = collider as BoxCollider2D; boxCollider.size.width = contentSize.width; boxCollider.size.height = contentSize.height; // 调整偏移量,使碰撞器居中 const anchorPoint = uiTransform.anchorPoint; boxCollider.offset.x = (0.5 - anchorPoint.x) * contentSize.width; boxCollider.offset.y = (0.5 - anchorPoint.y) * contentSize.height; console.log(`[EnemyInstance] BoxCollider2D 已自适应: size(${boxCollider.size.width}, ${boxCollider.size.height}), offset(${boxCollider.offset.x.toFixed(2)}, ${boxCollider.offset.y.toFixed(2)})`); } else if (collider instanceof CircleCollider2D) { // 圆形碰撞器:使用ContentSize的较小值作为直径 const circleCollider = collider as CircleCollider2D; const radius = Math.min(contentSize.width, contentSize.height) / 2; circleCollider.radius = radius; // 调整偏移量,使碰撞器居中 const anchorPoint = uiTransform.anchorPoint; circleCollider.offset.x = (0.5 - anchorPoint.x) * contentSize.width; circleCollider.offset.y = (0.5 - anchorPoint.y) * contentSize.height; console.log(`[EnemyInstance] CircleCollider2D 已自适应: radius(${radius.toFixed(2)}), offset(${circleCollider.offset.x.toFixed(2)}, ${circleCollider.offset.y.toFixed(2)})`); } else { console.warn(`[EnemyInstance] 不支持的碰撞器类型: ${collider.constructor.name}`); } } // 碰撞开始事件 onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) { const nodeName = otherCollider.node.name; // 如果碰到墙体,停止移动并开始攻击 if (nodeName.includes('Wall') || nodeName.includes('wall') || nodeName.includes('Fence') || nodeName.includes('Jiguang')) { this.state = EnemyState.ATTACKING; this.attackTimer = 0; // 立即开始攻击 // 切换攻击动画 this.playAttackAnimation(); } } // 获取节点路径 getNodePath(node: Node): string { let path = node.name; let current = node; while (current.parent) { current = current.parent; path = current.name + '/' + path; } return path; } // 计算游戏区域中心 private calculateGameAreaCenter() { const gameArea = find('Canvas/GameLevelUI/GameArea'); if (gameArea) { this.gameAreaCenter = gameArea.worldPosition; } } /** * 初始化血条动画组件 */ private initializeHPBarAnimation() { const hpBar = this.node.getChildByName('HPBar'); if (hpBar) { // 查找红色和黄色血条节点 const redBarNode = hpBar.getChildByName('RedBar'); const yellowBarNode = hpBar.getChildByName('YellowBar'); if (redBarNode && yellowBarNode) { // 添加血条动画组件 this.hpBarAnimation = this.node.addComponent(HPBarAnimation); if (this.hpBarAnimation) { // 正确设置红色和黄色血条节点引用 this.hpBarAnimation.redBarNode = redBarNode; this.hpBarAnimation.yellowBarNode = yellowBarNode; this.hpBarAnimation.hpBarRootNode = hpBar; // 设置HPBar根节点 console.log(`[EnemyInstance] 血条动画组件已初始化`); } } else { console.warn(`[EnemyInstance] HPBar下未找到RedBar或YellowBar节点,RedBar: ${!!redBarNode}, YellowBar: ${!!yellowBarNode}`); } } else { console.warn(`[EnemyInstance] 未找到HPBar节点,无法初始化血条动画`); } } // 更新血量显示 updateHealthDisplay(showBar: boolean = false) { // 确保血量值在有效范围内 this.health = Math.max(0, Math.min(this.maxHealth, this.health)); const healthProgress = this.maxHealth > 0 ? this.health / this.maxHealth : 0; console.log(`[EnemyInstance] 更新血量显示: ${this.health}/${this.maxHealth} (${(healthProgress * 100).toFixed(1)}%)`); // 使用血条动画组件更新血条 if (this.hpBarAnimation) { this.hpBarAnimation.updateProgress(healthProgress, showBar); } else { // 备用方案:直接更新血条 const hpBar = this.node.getChildByName('HPBar'); if (hpBar) { const progressBar = hpBar.getComponent(ProgressBar); if (progressBar) { progressBar.progress = healthProgress; } // 根据showBar参数控制血条显示 hpBar.active = showBar; } } // 更新血量数字 const hpLabel = this.node.getChildByName('HPLabel'); if (hpLabel) { const label = hpLabel.getComponent(Label); if (label) { // 显示整数血量值 label.string = Math.ceil(this.health).toString(); } } } // 受到伤害 takeDamage(damage: number, isCritical: boolean = false) { // 如果已经死亡,不再处理伤害 if (this.state === EnemyState.DEAD) { return; } // 确保伤害值为正数 if (damage <= 0) { console.warn(`[EnemyInstance] 无效的伤害值: ${damage}`); return; } // 应用防御力减少伤害 const enemyComponent = this.getComponent(EnemyComponent); const defense = enemyComponent ? enemyComponent.getDefense() : 0; let finalDamage = Math.max(1, damage - defense); // 至少造成1点伤害 // 检查格挡 if (enemyComponent && enemyComponent.canBlock() && this.tryBlock()) { finalDamage *= (1 - enemyComponent.getBlockDamageReduction()); this.showBlockEffect(); } // 计算新的血量,确保不会低于0 const oldHealth = this.health; const newHealth = Math.max(0, this.health - finalDamage); const actualHealthLoss = oldHealth - newHealth; // 实际血量损失 this.health = newHealth; // 检查是否触发狂暴 this.checkRageTrigger(); // 日志显示武器的真实伤害值,而不是血量差值 console.log(`[EnemyInstance] 敌人受到伤害: ${damage} (武器伤害), 防御后伤害: ${finalDamage}, 实际血量损失: ${actualHealthLoss}, 剩余血量: ${this.health}/${this.maxHealth}`); // 受击音效已移除 // 显示伤害数字动画(在敌人头顶)- 显示防御后的实际伤害 // 优先使用EnemyController节点上的DamageNumberAni组件实例 if (this.controller) { const damageAni = this.controller.getComponent(DamageNumberAni); if (damageAni) { damageAni.showDamageNumber(finalDamage, this.node.worldPosition, isCritical); } else { // 如果没有找到组件实例,使用静态方法作为备用 DamageNumberAni.showDamageNumber(finalDamage, this.node.worldPosition, isCritical); } } else { // 如果没有controller引用,使用静态方法 DamageNumberAni.showDamageNumber(finalDamage, this.node.worldPosition, isCritical); } // 更新血量显示和动画,受伤时显示血条 this.updateHealthDisplay(true); // 如果血量低于等于0,销毁敌人 if (this.health <= 0) { console.log(`[EnemyInstance] 敌人死亡,开始销毁流程`); this.state = EnemyState.DEAD; this.spawnCoin(); // 进入死亡流程,禁用碰撞避免重复命中 const enemySprite = this.node.getChildByName('EnemySprite'); if (enemySprite) { const col = enemySprite.getComponent(Collider2D); if (col) col.enabled = false; } this.playDeathAnimationAndDestroy(); } } onDestroy() { console.log(`[EnemyInstance] onDestroy 被调用,准备通知控制器`); // 通知控制器 & GameManager if (this.controller && typeof (this.controller as any).notifyEnemyDead === 'function') { // 检查控制器是否处于清理状态,避免在清理过程中触发游戏事件 const isClearing = (this.controller as any).isClearing; if (isClearing) { console.log(`[EnemyInstance] 控制器处于清理状态,跳过死亡通知`); return; } console.log(`[EnemyInstance] 调用 notifyEnemyDead`); (this.controller as any).notifyEnemyDead(this.node); } else { console.warn(`[EnemyInstance] 无法调用 notifyEnemyDead: controller=${!!this.controller}`); } } update(deltaTime: number) { // 如果敌人被暂停,则不执行任何更新逻辑 if (this.isPaused) { return; } if (this.state === EnemyState.MOVING) { this.updateMovement(deltaTime); } else if (this.state === EnemyState.ATTACKING) { this.updateAttack(deltaTime); } // 不再每帧播放攻击动画,避免日志刷屏 } // 更新移动逻辑 private updateMovement(deltaTime: number) { // 继续移动到目标墙体 this.moveTowardsTarget(deltaTime); } // 移动到目标位置 private moveTowardsTarget(deltaTime: number) { // 使用世界坐标进行移动计算,确保不受父节点坐标系影响 const currentWorldPos = this.node.worldPosition.clone(); // 目标世界坐标:优先使用指定的 Fence,其次退化到游戏区域中心 let targetWorldPos: Vec3; if (this.targetFence && this.targetFence.isValid) { targetWorldPos = this.targetFence.worldPosition.clone(); } else { targetWorldPos = this.gameAreaCenter.clone(); } const dir = targetWorldPos.subtract(currentWorldPos); if (dir.length() === 0) return; dir.normalize(); // 获取当前速度(考虑狂暴加成) const enemyComponent = this.getComponent(EnemyComponent); const currentSpeed = enemyComponent ? enemyComponent.getCurrentSpeed() : this.speed; const moveDistance = currentSpeed * deltaTime; let newWorldPos = currentWorldPos.add(dir.multiplyScalar(moveDistance)); // 应用摆动效果 if (enemyComponent) { const swayAmplitude = enemyComponent.getSwingAmplitude(); const swayFrequency = enemyComponent.getSwingFrequency(); if (swayAmplitude > 0 && swayFrequency > 0) { this.swayTime += deltaTime; // 计算垂直于移动方向的摆动偏移 const swayOffset = Math.sin(this.swayTime * swayFrequency * 2 * Math.PI) * swayAmplitude; // 计算垂直于移动方向的向量 const perpDir = new Vec3(-dir.y, dir.x, 0); const swayVector = perpDir.multiplyScalar(swayOffset); newWorldPos = newWorldPos.add(swayVector); } } // 直接设置世界坐标 this.node.setWorldPosition(newWorldPos); } // 更新攻击逻辑 private updateAttack(deltaTime: number) { this.attackTimer -= deltaTime; if (this.attackTimer <= 0) { // 执行攻击 this.performAttack(); // 重置攻击计时器 this.attackTimer = this.attackInterval; } } // 执行攻击 private performAttack() { if (!this.controller) { return; } const enemyComponent = this.getComponent(EnemyComponent); const attackType = enemyComponent ? enemyComponent.getAttackType() : 'melee'; // 播放攻击音效 EnemyAudio.playAttackSound(this.enemyConfig); // 根据攻击类型执行不同的攻击逻辑 if (attackType === 'ranged' || attackType === 'projectile') { this.performRangedAttack(); } else { // 近战攻击:播放攻击动画,动画结束后造成伤害 this.playAttackAnimationWithDamage(); } } // 执行远程攻击(投掷) private performRangedAttack() { const enemyComponent = this.getComponent(EnemyComponent); if (!enemyComponent) return; const projectileType = enemyComponent.getProjectileType(); const projectileSpeed = enemyComponent.getProjectileSpeed(); console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 发射投掷物: ${projectileType}, 速度: ${projectileSpeed}`); // TODO: 实际创建和发射投掷物的逻辑 // 这里需要根据项目的投掷物系统来实现 // 例如:创建投掷物预制体,设置速度和方向,添加碰撞检测等 // 暂时直接造成伤害作为占位符 this.scheduleOnce(() => { this.dealDamageToWall(); }, 1.0); // 1秒后造成伤害,模拟投掷物飞行时间 } // 播放行走动画 private playWalkAnimation() { if (!this.skeleton) return; const enemyComp = this.getComponent('EnemyComponent') as any; const anims = enemyComp?.getAnimations ? enemyComp.getAnimations() : {}; const walkName = anims.walk ?? 'walk'; const idleName = anims.idle ?? 'idle'; if (this.skeleton.findAnimation(walkName)) { this.skeleton.setAnimation(0, walkName, true); // 行走音效已移除 } else if (this.skeleton.findAnimation(idleName)) { this.skeleton.setAnimation(0, idleName, true); } } // 播放攻击动画 private playAttackAnimation() { if (!this.skeleton) return; const enemyComp2 = this.getComponent('EnemyComponent') as any; const anims2 = enemyComp2?.getAnimations ? enemyComp2.getAnimations() : {}; const attackName = anims2.attack ?? 'attack'; // 移除频繁打印 if (this.skeleton.findAnimation(attackName)) { this.skeleton.setAnimation(0, attackName, true); } } // 播放攻击动画并在动画结束时造成伤害 private playAttackAnimationWithDamage() { if (!this.skeleton) { // 如果没有骨骼动画,直接造成伤害 this.dealDamageToWall(); return; } const enemyComp = this.getComponent('EnemyComponent') as any; const anims = enemyComp?.getAnimations ? enemyComp.getAnimations() : {}; const attackName = anims.attack ?? 'attack'; const animation = this.skeleton.findAnimation(attackName); if (animation) { // 播放攻击动画(不循环) this.skeleton.setAnimation(0, attackName, false); // 获取动画时长并在动画结束时造成伤害 const animationDuration = animation.duration; console.log(`[EnemyInstance] 攻击动画时长: ${animationDuration}秒`); // 使用定时器在动画结束时造成伤害 this.scheduleOnce(() => { this.dealDamageToWall(); // 动画完成后切换回行走动画 this.playWalkAnimation(); }, animationDuration); } else { // 如果找不到攻击动画,直接造成伤害 this.dealDamageToWall(); } } // 对墙体造成伤害 private dealDamageToWall() { if (this.controller) { // 获取当前攻击力(考虑狂暴加成) const enemyComponent = this.getComponent(EnemyComponent); const currentAttackPower = enemyComponent ? enemyComponent.getCurrentAttackPower() : this.attackPower; this.controller.damageWall(currentAttackPower); } } private playDeathAnimationAndDestroy() { console.log(`[EnemyInstance] 开始播放死亡动画并销毁`); // 播放死亡音效 EnemyAudio.playDeathSound(this.enemyConfig); if (this.skeleton) { const enemyComp = this.getComponent('EnemyComponent') as any; const anims = enemyComp?.getAnimations ? enemyComp.getAnimations() : {}; const deathName = anims.dead ?? 'dead'; if (this.skeleton.findAnimation(deathName)) { this.skeleton.setAnimation(0, deathName, false); // 销毁节点在动画完毕后 this.skeleton.setCompleteListener(() => { this.node.destroy(); }); return; } } this.node.destroy(); } private spawnCoin() { const ctrl = this.controller as any; // EnemyController if (!ctrl?.coinPrefab) return; const coin = instantiate(ctrl.coinPrefab); find('Canvas')!.addChild(coin); // 放到 UI 层 const pos = new Vec3(); this.node.getWorldPosition(pos); // 取死亡敌人的世界坐标 coin.worldPosition = pos; // 金币就在敌人身上出现 } /** * 暂停敌人 */ public pause(): void { this.isPaused = true; console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 已暂停`); } /** * 恢复敌人 */ public resume(): void { this.isPaused = false; console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 已恢复`); } /** * 检查是否暂停 */ public isPausedState(): boolean { return this.isPaused; } /** * 重置血条状态(满血并隐藏) */ public resetHealthBar(): void { if (this.hpBarAnimation) { this.hpBarAnimation.resetToFullAndHide(); } else { // 备用方案:直接隐藏血条 const hpBar = this.node.getChildByName('HPBar'); if (hpBar) { hpBar.active = false; const progressBar = hpBar.getComponent(ProgressBar); if (progressBar) { progressBar.progress = 1.0; } } } } /** * 尝试格挡攻击 */ private tryBlock(): boolean { const enemyComponent = this.getComponent(EnemyComponent); if (!enemyComponent) return false; const blockChance = enemyComponent.getBlockChance(); return Math.random() < blockChance; } /** * 显示格挡效果 */ private showBlockEffect(): void { console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 格挡了攻击`); // TODO: 添加格挡视觉效果 } /** * 检查是否触发狂暴状态 */ private checkRageTrigger(): void { const enemyComponent = this.getComponent(EnemyComponent); if (!enemyComponent) return; const healthPercent = this.health / this.maxHealth; const rageTriggerThreshold = enemyComponent.getRageTriggerThreshold(); if (healthPercent <= rageTriggerThreshold && !enemyComponent.isInRage()) { enemyComponent.triggerRage(); console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 进入狂暴状态`); } } }