浏览代码

敌人配置不起效修复

181404010226 3 月之前
父节点
当前提交
32c6a38124

+ 74 - 23
assets/resources/data/enemies.json

@@ -4,14 +4,15 @@
     "name": "普通僵尸",
     "type": "basic",
     "stats": {
-      "health": 35,
-      "maxHealth": 35,
+      "health": 45,
+      "maxHealth": 45,
       "defense": 0,
-      "speed": 30.0
+      "speed": 30.0,
+      "dropEnergy": 1
     },
     "movement": {
       "pattern": "direct",
-      "speed": 30.0,
+      "speed": 50.0,
       "patrolRange": 100,
       "chaseRange": 200,
       "rotationSpeed": 180.0,
@@ -21,18 +22,18 @@
       "speedVariation": 0.1
     },
     "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
+      "attackDamage": 2,
+      "attackRange": 30.0,
+      "attackSpeed": 0.4,
       "canBlock": false,
       "blockChance": 0.0,
       "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
+      "attackCooldown": 3.0,
       "attackType": "melee",
       "attackDelay": 1.0,
       "weaponType": "none",
       "projectileType": "none",
-      "projectileSpeed": 100.0
+      "projectileSpeed": 50.0
     },
     "visualConfig": {
       "spritePath": "Animation/EnemyAni/001",
@@ -88,7 +89,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "roadblock_zombie",
@@ -180,7 +182,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "wandering_zombie",
@@ -272,7 +275,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "mage_zombie",
@@ -364,7 +368,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "archer_zombie",
@@ -456,7 +461,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "stealth_zombie",
@@ -467,7 +473,7 @@
       "maxHealth": 42,
       "defense": 0,
       "speed": 35.0,
-      "dropEnergy": 2
+      "dropEnergy": 4
     },
     "movement": {
       "pattern": "direct",
@@ -548,7 +554,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "bucket_zombie",
@@ -640,7 +647,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "barrel_zombie",
@@ -732,7 +740,8 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.0,
       "rage_speed_multiplier": 1.0
-    }
+    },
+    "special_abilities": []
   },
   {
     "id": "boss1_gatekeeper",
@@ -845,7 +854,21 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.5,
       "rage_speed_multiplier": 1.3
-    }
+    },
+    "special_abilities": [
+      {
+        "type": "charge_attack",
+        "damage": 1,
+        "range": 150,
+        "cooldown": 8
+      },
+      {
+        "type": "area_attack",
+        "damage": 2,
+        "range": 100,
+        "cooldown": 12
+      }
+    ]
   },
   {
     "id": "boss2_gravedigger",
@@ -944,7 +967,7 @@
     },
     "audio": {
       "attack_sound": "data/弹球音效/hammer1.mp3",
-      "death_sound": "data/弹球音效/boss die.mp3",
+      "death_sound": "data/弹球音效/boss die.mp4",
       "hit_sound": "Null",
       "walk_sound": "Null",
       "block_sound": "nan",
@@ -958,7 +981,21 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.5,
       "rage_speed_multiplier": 1.3
-    }
+    },
+    "special_abilities": [
+      {
+        "type": "charge_attack",
+        "damage": 1,
+        "range": 150,
+        "cooldown": 8
+      },
+      {
+        "type": "area_attack",
+        "damage": 2,
+        "range": 100,
+        "cooldown": 12
+      }
+    ]
   },
   {
     "id": "boss3_cyborg",
@@ -1057,7 +1094,7 @@
     },
     "audio": {
       "attack_sound": "data/弹球音效/hammer1.mp3",
-      "death_sound": "data/弹球音效/boss die.mp3",
+      "death_sound": "data/弹球音效/boss die.mp5",
       "hit_sound": "Null",
       "walk_sound": "Null",
       "block_sound": "nan",
@@ -1071,6 +1108,20 @@
       "rage_threshold": 0.3,
       "rage_damage_multiplier": 1.5,
       "rage_speed_multiplier": 1.3
-    }
+    },
+    "special_abilities": [
+      {
+        "type": "charge_attack",
+        "damage": 1,
+        "range": 150,
+        "cooldown": 8
+      },
+      {
+        "type": "area_attack",
+        "damage": 2,
+        "range": 100,
+        "cooldown": 12
+      }
+    ]
   }
 ]

二进制
assets/resources/data/excel/__pycache__/enemy_config_manager.cpython-313.pyc


二进制
assets/resources/data/excel/__pycache__/level_config_manager.cpython-313.pyc


二进制
assets/resources/data/excel/__pycache__/weapon_config_manager.cpython-313.pyc


+ 61 - 57
assets/resources/data/excel/enemy_config_manager.py

@@ -67,8 +67,8 @@ class EnemyConfigManager:
             raise FileNotFoundError(f"Excel文件不存在: {self.excel_path}")
         
         try:
