Browse Source

敌人待机

181404010226 2 months ago
parent
commit
2f2a96678d
1 changed files with 61 additions and 12 deletions
  1. 61 12
      assets/scripts/CombatSystem/EnemyInstance.ts

+ 61 - 12
assets/scripts/CombatSystem/EnemyInstance.ts

@@ -25,6 +25,7 @@ interface EnemyControllerType {
 enum EnemyState {
     DRIFTING, // 漂移中(从生成位置移动到线上)
     MOVING,   // 移动中
+    IDLE,     // 待机中(碰到墙体后停止移动但可以攻击)
     ATTACKING, // 攻击中
     DEAD      // 死亡
 }
@@ -438,17 +439,17 @@ export class EnemyInstance extends Component {
         // 检查是否碰到墙体(更严格的墙体识别)
         const isWall = this.isWallNode(otherCollider.node);
         if (isWall) {
-            console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 碰撞到墙体 ${nodeName},切换到攻击状态`);
+            console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 碰撞到墙体 ${nodeName},切换到待机状态`);
             
-            this.state = EnemyState.ATTACKING;
+            this.state = EnemyState.IDLE;
             this.attackTimer = 0; // 立即开始攻击
             this.collidedWall = otherCollider.node; // 记录碰撞的墙体
             
             // 停止移动
             this.stopRigidBodyMovement();
             
-            // 切换攻击动画
-            this.playAttackAnimation();
+            // 切换到待机动画
+            this.playIdleAnimation();
         }
     }
     
@@ -653,6 +654,8 @@ export class EnemyInstance extends Component {
             this.updateMovement(deltaTime);
             // 在移动状态检查墙体碰撞
             this.checkWallCollisionByDistance();
+        } else if (this.state === EnemyState.IDLE) {
+            this.updateIdle(deltaTime);
         } else if (this.state === EnemyState.ATTACKING) {
             this.updateAttack(deltaTime);
         }
@@ -858,6 +861,29 @@ export class EnemyInstance extends Component {
         }
     }
 
+    // 待机状态更新(停止移动但可以攻击)
+    private updateIdle(deltaTime: number) {
+        // 在待机状态下停止移动
+        const enemySprite = this.node.getChildByName('EnemySprite');
+        if (enemySprite) {
+            const rigidBody = enemySprite.getComponent(RigidBody2D);
+            if (rigidBody) {
+                // 停止物理移动
+                rigidBody.linearVelocity = new Vec2(0, 0);
+            }
+        }
+        
+        this.attackTimer -= deltaTime;
+        
+        if (this.attackTimer <= 0) {
+            // 执行攻击
+            this.performAttack();
+            
+            // 重置攻击计时器
+            this.attackTimer = this.attackInterval;
+        }
+    }
+
     // 执行攻击
     private performAttack() {
         if (!this.controller) {
@@ -939,6 +965,23 @@ export class EnemyInstance extends Component {
         }, 0.1);
     }
 
+    // 播放待机动画
+    private playIdleAnimation() {
+        if (!this.skeleton) return;
+        const enemyComp = this.getComponent('EnemyComponent') as any;
+        const anims = enemyComp?.getAnimations ? enemyComp.getAnimations() : {};
+        const idleName = anims.idle ?? 'idle';
+
+        if (this.skeleton.findAnimation(idleName)) {
+            this.skeleton.setAnimation(0, idleName, true);
+        }
+        
+        // 动画切换后延迟更新血条位置,确保动画尺寸已生效
+        this.scheduleOnce(() => {
+            this.updateHPBarPosition();
+        }, 0.1);
+    }
+
     // 播放攻击动画并在动画结束时造成伤害
     private playAttackAnimationWithDamage() {
         if (!this.skeleton) {
@@ -968,8 +1011,14 @@ export class EnemyInstance extends Component {
             // 使用定时器在动画结束时造成伤害
             this.scheduleOnce(() => {
                 this.dealDamageToWall();
-                // 动画完成后切换回行走动画
-                this.playWalkAnimation();
+                // 动画完成后根据当前状态切换动画
+                if (this.state === EnemyState.IDLE) {
+                    // 如果是待机状态,切换回待机动画
+                    this.playIdleAnimation();
+                } else {
+                    // 其他状态切换回行走动画
+                    this.playWalkAnimation();
+                }
             }, animationDuration);
         } else {
             // 如果找不到攻击动画,直接造成伤害
@@ -1136,8 +1185,8 @@ export class EnemyInstance extends Component {
      * 基于距离检查墙体碰撞
      */
     private checkWallCollisionByDistance(): void {
-        if (this.state === EnemyState.ATTACKING) {
-            return; // 已经在攻击状态,不需要再检查
+        if (this.state === EnemyState.ATTACKING || this.state === EnemyState.IDLE) {
+            return; // 已经在攻击状态或待机状态,不需要再检查
         }
 
         const enemySprite = this.node.getChildByName('EnemySprite');
@@ -1154,17 +1203,17 @@ export class EnemyInstance extends Component {
             const distance = Vec3.distance(currentPos, wallPos);
             
             if (distance <= collisionDistance) {
-                console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 距离检测到墙体 ${wallNode.name},距离: ${distance.toFixed(2)},切换到攻击状态`);
+                console.log(`[EnemyInstance] 敌人 ${this.getEnemyName()} 距离检测到墙体 ${wallNode.name},距离: ${distance.toFixed(2)},切换到待机状态`);
                 
-                this.state = EnemyState.ATTACKING;
+                this.state = EnemyState.IDLE;
                 this.attackTimer = 0; // 立即开始攻击
                 this.collidedWall = wallNode; // 记录碰撞的墙体
                 
                 // 停止移动
                 this.stopRigidBodyMovement();
                 
-                // 切换攻击动画
-                this.playAttackAnimation();
+                // 切换到待机动画
+                this.playIdleAnimation();
                 
                 return; // 找到一个墙体就停止检查
             }