Browse Source

停止向墙体移动

181404010226 2 months ago
parent
commit
f2aef3a7c5

File diff suppressed because it is too large
+ 217 - 145
assets/Scenes/GameLevel.scene


BIN
assets/data/excel/~$敌人配置表.xlsx


+ 12 - 0
assets/data/excel/~$敌人配置表.xlsx.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.0.0",
+  "importer": "*",
+  "imported": true,
+  "uuid": "5207e2b8-beeb-49ae-a4ea-6005d13702cf",
+  "files": [
+    ".json",
+    ".xlsx"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 2 - 2
assets/resources/prefabs/DamageNumber.prefab

@@ -76,7 +76,7 @@
     },
     "_contentSize": {
       "__type__": "cc.Size",
-      "width": 47.78,
+      "width": 120,
       "height": 40
     },
     "_anchorPoint": {
@@ -115,7 +115,7 @@
     "_string": "12",
     "_horizontalAlign": 1,
     "_verticalAlign": 1,
-    "_actualFontSize": 20,
+    "_actualFontSize": 25,
     "_fontSize": 25,
     "_fontFamily": "Arial",
     "_lineHeight": 40,

+ 2 - 2
assets/scripts/Animations/DamageNumberAni.ts

@@ -89,8 +89,8 @@ export class DamageNumberAni extends Component {
         // 设置伤害数字文本
         const label = damageNode.getComponent(Label);
         if (label) {
-            // 显示精确的伤害值,保留一位小数(如果有小数部分)
-            const damageText = damage % 1 === 0 ? damage.toString() : damage.toFixed(1);
+            // 将伤害值四舍五入为整数,不显示小数位
+            const damageText = Math.round(damage).toString();
             label.string = damageText;
             
             // 暴击时使用不同颜色

+ 70 - 26
assets/scripts/CombatSystem/EnemyInstance.ts

@@ -104,6 +104,12 @@ export class EnemyInstance extends Component {
     // 暂停状态标记
     private isPaused: boolean = false;
 
+    // 当前播放的动画名称,用于避免重复播放
+    private currentAnimationName: string = '';
+
+    // 攻击状态下的动画管理
+    private isPlayingAttackAnimation: boolean = false;
+
 
     start() {
         // 初始化敌人
@@ -861,20 +867,14 @@ export class EnemyInstance extends Component {
         const enemyComponent = this.getComponent(EnemyComponent);
         const attackRange = enemyComponent ? enemyComponent.getAttackRange() : 30;
         
-        if (attackRange <= 0) {
-            // 近战攻击:在攻击状态下停止移动
-            const enemySprite = this.node.getChildByName('EnemySprite');
-            if (enemySprite) {
-                const rigidBody = enemySprite.getComponent(RigidBody2D);
-                if (rigidBody) {
-                    // 停止物理移动
-                    rigidBody.linearVelocity = new Vec2(0, 0);
-                }
+        // 无论近战还是远程攻击,在攻击状态下都停止移动
+        const enemySprite = this.node.getChildByName('EnemySprite');
+        if (enemySprite) {
+            const rigidBody = enemySprite.getComponent(RigidBody2D);
+            if (rigidBody) {
+                // 停止物理移动
+                rigidBody.linearVelocity = new Vec2(0, 0);
             }
-        } else {
-            // 远程攻击:继续移动,但不需要在这里播放行走动画
-            // 攻击动画会在performRangedAttack中播放,完成后会根据状态切换回行走动画
-            this.updateMovement(deltaTime);
         }
         
         this.attackTimer -= deltaTime;
@@ -885,6 +885,11 @@ export class EnemyInstance extends Component {
             
             // 重置攻击计时器
             this.attackTimer = this.attackInterval;
+        } else {
+            // 攻击冷却期间播放待机动画(只有在不播放攻击动画时)
+            if (!this.isPlayingAttackAnimation) {
+                this.playIdleAnimationSafe();
+            }
         }
     }
 
@@ -959,6 +964,9 @@ export class EnemyInstance extends Component {
         if (animation) {
             // 播放攻击动画(不循环)
             this.skeleton.setAnimation(0, attackName, false);
+            this.currentAnimationName = attackName;
+            this.isPlayingAttackAnimation = true;
+            console.log(`[EnemyInstance] 播放远程攻击动画: ${attackName}`);
             
             // 动画切换后延迟更新血条位置,确保动画尺寸已生效
             this.scheduleOnce(() => {
@@ -977,11 +985,12 @@ export class EnemyInstance extends Component {
             
             // 动画完成后根据当前状态切换动画
             this.scheduleOnce(() => {
-                if (this.state === EnemyState.IDLE) {
-                    // 如果是待机状态,切换回待机动画
+                this.isPlayingAttackAnimation = false;
+                if (this.state === EnemyState.IDLE || this.state === EnemyState.ATTACKING) {
+                    // 如果是待机状态或攻击状态,切换回待机动画
                     this.playIdleAnimation();
-                } else if (this.state === EnemyState.ATTACKING) {
-                    // 如果还在攻击状态(移动中攻击),切换回行走动画
+                } else {
+                    // 其他状态切换回行走动画
                     this.playWalkAnimation();
                 }
             }, animationDuration);
@@ -1053,11 +1062,18 @@ export class EnemyInstance extends Component {
         const walkName = anims.walk ?? 'walk';
         const idleName = anims.idle ?? 'idle';
 
+        let animationToPlay = '';
         if (this.skeleton.findAnimation(walkName)) {
-            this.skeleton.setAnimation(0, walkName, true);
-            // 行走音效已移除
+            animationToPlay = walkName;
         } else if (this.skeleton.findAnimation(idleName)) {
-            this.skeleton.setAnimation(0, idleName, true);
+            animationToPlay = idleName;
+        }
+
+        if (animationToPlay && this.currentAnimationName !== animationToPlay) {
+            this.skeleton.setAnimation(0, animationToPlay, true);
+            this.currentAnimationName = animationToPlay;
+            this.isPlayingAttackAnimation = false;
+            console.log(`[EnemyInstance] 播放行走动画: ${animationToPlay}`);
         }
         
         // 动画切换后延迟更新血条位置,确保动画尺寸已生效
@@ -1073,10 +1089,11 @@ export class EnemyInstance extends Component {
         const anims2 = enemyComp2?.getAnimations ? enemyComp2.getAnimations() : {};
         const attackName = anims2.attack ?? 'attack';
 
-        // 移除频繁打印
-
-        if (this.skeleton.findAnimation(attackName)) {
+        if (this.skeleton.findAnimation(attackName) && this.currentAnimationName !== attackName) {
             this.skeleton.setAnimation(0, attackName, true);
+            this.currentAnimationName = attackName;
+            this.isPlayingAttackAnimation = true;
+            console.log(`[EnemyInstance] 播放攻击动画: ${attackName}`);
         }
         
         // 动画切换后延迟更新血条位置,确保动画尺寸已生效
@@ -1092,8 +1109,11 @@ export class EnemyInstance extends Component {
         const anims = enemyComp?.getAnimations ? enemyComp.getAnimations() : {};
         const idleName = anims.idle ?? 'idle';
 
-        if (this.skeleton.findAnimation(idleName)) {
+        if (this.skeleton.findAnimation(idleName) && this.currentAnimationName !== idleName) {
             this.skeleton.setAnimation(0, idleName, true);
+            this.currentAnimationName = idleName;
+            this.isPlayingAttackAnimation = false;
+            console.log(`[EnemyInstance] 播放待机动画: ${idleName}`);
         }
         
         // 动画切换后延迟更新血条位置,确保动画尺寸已生效
@@ -1102,6 +1122,26 @@ export class EnemyInstance extends Component {
         }, 0.1);
     }
 
+    // 安全播放待机动画(避免重复调用)
+    private playIdleAnimationSafe() {
+        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.currentAnimationName !== idleName && !this.isPlayingAttackAnimation) {
+            this.skeleton.setAnimation(0, idleName, true);
+            this.currentAnimationName = idleName;
+            console.log(`[EnemyInstance] 安全播放待机动画: ${idleName}`);
+            
+            // 动画切换后延迟更新血条位置,确保动画尺寸已生效
+            this.scheduleOnce(() => {
+                this.updateHPBarPosition();
+            }, 0.1);
+        }
+    }
+
     // 播放攻击动画并在动画结束时造成伤害
     private playAttackAnimationWithDamage() {
         if (!this.skeleton) {
@@ -1118,6 +1158,9 @@ export class EnemyInstance extends Component {
         if (animation) {
             // 播放攻击动画(不循环)
             this.skeleton.setAnimation(0, attackName, false);
+            this.currentAnimationName = attackName;
+            this.isPlayingAttackAnimation = true;
+            console.log(`[EnemyInstance] 播放近战攻击动画: ${attackName}`);
             
             // 动画切换后延迟更新血条位置,确保动画尺寸已生效
             this.scheduleOnce(() => {
@@ -1131,9 +1174,10 @@ export class EnemyInstance extends Component {
             // 使用定时器在动画结束时造成伤害
             this.scheduleOnce(() => {
                 this.dealDamageToWall();
+                this.isPlayingAttackAnimation = false;
                 // 动画完成后根据当前状态切换动画
-                if (this.state === EnemyState.IDLE) {
-                    // 如果是待机状态,切换回待机动画
+                if (this.state === EnemyState.IDLE || this.state === EnemyState.ATTACKING) {
+                    // 如果是待机状态或攻击状态,切换回待机动画
                     this.playIdleAnimation();
                 } else {
                     // 其他状态切换回行走动画

+ 14 - 1
assets/scripts/CombatSystem/SkillSelection/SkillSelectionController.ts

@@ -39,6 +39,16 @@ export class SkillSelectionController extends Component {
     start() {
         this.loadSkillConfig();
     }
+
+    /**
+     * 每次界面激活时刷新技能状态
+     */
+    protected onEnable() {
+        // 如果技能配置已加载,重新随机选择技能并更新UI
+        if (this._skillConfig && this.skillButtons.length > 0) {
+            this.randomizeSkills();
+        }
+    }
     
 
 
@@ -147,6 +157,9 @@ export class SkillSelectionController extends Component {
                 if (skillManager) {
                     const currentLevel = skillManager.getSkillLevel(skillData.id);
                     console.log(`[SkillSelectionController] 技能 ${skillData.name} 当前等级: ${currentLevel}`);
+                    
+                    // 强制刷新技能等级显示
+                    skillButton.refreshSkillLevel();
                 }
             } else {
                 skillButton.setSkillData(null);
@@ -222,7 +235,7 @@ export class SkillSelectionController extends Component {
             btn.setInteractable(true);
         });
         
-        // 重新随机选择技能
+        // 重新随机选择技能(这里会自动获取最新的技能等级状态)
         this.randomizeSkills();
     }
 

+ 64 - 20
assets/scripts/FourUI/MainSystem/MainUIControlller.ts

@@ -25,6 +25,8 @@ export class MainUIController extends Component {
   @property(Node) upgradeHpLabel: Node = null;       // 升级后血量数字
   @property(Label) upgradeCurrentHpLabel: Label = null;  // 当前血量Label
   @property(Label) upgradeNextHpLabel: Label = null;     // 升级后血量Label
+  @property(Label) upgradeInfoLabel: Label = null;       // 升级信息Label(显示"升级墙壁"或"已满级")
+  @property(Node) upgradeArrowNode: Node = null;         // 箭头符号节点xxtb
 
   /* 墙体配置 */
   // @property(JsonAsset) wallConfigAsset: JsonAsset = null;  // 墙体配置JSON资源 - 已改为动态加载
@@ -336,28 +338,70 @@ export class MainUIController extends Component {
     const costLbl = this.upgradeCostLabel?.getComponent(Label);
     const hpLbl = this.upgradeHpLabel?.getComponent(Label);
     
-    // 显示升级费用
     const currentLevel = this.sdm.getWallLevel();
-    const cost = this.getWallUpgradeCost(currentLevel);
-    if (costLbl) {
-      costLbl.string = cost.toString();
-      console.log(`[MainUIController] 升级费用: ${cost}`);
-    }
-
-    // 显示当前和下一级血量
-    const currentHp = this.getWallHealthByLevel(currentLevel);
-    
-    // 计算下一级血量 - 使用配置数据
-    const nextHp = this.getWallHealthByLevel(currentLevel + 1);
+    const maxLevel = this.getWallMaxLevel();
     
-    // 如果有新的分离Label,使用分离显示
-    if (this.upgradeCurrentHpLabel && this.upgradeNextHpLabel) {
-      this.upgradeCurrentHpLabel.string = `${currentHp}>>`;
-      this.upgradeNextHpLabel.string = `${nextHp}`;
-      console.log(`[MainUIController] 分离血量显示: 当前=${currentHp}, 升级后=${nextHp}, 当前等级: ${currentLevel}`);
-    }else {
-      console.error('[MainUIController] 升级信息标签未找到');
-      return;
+    // 检查是否已达到最大等级
+    if (currentLevel >= maxLevel) {
+      // 满级状态:显示"已满级",隐藏当前血量和箭头,只显示满级血量
+      if (this.upgradeInfoLabel) {
+        this.upgradeInfoLabel.string = "已满级";
+      }
+      
+      // 隐藏当前血量Label和箭头符号
+      if (this.upgradeCurrentHpLabel) {
+        this.upgradeCurrentHpLabel.node.active = false;
+      }
+      if (this.upgradeArrowNode) {
+        this.upgradeArrowNode.active = false;
+      }
+      
+      // 只显示满级血量
+      if (this.upgradeNextHpLabel) {
+        const maxHp = this.getWallHealthByLevel(currentLevel);
+        this.upgradeNextHpLabel.string = `${maxHp}`;
+        this.upgradeNextHpLabel.node.active = true;
+      }
+      
+      // 隐藏升级费用
+      if (costLbl) {
+        costLbl.string = "";
+      }
+      
+      console.log(`[MainUIController] 满级状态显示: 等级=${currentLevel}, 血量=${this.getWallHealthByLevel(currentLevel)}`);
+    } else {
+      // 非满级状态:正常显示升级信息
+      if (this.upgradeInfoLabel) {
+        this.upgradeInfoLabel.string = "升级墙壁";
+      }
+      
+      // 显示升级费用
+      const cost = this.getWallUpgradeCost(currentLevel);
+      if (costLbl) {
+        costLbl.string = cost.toString();
+        console.log(`[MainUIController] 升级费用: ${cost}`);
+      }
+
+      // 显示当前和下一级血量
+      const currentHp = this.getWallHealthByLevel(currentLevel);
+      const nextHp = this.getWallHealthByLevel(currentLevel + 1);
+      
+      // 显示当前血量Label和箭头符号
+      if (this.upgradeCurrentHpLabel) {
+        this.upgradeCurrentHpLabel.string = `${currentHp}>>`;
+        this.upgradeCurrentHpLabel.node.active = true;
+      }
+      if (this.upgradeArrowNode) {
+        this.upgradeArrowNode.active = true;
+      }
+      
+      // 显示升级后血量
+      if (this.upgradeNextHpLabel) {
+        this.upgradeNextHpLabel.string = `${nextHp}`;
+        this.upgradeNextHpLabel.node.active = true;
+      }
+      
+      console.log(`[MainUIController] 升级信息显示: 当前=${currentHp}, 升级后=${nextHp}, 当前等级: ${currentLevel}`);
     }
     
     // 升级按钮始终保持可点击状态,通过Toast显示各种提示

+ 9 - 0
assets/scripts/Guide.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "702fce6b-2ba2-4b79-94ae-14e1584ff043",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

Some files were not shown because too many files changed in this diff