-            # 读取所有工作表
-            excel_data = pd.read_excel(self.excel_path, sheet_name=None)
+            # 读取所有工作表,不指定header以保留所有行
+            excel_data = pd.read_excel(self.excel_path, sheet_name=None, header=None)
             print(f"找到工作表: {list(excel_data.keys())}")
             
             # 解析各个工作表
@@ -95,9 +95,9 @@ class EnemyConfigManager:
             return {}
         
         config = {}
-        for index, row in df.iterrows():
-            if index == 0:  # 跳过标题行
-                continue
+        # 从第1行开始处理(跳过第0行标题)
+        for i in range(1, len(df)):
+            row = df.iloc[i]
             
             enemy_id = str(row.iloc[0]).strip()
             if pd.isna(row.iloc[0]) or enemy_id == '':
@@ -184,31 +184,36 @@ class EnemyConfigManager:
         
         visual_config = {}
         
-        for _, row in df.iterrows():
-            enemy_id = str(row.get('敌人ID', '')).strip()
-            if not enemy_id or enemy_id == '敌人ID':
+        for index, row in df.iterrows():
+            if index == 0:  # 跳过标题行
+                continue
+                
+            enemy_id = str(row.iloc[0]).strip()
+            if pd.isna(row.iloc[0]) or enemy_id == '':
                 continue
                 
             config = {
-                'sprite_path': str(row.get('精灵路径', '')).strip(),
-                'scale': float(row.get('缩放比例', 1.0)),
-                'animation_speed': float(row.get('动画速度', 1.0)),
-                'flip_horizontal': bool(row.get('水平翻转', False)),
+                'sprite_path': str(row.iloc[1]) if not pd.isna(row.iloc[1]) else '',
+                'scale': float(row.iloc[2]) if not pd.isna(row.iloc[2]) else 1.0,
+                'animation_speed': float(row.iloc[3]) if not pd.isna(row.iloc[3]) else 1.0,
+                'flip_horizontal': bool(row.iloc[4]) if not pd.isna(row.iloc[4]) else False,
                 'animations': {
-                    'idle': str(row.get('待机动画', 'idle')).strip(),
-                    'walk': str(row.get('行走动画', 'walk')).strip(),
-                    'attack': str(row.get('攻击动画', 'attack')).strip(),
-                    'death': str(row.get('死亡动画', 'dead')).strip()
+                    'idle': str(row.iloc[5]) if not pd.isna(row.iloc[5]) else 'idle',
+                    'walk': str(row.iloc[6]) if not pd.isna(row.iloc[6]) else 'walk',
+                    'attack': str(row.iloc[7]) if not pd.isna(row.iloc[7]) else 'attack',
+                    'death': str(row.iloc[8]) if not pd.isna(row.iloc[8]) else 'dead'
                 }
             }
             
             # 武器道具(可选)
-            weapon_prop = str(row.get('武器道具', '')).strip()
-            if weapon_prop:
-                config['weapon_prop'] = weapon_prop
+            if len(row) > 9 and not pd.isna(row.iloc[9]):
+                weapon_prop = str(row.iloc[9]).strip()
+                if weapon_prop:
+                    config['weapon_prop'] = weapon_prop
                 
             visual_config[enemy_id] = config
             
+        print(f"解析视觉配置: {len(visual_config)} 个敌人")
         return visual_config
     
     def _parse_audio_config(self, df):
@@ -218,33 +223,24 @@ class EnemyConfigManager:
         
         audio_config = {}
         
-        for _, row in df.iterrows():
-            enemy_id = str(row.get('敌人ID', '')).strip()
-            if not enemy_id or enemy_id == '敌人ID':
+        for index, row in df.iterrows():
+            if index == 0:  # 跳过标题行
+                continue
+                
+            enemy_id = str(row.iloc[0]).strip()
+            if pd.isna(row.iloc[0]) or enemy_id == '':
                 continue
                 
             config = {
-                'attack_sound': str(row.get('攻击音效', '')).strip(),
-                'death_sound': str(row.get('死亡音效', '')).strip(),
-                'hit_sound': str(row.get('受击音效', '')).strip(),
-                'walk_sound': str(row.get('行走音效', '')).strip()
+                'attack_sound': str(row.iloc[1]) if not pd.isna(row.iloc[1]) else '',
+                'death_sound': str(row.iloc[2]) if not pd.isna(row.iloc[2]) else '',
+                'hit_sound': str(row.iloc[3]) if not pd.isna(row.iloc[3]) else '',
+                'walk_sound': str(row.iloc[4]) if not pd.isna(row.iloc[4]) else ''
             }
             
