|
|
@@ -1,5 +1,6 @@
|
|
|
import { _decorator, Component, Node, Prefab, instantiate, Vec3, Vec2, Sprite, SpriteFrame, resources, RigidBody2D, CCFloat, CCInteger } from 'cc';
|
|
|
import { ConfigManager, EnemyConfig } from './ConfigManager';
|
|
|
+import { EnemyComponent } from './EnemyComponent';
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
/**
|
|
|
@@ -257,210 +258,4 @@ export class EnemySpawnerExample extends Component {
|
|
|
this.spawnInterval = interval;
|
|
|
this.spawnTimer = 0;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * 敌人组件
|
|
|
- * 用于存储敌人的配置信息和行为逻辑
|
|
|
- */
|
|
|
-@ccclass('EnemyComponent')
|
|
|
-export class EnemyComponent extends Component {
|
|
|
- public enemyConfig: EnemyConfig = null;
|
|
|
- public spawner: EnemySpawnerExample = null;
|
|
|
-
|
|
|
- private currentHealth: number = 0;
|
|
|
- private moveTimer: number = 0;
|
|
|
- private attackTimer: number = 0;
|
|
|
- private isAlive: boolean = true;
|
|
|
-
|
|
|
- start() {
|
|
|
- if (this.enemyConfig) {
|
|
|
- this.currentHealth = this.enemyConfig.stats.health;
|
|
|
- this.setupMovement();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- update(deltaTime: number) {
|
|
|
- if (!this.isAlive || !this.enemyConfig) return;
|
|
|
-
|
|
|
- this.updateMovement(deltaTime);
|
|
|
- this.updateAttack(deltaTime);
|
|
|
- this.checkBounds();
|
|
|
- }
|
|
|
-
|
|
|
- // 设置移动行为
|
|
|
- private setupMovement() {
|
|
|
- const rigidBody = this.node.getComponent(RigidBody2D);
|
|
|
- if (rigidBody && this.enemyConfig) {
|
|
|
- const movement = this.enemyConfig.movement;
|
|
|
- const speed = this.enemyConfig.stats.speed;
|
|
|
-
|
|
|
- switch (movement.type) {
|
|
|
- case 'straight':
|
|
|
- rigidBody.linearVelocity = new Vec2(-speed, 0);
|
|
|
- break;
|
|
|
- case 'sway':
|
|
|
- rigidBody.linearVelocity = new Vec2(-speed, 0);
|
|
|
- break;
|
|
|
- default:
|
|
|
- rigidBody.linearVelocity = new Vec2(-speed, 0);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 更新移动
|
|
|
- private updateMovement(deltaTime: number) {
|
|
|
- if (!this.enemyConfig) return;
|
|
|
-
|
|
|
- const movement = this.enemyConfig.movement;
|
|
|
-
|
|
|
- if (movement.type === 'sway') {
|
|
|
- this.moveTimer += deltaTime;
|
|
|
- const rigidBody = this.node.getComponent(RigidBody2D);
|
|
|
-
|
|
|
- if (rigidBody) {
|
|
|
- const speed = this.enemyConfig.stats.speed;
|
|
|
- const swayAmplitude = movement.swayAmplitude || 20;
|
|
|
- const swayFrequency = movement.swayFrequency || 2.0;
|
|
|
-
|
|
|
- const yVelocity = Math.sin(this.moveTimer * swayFrequency) * swayAmplitude;
|
|
|
- rigidBody.linearVelocity = new Vec2(-speed, yVelocity);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 更新攻击
|
|
|
- private updateAttack(deltaTime: number) {
|
|
|
- if (!this.enemyConfig) return;
|
|
|
-
|
|
|
- this.attackTimer += deltaTime;
|
|
|
-
|
|
|
- if (this.attackTimer >= this.enemyConfig.combat.attackCooldown) {
|
|
|
- this.performAttack();
|
|
|
- this.attackTimer = 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 执行攻击
|
|
|
- private performAttack() {
|
|
|
- if (!this.enemyConfig) return;
|
|
|
-
|
|
|
- const combat = this.enemyConfig.combat;
|
|
|
-
|
|
|
- switch (combat.attackType) {
|
|
|
- case 'magic_projectile':
|
|
|
- case 'arrow_projectile':
|
|
|
- this.fireProjectile();
|
|
|
- break;
|
|
|
- case 'melee':
|
|
|
- case 'heavy_melee':
|
|
|
- this.performMeleeAttack();
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 发射投射物
|
|
|
- private fireProjectile() {
|
|
|
- console.log(`${this.enemyConfig.name} 发射投射物`);
|
|
|
- // 这里应该创建子弹并发射
|
|
|
- }
|
|
|
-
|
|
|
- // 执行近战攻击
|
|
|
- private performMeleeAttack() {
|
|
|
- console.log(`${this.enemyConfig.name} 执行近战攻击`);
|
|
|
- // 这里应该检测攻击范围内的目标
|
|
|
- }
|
|
|
-
|
|
|
- // 检查边界
|
|
|
- private checkBounds() {
|
|
|
- const position = this.node.getPosition();
|
|
|
-
|
|
|
- // 如果敌人移动到屏幕左侧外,销毁它
|
|
|
- if (position.x < -900) {
|
|
|
- this.die();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 受到伤害
|
|
|
- public takeDamage(damage: number) {
|
|
|
- if (!this.isAlive) return;
|
|
|
-
|
|
|
- this.currentHealth -= damage;
|
|
|
- console.log(`${this.enemyConfig.name} 受到 ${damage} 点伤害,剩余血量: ${this.currentHealth}`);
|
|
|
-
|
|
|
- if (this.currentHealth <= 0) {
|
|
|
- this.die();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 死亡
|
|
|
- private die() {
|
|
|
- if (!this.isAlive) return;
|
|
|
-
|
|
|
- this.isAlive = false;
|
|
|
- console.log(`${this.enemyConfig.name} 死亡`);
|
|
|
-
|
|
|
- // 处理爆炸类型敌人的死亡爆炸
|
|
|
- if (this.enemyConfig.type === 'explosive') {
|
|
|
- this.explode();
|
|
|
- }
|
|
|
-
|
|
|
- // 通知生成器
|
|
|
- if (this.spawner) {
|
|
|
- this.spawner.onEnemyDeath(this.node);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 爆炸
|
|
|
- private explode() {
|
|
|
- console.log(`${this.enemyConfig.name} 爆炸!`);
|
|
|
- // 这里应该创建爆炸效果和伤害判定
|
|
|
- }
|
|
|
-
|
|
|
- // 获取敌人信息
|
|
|
- public getEnemyInfo(): string {
|
|
|
- if (!this.enemyConfig) return '未知敌人';
|
|
|
-
|
|
|
- return `${this.enemyConfig.name}\n` +
|
|
|
- `类型: ${this.enemyConfig.type}\n` +
|
|
|
- `血量: ${this.currentHealth}/${this.enemyConfig.stats.health}\n` +
|
|
|
- `速度: ${this.enemyConfig.stats.speed}\n` +
|
|
|
- `伤害: ${this.enemyConfig.stats.damage}`;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取当前血量
|
|
|
- public getCurrentHealth(): number {
|
|
|
- return this.currentHealth;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取最大血量
|
|
|
- public getMaxHealth(): number {
|
|
|
- return this.enemyConfig?.stats?.health || 100;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取移动速度
|
|
|
- public getSpeed(): number {
|
|
|
- return this.enemyConfig?.stats?.speed || 50;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取攻击力
|
|
|
- public getDamage(): number {
|
|
|
- return this.enemyConfig?.stats?.damage || 20;
|
|
|
- }
|
|
|
-
|
|
|
- // 检查是否有特殊能力
|
|
|
- public hasSpecialAbility(ability: string): boolean {
|
|
|
- if (!this.enemyConfig || !this.enemyConfig.specialAbilities) return false;
|
|
|
-
|
|
|
- // 使用循环代替includes方法
|
|
|
- for (let i = 0; i < this.enemyConfig.specialAbilities.length; i++) {
|
|
|
- if (this.enemyConfig.specialAbilities[i] === ability) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
}
|