import { _decorator, Component, Node, Color, UIOpacity } from 'cc'; import { sp } from 'cc'; import { ConfigManager, EnemyConfig } from '../Core/ConfigManager'; import EventBus, { GameEvents } from '../Core/EventBus'; const { ccclass, property } = _decorator; /** * 敌人组件 * 用于存储敌人的配置信息和基础属性 */ @ccclass('EnemyComponent') export class EnemyComponent extends Component { public enemyConfig: EnemyConfig = null; public spawner: any = null; // 对生成器的引用 private rageActive: boolean = false; private rageStartTime: number = 0; // 隐身状态 private stealthActive: boolean = false; start() { // 统一由 EnemyInstance 发出隐身事件并驱动 AttackStateManager。 // 此组件仅响应事件并更新视觉透明度,不再主动调度隐身。 } onEnable() { const eventBus = EventBus.getInstance(); eventBus.on(GameEvents.ENEMY_STEALTH_START, this.onStealthStart, this); eventBus.on(GameEvents.ENEMY_STEALTH_END, this.onStealthEnd, this); } onDisable() { // 组件禁用时取消调度,避免泄漏 this.unscheduleAllCallbacks(); const eventBus = EventBus.getInstance(); eventBus.off(GameEvents.ENEMY_STEALTH_START, this.onStealthStart, this); eventBus.off(GameEvents.ENEMY_STEALTH_END, this.onStealthEnd, this); } // 获取敌人生命值 public getHealth(): number { return this.enemyConfig?.stats?.health || 100; } // 获取敌人速度 public getSpeed(): number { return this.enemyConfig?.stats?.speed || 50; } // 获取敌人伤害 public getDamage(): number { return this.enemyConfig?.combat?.attackDamage || 20; } // 获取敌人攻击范围 public getAttackRange(): number { return this.enemyConfig?.combat?.attackRange || 30; } // 获取敌人攻击速度 public getAttackSpeed(): number { return this.enemyConfig?.combat?.attackSpeed || 1.0; } // 获取敌人防御力 public getDefense(): number { return this.enemyConfig?.stats?.defense || 0; } // 获取击杀奖励 public getCoinReward(): number { return this.enemyConfig?.stats?.dropEnergy || 1; } // === 移动相关配置 === // 获取移动类型 public getMovementType(): string { return this.enemyConfig?.movement?.moveType || 'straight'; } // 获取移动模式 public getMovementPattern(): string { return this.enemyConfig?.movement?.pattern || 'direct'; } // 获取摆动幅度 public getSwingAmplitude(): number { return this.enemyConfig?.movement?.swingAmplitude || 0.0; } // 获取摆动频率 public getSwingFrequency(): number { return this.enemyConfig?.movement?.swingFrequency || 0.0; } // 获取速度变化 public getSpeedVariation(): number { return this.enemyConfig?.movement?.speedVariation || 0.1; } // 获取旋转速度 public getRotationSpeed(): number { return this.enemyConfig?.movement?.rotationSpeed || 180.0; } // === 战斗相关配置 === // 获取攻击类型 public getAttackType(): string { return this.enemyConfig?.combat?.attackType || 'melee'; } // 获取攻击冷却时间 public getAttackCooldown(): number { return this.enemyConfig?.combat?.attackCooldown || 2.0; } // 获取攻击延迟 public getAttackDelay(): number { return this.enemyConfig?.combat?.attackDelay || 1.0; } // 获取武器类型 public getWeaponType(): string { return this.enemyConfig?.combat?.weaponType || 'none'; } // 获取投掷物类型 public getProjectileType(): string { return this.enemyConfig?.combat?.projectileType || 'none'; } // 获取投掷物速度 public getProjectileSpeed(): number { return this.enemyConfig?.combat?.projectileSpeed || 100.0; } // 是否造成墙体震动 public getCausesWallShake(): boolean { return this.enemyConfig?.combat?.causesWallShake || false; } // === 格挡系统 === // 是否可以格挡 public canBlock(): boolean { return this.enemyConfig?.combat?.canBlock || false; } // 获取格挡几率 public getBlockChance(): number { return this.enemyConfig?.combat?.blockChance || 0.0; } // 获取格挡伤害减免 public getBlockDamageReduction(): number { return this.enemyConfig?.combat?.blockDamageReduction || 0.5; } // === 狂暴系统 === // 是否有狂暴能力 public hasRage(): boolean { return this.enemyConfig?.boss?.rage_threshold > 0 || false; } // 获取狂暴触发血量阈值 public getRageThreshold(): number { return this.enemyConfig?.boss?.rage_threshold || 0.3; } // 获取狂暴触发血量阈值(别名方法) public getRageTriggerThreshold(): number { return this.getRageThreshold(); } // 获取狂暴伤害倍率 public getRageDamageMultiplier(): number { return this.enemyConfig?.boss?.rage_damage_multiplier || 1.5; } // 获取狂暴速度倍率 public getRageSpeedMultiplier(): number { return this.enemyConfig?.boss?.rage_speed_multiplier || 1.3; } // 获取狂暴持续时间 public getRageDuration(): number { return 10.0; // 固定持续时间 } // === 特殊能力 === // 获取特殊能力类型 public getSpecialAbility(): string { const abilities = this.enemyConfig?.special_abilities; if (Array.isArray(abilities) && abilities.length > 0) { return abilities[0]?.type || 'none'; } return 'none'; } // 获取特殊能力冷却时间 public getSpecialAbilityCooldown(): number { const abilities = this.enemyConfig?.special_abilities; if (Array.isArray(abilities) && abilities.length > 0) { const cooldown = abilities[0]?.cooldown; return typeof cooldown === 'number' ? cooldown : 5.0; } return 5.0; } /** * 应用隐身透明度到 EnemySprite 的 Skeleton * @param opacity 透明度(0-255),示例:50 表示半透明 */ private applyStealthOpacity(opacity: number): void { const enemySprite = this.findEnemySpriteNode(); if (!enemySprite) { console.warn('[EnemyComponent] 未找到 EnemySprite 节点,无法应用隐身透明度'); return; } // 设置 UIOpacity 以保证整节点透明度生效 let uiOpacity = enemySprite.getComponent(UIOpacity); if (!uiOpacity) { uiOpacity = enemySprite.addComponent(UIOpacity); } uiOpacity.opacity = Math.max(0, Math.min(255, opacity)); // 同时设置 Skeleton 的颜色 alpha(与编辑器表现一致) const skeleton = enemySprite.getComponent(sp.Skeleton); if (skeleton) { const current = skeleton.color ?? new Color(255, 255, 255, 255); const next = new Color(current.r, current.g, current.b, Math.max(0, Math.min(255, opacity))); skeleton.color = next; } } /** * 在当前节点层级下查找 EnemySprite 节点(兼容不同层级路径) */ private findEnemySpriteNode(): Node | null { // 直接子节点命中 const direct = this.node.getChildByName('EnemySprite'); if (direct) return direct; // 深度遍历查找 const stack: Node[] = [...this.node.children]; while (stack.length > 0) { const cur = stack.pop()!; if (cur.name === 'EnemySprite') return cur; stack.push(...cur.children); } return null; } // === 隐身事件响应 === private onStealthStart(data: { enemy: any, duration?: number }) { if (!data || !data.enemy || !data.enemy.node) return; if (data.enemy.node !== this.node) return; this.stealthActive = true; this.applyStealthOpacity(100); console.log(`[EnemyComponent] 接收隐身开始事件: ${this.node.name}, 持续: ${data.duration ?? '-'} 秒`); } private onStealthEnd(data: { enemy: any }) { if (!data || !data.enemy || !data.enemy.node) return; if (data.enemy.node !== this.node) return; this.stealthActive = false; this.applyStealthOpacity(255); console.log(`[EnemyComponent] 接收隐身结束事件: ${this.node.name}`); } // === 狂暴状态管理 === // 检查是否处于狂暴状态 public isInRage(): boolean { if (!this.rageActive) return false; // 检查狂暴是否过期 const currentTime = Date.now(); const rageDuration = this.getRageDuration() * 1000; // 转换为毫秒 if (currentTime - this.rageStartTime > rageDuration) { this.endRage(); return false; } return true; } // 触发狂暴状态 public triggerRage(): void { if (!this.hasRage()) return; this.rageActive = true; this.rageStartTime = Date.now(); console.log(`[EnemyComponent] 狂暴状态激活,持续时间: ${this.getRageDuration()}秒`); } // 结束狂暴状态 public endRage(): void { this.rageActive = false; this.rageStartTime = 0; console.log(`[EnemyComponent] 狂暴状态结束`); } // 获取当前攻击力(考虑狂暴加成) public getCurrentAttackPower(): number { const baseDamage = this.getDamage(); if (this.isInRage()) { return baseDamage * this.getRageDamageMultiplier(); } return baseDamage; } // 获取当前移动速度(考虑狂暴加成) public getCurrentSpeed(): number { const baseSpeed = this.getSpeed(); if (this.isInRage()) { return baseSpeed * this.getRageSpeedMultiplier(); } return baseSpeed; } // 获取动画配置 public getAnimations(): any { return this.enemyConfig?.visualConfig?.animations || {}; } // 获取音频配置 public getAudioConfig(): any { return this.enemyConfig?.audioConfig || {}; } // 检查是否有特殊能力 public hasSpecialAbility(abilityType: string): boolean { if (!this.enemyConfig || !this.enemyConfig.special_abilities) return false; return this.enemyConfig.special_abilities.some(ability => ability.type === abilityType); } // 获取特殊配置 public getBossConfig(): any { return this.enemyConfig?.boss || null; } // 获取敌人信息文本 public getEnemyInfo(): string { if (!this.enemyConfig) return '未知敌人'; return `${this.enemyConfig.name}\n` + `类型: ${this.enemyConfig.type}\n` + `生命值: ${this.enemyConfig.stats?.health || 0}\n` + `速度: ${this.enemyConfig.stats?.speed || 0}\n` + `伤害: ${this.enemyConfig.combat?.attackDamage || 0}\n` + `攻击范围: ${this.enemyConfig.combat?.attackRange || 0}`; } // 死亡时调用 public onDeath() { if (this.spawner && this.spawner.onEnemyDeath) { this.spawner.onEnemyDeath(this.node); } } }