-            # 可选音效
-            optional_sounds = {
-                'block_sound': '格挡音效',
-                'stealth_sound': '隐身音效', 
-                'armor_break_sound': '护甲破碎音效',
-                'fuse_sound': '引信音效'
-            }
-            
-            for key, col_name in optional_sounds.items():
-                sound = str(row.get(col_name, '')).strip()
-                if sound:
-                    config[key] = sound
-                    
             audio_config[enemy_id] = config
             
+        print(f"解析音频配置: {len(audio_config)} 个敌人")
         return audio_config
     
     def _parse_special_abilities(self, df):
@@ -254,12 +250,15 @@ class EnemyConfigManager:
         
         abilities_config = {}
         
-        for _, row in df.iterrows():
-            enemy_id = str(row.get('敌人ID', '')).strip()
-            if not enemy_id or enemy_id == '敌人ID':
+        for index, row in df.iterrows():
+            if index == 0:  # 跳过标题行
+                continue
+                
+            enemy_id = str(row.iloc[0]).strip()
+            if pd.isna(row.iloc[0]) or enemy_id == '':
                 continue
                 
-            ability_type = str(row.get('能力类型', '')).strip()
+            ability_type = str(row.iloc[1]).strip() if not pd.isna(row.iloc[1]) else ''
             if not ability_type:
                 # 没有特殊能力的敌人
                 if enemy_id not in abilities_config:
@@ -268,15 +267,16 @@ class EnemyConfigManager:
                 
             ability = {
                 'type': ability_type,
-                'damage': int(row.get('伤害', 0)),
-                'range': int(row.get('范围', 0)),
-                'cooldown': int(row.get('冷却时间', 0))
+                'damage': int(row.iloc[2]) if not pd.isna(row.iloc[2]) else 0,
+                'range': int(row.iloc[3]) if not pd.isna(row.iloc[3]) else 0,
+                'cooldown': int(row.iloc[4]) if not pd.isna(row.iloc[4]) else 0
             }
             
             if enemy_id not in abilities_config:
                 abilities_config[enemy_id] = []
             abilities_config[enemy_id].append(ability)
             
+        print(f"解析特殊能力配置: {len(abilities_config)} 个敌人")
         return abilities_config
     
     def _parse_boss_config(self, df):
@@ -286,21 +286,25 @@ class EnemyConfigManager:
         
         boss_config = {}
         
-        for _, row in df.iterrows():
-            enemy_id = str(row.get('敌人ID', '')).strip()
-            if not enemy_id or enemy_id == '敌人ID':
+        for index, row in df.iterrows():
+            if index == 0:  # 跳过标题行
+                continue
+                
+            enemy_id = str(row.iloc[0]).strip()
+            if pd.isna(row.iloc[0]) or enemy_id == '':
                 continue
                 
             config = {
-                'is_boss': bool(row.get('是否BOSS', False)),
-                'phases': int(row.get('阶段数', 1)),
-                'rage_threshold': float(row.get('狂暴阈值', 0.3)),
-                'rage_damage_multiplier': float(row.get('狂暴伤害倍数', 1.0)),
-                'rage_speed_multiplier': float(row.get('狂暴速度倍数', 1.0))
+                'is_boss': bool(row.iloc[1]) if not pd.isna(row.iloc[1]) else False,
+                'phases': int(row.iloc[2]) if not pd.isna(row.iloc[2]) else 1,
+                'rage_threshold': float(row.iloc[3]) if not pd.isna(row.iloc[3]) else 0.3,
+                'rage_damage_multiplier': float(row.iloc[4]) if not pd.isna(row.iloc[4]) else 1.0,
+                'rage_speed_multiplier': float(row.iloc[5]) if not pd.isna(row.iloc[5]) else 1.0
             }
             
             boss_config[enemy_id] = config
             
+        print(f"解析BOSS配置: {len(boss_config)} 个敌人")
         return boss_config
     
     def merge_configurations(self):
@@ -314,7 +318,7 @@ class EnemyConfigManager:
         
         # 获取所有Excel中的敌人ID
         excel_enemy_ids = set()
-        for config_type in ['basic', 'combat', 'movement', 'visual', 'audio', 'special_abilities', 'boss']:
+        for config_type in ['basic', 'combat', 'movement', 'visual', 'audio', 'special', 'boss']:
             if config_type in self.excel_data:
                 excel_enemy_ids.update(self.excel_data[config_type].keys())
         
@@ -435,8 +439,8 @@ class EnemyConfigManager:
                 enemy_config['audio'][key] = value
         
         # 更新特殊能力配置
-        if 'special_abilities' in self.excel_data and enemy_id in self.excel_data['special_abilities']:
-            abilities_data = self.excel_data['special_abilities'][enemy_id]
+        if 'special' in self.excel_data and enemy_id in self.excel_data['special']:
+            abilities_data = self.excel_data['special'][enemy_id]
             
             if 'special_abilities' not in enemy_config:
                 enemy_config['special_abilities'] = []

二进制
assets/resources/data/excel/敌人配置表.xlsx