فهرست منبع

武器外观粗略

181404010226 3 ماه پیش
والد
کامیت
1321b25c81
34فایلهای تغییر یافته به همراه1872 افزوده شده و 2045 حذف شده
  1. 24 0
      assets/Scenes/GameLevel.scene
  2. 253 13
      assets/Scenes/TestScene.scene
  3. 3 3
      assets/assets/Prefabs/Blocks/Block002.prefab
  4. 1 1
      assets/resources/data/backups/levels/Level1_20250827_094518.json.meta
  5. 1 1
      assets/resources/data/backups/levels/Level1_20250827_094831.json.meta
  6. 11 0
      assets/resources/data/backups/levels/Level2_20250827_094517.json.meta
  7. 11 0
      assets/resources/data/backups/levels/Level2_20250827_094831.json.meta
  8. 11 0
      assets/resources/data/backups/levels/Level3_20250827_094518.json.meta
  9. 11 0
      assets/resources/data/backups/levels/Level3_20250827_094831.json.meta
  10. 11 0
      assets/resources/data/backups/levels/Level4_20250827_094517.json.meta
  11. 11 0
      assets/resources/data/backups/levels/Level4_20250827_094831.json.meta
  12. 11 0
      assets/resources/data/backups/levels/Level5_20250827_094517.json.meta
  13. 11 0
      assets/resources/data/backups/levels/Level5_20250827_094831.json.meta
  14. 11 0
      assets/resources/data/backups/levels/Level6_20250827_094518.json.meta
  15. 11 0
      assets/resources/data/backups/levels/Level6_20250827_094831.json.meta
  16. 11 0
      assets/resources/data/backups/levels/Level7_20250827_094517.json.meta
  17. 11 0
      assets/resources/data/backups/levels/Level7_20250827_094831.json.meta
  18. 11 0
      assets/resources/data/backups/levels/Level8_20250827_094517.json.meta
  19. 11 0
      assets/resources/data/backups/levels/Level8_20250827_094831.json.meta
  20. 11 0
      assets/resources/data/backups/levels/Level9_20250827_094518.json.meta
  21. 11 0
      assets/resources/data/backups/levels/Level9_20250827_094831.json.meta
  22. 0 736
      assets/resources/data/enemies_backup_20250820_103011.json
  23. 0 1066
      assets/resources/data/enemies_backup_20250820_170519.json
  24. BIN
      assets/resources/data/excel/__pycache__/weapon_config_manager.cpython-313.pyc
  25. 331 0
      assets/resources/data/excel/generate_excel_from_json.py
  26. 12 0
      assets/resources/data/excel/generate_excel_from_json.py.meta
  27. 129 7
      assets/resources/data/excel/weapon_config_manager.py
  28. BIN
      assets/resources/data/excel/方块武器配置/方块武器配置表.xlsx
  29. 112 0
      assets/resources/data/weapon_shape_position_offsets.json
  30. 11 0
      assets/resources/data/weapon_shape_position_offsets.json.meta
  31. 132 72
      assets/resources/data/weapons.json
  32. 65 145
      assets/scripts/CombatSystem/BlockManager.ts
  33. 621 0
      assets/scripts/TestScene/WeaponBlockTestScript.ts
  34. 1 1
      assets/scripts/TestScene/WeaponBlockTestScript.ts.meta

+ 24 - 0
assets/Scenes/GameLevel.scene

@@ -27632,6 +27632,26 @@
       {
         "__uuid__": "2c3693c7-a923-439d-899e-ca0d5340572a",
         "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "1776637a-37c8-4115-b758-0433a17d8f01",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "c5c50d29-4d75-4053-a182-b8e756372fb8",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "fc4bc660-4efd-48b7-8f4d-04db9f3c23cc",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "9da27476-ca02-4534-bfc5-a2075a400849",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "100736d9-f230-4018-9613-c3f4d99843cb",
+        "__expectedType__": "cc.Prefab"
       }
     ],
     "gridContainer": {
@@ -27646,6 +27666,10 @@
     "placedBlocksContainer": {
       "__id__": 267
     },
+    "weaponShapePositionOffsetsAsset": {
+      "__uuid__": "fb9a0105-f68e-4ae5-b313-5d761d5d2612",
+      "__expectedType__": "cc.JsonAsset"
+    },
     "_id": "19nrhqXPpAQ7nRPaH27rI/"
   },
   {

+ 253 - 13
assets/Scenes/TestScene.scene

@@ -23,7 +23,7 @@
     "_active": true,
     "_components": [],
     "_prefab": {
-      "__id__": 8
+      "__id__": 14
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -54,7 +54,7 @@
     },
     "autoReleaseAssets": false,
     "_globals": {
-      "__id__": 9
+      "__id__": 15
     },
     "_id": "8a125a67-dbc5-4c64-b398-6a616deee4aa"
   },
@@ -69,18 +69,21 @@
     "_children": [
       {
         "__id__": 3
+      },
+      {
+        "__id__": 5
       }
     ],
     "_active": true,
     "_components": [
       {
-        "__id__": 5
+        "__id__": 11
       },
       {
-        "__id__": 6
+        "__id__": 12
       },
       {
-        "__id__": 7
+        "__id__": 13
       }
     ],
     "_prefab": null,
@@ -204,6 +207,243 @@
     "_trackingType": 0,
     "_id": "63WIch3o5BEYRlXzTT0oWc"
   },
+  {
+    "__type__": "cc.Node",
+    "_name": "Test",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [
+      {
+        "__id__": 6
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 9
+      },
+      {
+        "__id__": 10
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "c5vHvM5NtOhpvDIpWOcmIv"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "TestContainer",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 5
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 7
+      },
+      {
+        "__id__": 8
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 146.298,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "dakWNhS4dEx5a8FIq+sWMf"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 6
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 700,
+      "height": 1000
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "02LzZVgepKhY5pYUsCo5TT"
+  },
+  {
+    "__type__": "cc.Layout",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 6
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_resizeMode": 0,
+    "_layoutType": 3,
+    "_cellSize": {
+      "__type__": "cc.Size",
+      "width": 40,
+      "height": 40
+    },
+    "_startAxis": 0,
+    "_paddingLeft": 0,
+    "_paddingRight": 0,
+    "_paddingTop": 0,
+    "_paddingBottom": 0,
+    "_spacingX": 20,
+    "_spacingY": 0,
+    "_verticalDirection": 1,
+    "_horizontalDirection": 0,
+    "_constraint": 0,
+    "_constraintNum": 2,
+    "_affectedByScale": false,
+    "_isAlign": false,
+    "_id": "20seuYbhVOK5dqGNJalFC9"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 5
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 720,
+      "height": 1334
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "a3XpajTHZMiaZA76SrtJzL"
+  },
+  {
+    "__type__": "de769KSTUJOAIOEGPeHd7cR",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 5
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "testContainer": {
+      "__id__": 6
+    },
+    "blockPrefabs": [
+      {
+        "__uuid__": "9bd227fc-cc4f-46ca-bf7c-811318c3e88c",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "46f313aa-d24b-436e-a705-2dc1c6461f6e",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "498808e2-0ee8-40c6-8580-82a5a634d253",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "6fdf19f9-7e73-4b1c-9181-d72de52c0bd5",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "2c3693c7-a923-439d-899e-ca0d5340572a",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "1776637a-37c8-4115-b758-0433a17d8f01",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "c5c50d29-4d75-4053-a182-b8e756372fb8",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "fc4bc660-4efd-48b7-8f4d-04db9f3c23cc",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "9da27476-ca02-4534-bfc5-a2075a400849",
+        "__expectedType__": "cc.Prefab"
+      },
+      {
+        "__uuid__": "100736d9-f230-4018-9613-c3f4d99843cb",
+        "__expectedType__": "cc.Prefab"
+      }
+    ],
+    "weaponsConfigAsset": {
+      "__uuid__": "b0dff099-9502-41f9-8678-6126d42ddd68",
+      "__expectedType__": "cc.JsonAsset"
+    },
+    "_id": "a2wq705cJMCLQc8vFvM3cA"
+  },
   {
     "__type__": "cc.UITransform",
     "_name": "",
@@ -283,28 +523,28 @@
   {
     "__type__": "cc.SceneGlobals",
     "ambient": {
-      "__id__": 10
+      "__id__": 16
     },
     "shadows": {
-      "__id__": 11
+      "__id__": 17
     },
     "_skybox": {
-      "__id__": 12
+      "__id__": 18
     },
     "fog": {
-      "__id__": 13
+      "__id__": 19
     },
     "octree": {
-      "__id__": 14
+      "__id__": 20
     },
     "skin": {
-      "__id__": 15
+      "__id__": 21
     },
     "lightProbeInfo": {
-      "__id__": 16
+      "__id__": 22
     },
     "postSettings": {
-      "__id__": 17
+      "__id__": 23
     },
     "bakedWithStationaryMainLight": false,
     "bakedWithHighpLightmap": false

+ 3 - 3
assets/assets/Prefabs/Blocks/Block002.prefab

@@ -242,8 +242,8 @@
       "__type__": "cc.Quat",
       "x": 0,
       "y": 0,
-      "z": 0,
-      "w": 1
+      "z": 0.7071067811865475,
+      "w": 0.7071067811865476
     },
     "_lscale": {
       "__type__": "cc.Vec3",
@@ -257,7 +257,7 @@
       "__type__": "cc.Vec3",
       "x": 0,
       "y": 0,
-      "z": 0
+      "z": 90
     },
     "_id": ""
   },

+ 1 - 1
assets/resources/data/enemies_backup_20250820_103011.json.meta → assets/resources/data/backups/levels/Level1_20250827_094518.json.meta

@@ -2,7 +2,7 @@
   "ver": "2.0.1",
   "importer": "json",
   "imported": true,
-  "uuid": "696d2fc9-6742-4cf6-b1b2-0eea44c56492",
+  "uuid": "ea4932bc-c840-4a4f-bda4-4e8428076345",
   "files": [
     ".json"
   ],

+ 1 - 1
assets/resources/data/enemies_backup_20250820_170519.json.meta → assets/resources/data/backups/levels/Level1_20250827_094831.json.meta

@@ -2,7 +2,7 @@
   "ver": "2.0.1",
   "importer": "json",
   "imported": true,
-  "uuid": "b0e53274-1641-466c-a059-8d788642a3e0",
+  "uuid": "98b49889-e180-4786-a145-5e42dfddf315",
   "files": [
     ".json"
   ],

+ 11 - 0
assets/resources/data/backups/levels/Level2_20250827_094517.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "e89ef364-0213-4b26-b871-45380bfa4414",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level2_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "d1402ce1-650a-428b-a2d6-c39901ef8023",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level3_20250827_094518.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "51ecde33-49a5-46f8-b068-fd22eaea2fa1",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level3_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "fd6877d1-dc3c-49f5-9fff-ccf2882e841c",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level4_20250827_094517.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "4814e80d-862a-45d3-b354-2fb592ef11b4",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level4_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "103949c5-4d98-4abb-9d7b-80621be0be2c",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level5_20250827_094517.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "a3ec2f68-b6a0-492b-b36b-fff98efc52a0",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level5_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "0b3cc170-950e-408a-8a04-f9f7e994c73b",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level6_20250827_094518.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "2b05bf95-0651-4420-8529-ca0ddb83b82e",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level6_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "96901cbb-ab0f-4ed7-acc6-90c3f8df4384",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level7_20250827_094517.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "0b47251f-b885-452a-a0e9-ad04e3d9210b",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level7_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "3f656cb0-9c3d-46dc-a49d-dcd265cce8bd",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level8_20250827_094517.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "ec9fad3d-f87c-43b4-b74d-ef71a0274438",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level8_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "62364005-807a-4406-933d-e6fdfc67e01c",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level9_20250827_094518.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "e6b00134-e5c2-41ce-ac4d-27f710c49110",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 11 - 0
assets/resources/data/backups/levels/Level9_20250827_094831.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "b9ff01f8-6282-4428-9271-f41fdb0f4300",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 0 - 736
assets/resources/data/enemies_backup_20250820_103011.json

@@ -1,736 +0,0 @@
-[
-  {
-    "id": "normal_zombie",
-    "name": "普通僵尸",
-    "type": "basic",
-    "stats": {
-      "health": 35,
-      "maxHealth": 35,
-      "defense": 0,
-      "speed": 30.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 30.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/001",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/baseball_bat"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/zombie_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "roadblock_zombie",
-    "name": "路障僵尸",
-    "type": "armored",
-    "stats": {
-      "health": 50,
-      "maxHealth": 50,
-      "defense": 0,
-      "speed": 25.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 25.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/002",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/magic_staff"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/roadblock_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "wandering_zombie",
-    "name": "漫步僵尸",
-    "type": "wanderer",
-    "stats": {
-      "health": 42,
-      "maxHealth": 42,
-      "defense": 0,
-      "speed": 35.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 35.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "sway",
-      "swingAmplitude": 20.0,
-      "swingFrequency": 2.0,
-      "speedVariation": 0.2
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "melee_weapon",
-      "attackDelay": 1.0,
-      "weaponType": "baseball_bat",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/003",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/bow"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/wandering_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "mage_zombie",
-    "name": "法师僵尸",
-    "type": "ranged_caster",
-    "stats": {
-      "health": 25,
-      "maxHealth": 25,
-      "defense": 0,
-      "speed": 15.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 15.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "magic_projectile",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "magic_bolt",
-      "projectileSpeed": 50.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/004",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/mage_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "archer_zombie",
-    "name": "弓箭僵尸",
-    "type": "ranged_archer",
-    "stats": {
-      "health": 25,
-      "maxHealth": 25,
-      "defense": 0,
-      "speed": 15.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 15.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "arrow_projectile",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "arrow",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/005",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/archer_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "stealth_zombie",
-    "name": "隐身僵尸",
-    "type": "stealth",
-    "stats": {
-      "health": 42,
-      "maxHealth": 42,
-      "defense": 0,
-      "speed": 35.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 35.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "stealth_strike",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/006",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/stealth_walk",
-      "blockSound": "",
-      "stealthSound": "audio/stealth_activate",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "bucket_zombie",
-    "name": "铁桶僵尸",
-    "type": "heavy_armor",
-    "stats": {
-      "health": 70,
-      "maxHealth": 70,
-      "defense": 0,
-      "speed": 15.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 15.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "heavy_melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/007",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/iron_gate"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/bucket_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "audio/armor_break",
-      "fuseSound": "",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "barrel_zombie",
-    "name": "火药桶僵尸",
-    "type": "explosive",
-    "stats": {
-      "health": 35,
-      "maxHealth": 35,
-      "defense": 0,
-      "speed": 30.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 30.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/008",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/tombstone"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/barrel_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "audio/barrel_fuse",
-      "volume": 1.0
-    }
-  },
-  {
-    "id": "boss1_gatekeeper",
-    "name": "BOSS1",
-    "type": "boss",
-    "stats": {
-      "health": 500,
-      "maxHealth": 500,
-      "defense": 0,
-      "speed": 10.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 10.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "gate_slam",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/009",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/cyber_arm"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/boss1_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "specialAbilities": [
-      {
-        "type": "charge_attack",
-        "damage": 1,
-        "range": 150.0,
-        "cooldown": 8.0
-      },
-      {
-        "type": "area_attack",
-        "damage": 2,
-        "range": 100.0,
-        "cooldown": 12.0
-      }
-    ],
-    "bossConfig": {
-      "isBoss": true,
-      "phases": 1,
-      "enrageThreshold": 0.3,
-      "enrageDamageMultiplier": 1.5,
-      "enrageSpeedMultiplier": 1.3
-    }
-  },
-  {
-    "id": "boss2_gravedigger",
-    "name": "BOSS2",
-    "type": "boss",
-    "stats": {
-      "health": 500,
-      "maxHealth": 500,
-      "defense": 0,
-      "speed": 10.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 10.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "tombstone_smash",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/010",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/boss2_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "specialAbilities": [
-      {
-        "type": "charge_attack",
-        "damage": 1,
-        "range": 150.0,
-        "cooldown": 8.0
-      },
-      {
-        "type": "area_attack",
-        "damage": 2,
-        "range": 100.0,
-        "cooldown": 12.0
-      }
-    ],
-    "bossConfig": {
-      "isBoss": true,
-      "phases": 1,
-      "enrageThreshold": 0.3,
-      "enrageDamageMultiplier": 1.5,
-      "enrageSpeedMultiplier": 1.3
-    }
-  },
-  {
-    "id": "boss3_cyborg",
-    "name": "BOSS3",
-    "type": "boss",
-    "stats": {
-      "health": 250,
-      "maxHealth": 250,
-      "defense": 0,
-      "speed": 10.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 10.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "cyber_arm_combo",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/011",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/boss3_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "specialAbilities": [
-      {
-        "type": "charge_attack",
-        "damage": 1,
-        "range": 150.0,
-        "cooldown": 8.0
-      },
-      {
-        "type": "area_attack",
-        "damage": 2,
-        "range": 100.0,
-        "cooldown": 12.0
-      }
-    ],
-    "bossConfig": {
-      "isBoss": true,
-      "phases": 1,
-      "enrageThreshold": 0.3,
-      "enrageDamageMultiplier": 1.5,
-      "enrageSpeedMultiplier": 1.3
-    }
-  }
-]

+ 0 - 1066
assets/resources/data/enemies_backup_20250820_170519.json

@@ -1,1066 +0,0 @@
-[
-  {
-    "id": "normal_zombie",
-    "name": "普通僵尸",
-    "type": "basic",
-    "stats": {
-      "health": 35,
-      "maxHealth": 35,
-      "defense": 0,
-      "speed": 30.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 30.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 1.0,
-      "attackSpeed": 1.0,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 1.0,
-      "attackType": "melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/001",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/baseball_bat"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/zombie_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/001",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "props/baseball_bat"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/zombie_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "roadblock_zombie",
-    "name": "路障僵尸",
-    "type": "armored",
-    "stats": {
-      "health": 50,
-      "maxHealth": 50,
-      "defense": 1,
-      "speed": 25.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 40.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 30.0,
-      "attackSpeed": 0.3,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 3.0,
-      "attackType": "melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/002",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/magic_staff"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/roadblock_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/002",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "props/magic_staff"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/roadblock_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "wandering_zombie",
-    "name": "漫步僵尸",
-    "type": "wanderer",
-    "stats": {
-      "health": 42,
-      "maxHealth": 42,
-      "defense": 0,
-      "speed": 35.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 45.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "sway",
-      "swingAmplitude": 20.0,
-      "swingFrequency": 2.0,
-      "speedVariation": 0.2
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 30.0,
-      "attackSpeed": 0.4,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 3.0,
-      "attackType": "melee_weapon",
-      "attackDelay": 1.0,
-      "weaponType": "baseball_bat",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/003",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/bow"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/wandering_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/003",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "props/bow"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/wandering_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "mage_zombie",
-    "name": "法师僵尸",
-    "type": "ranged_caster",
-    "stats": {
-      "health": 25,
-      "maxHealth": 25,
-      "defense": 0,
-      "speed": 15.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 35.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 200.0,
-      "attackSpeed": 0.2,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 4.0,
-      "attackType": "magic_projectile",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "magic_bolt",
-      "projectileSpeed": 50.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/004",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/mage_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/004",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "nan"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/mage_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "archer_zombie",
-    "name": "弓箭僵尸",
-    "type": "ranged_archer",
-    "stats": {
-      "health": 25,
-      "maxHealth": 25,
-      "defense": 0,
-      "speed": 15.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 40.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 250.0,
-      "attackSpeed": 0.2,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 4.0,
-      "attackType": "arrow_projectile",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "arrow",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/005",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/archer_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/005",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "nan"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/archer_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "stealth_zombie",
-    "name": "隐身僵尸",
-    "type": "stealth",
-    "stats": {
-      "health": 42,
-      "maxHealth": 42,
-      "defense": 0,
-      "speed": 35.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 60.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 30.0,
-      "attackSpeed": 0.4,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 3.0,
-      "attackType": "stealth_strike",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/006",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/stealth_walk",
-      "blockSound": "",
-      "stealthSound": "audio/stealth_activate",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/006",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "nan"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/stealth_walk",
-      "block_sound": "nan",
-      "stealth_sound": "audio/stealth_activate",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "bucket_zombie",
-    "name": "铁桶僵尸",
-    "type": "heavy_armor",
-    "stats": {
-      "health": 70,
-      "maxHealth": 70,
-      "defense": 2,
-      "speed": 15.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 30.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 30.0,
-      "attackSpeed": 0.3,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 4.0,
-      "attackType": "heavy_melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/007",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/iron_gate"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/bucket_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "audio/armor_break",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/007",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "props/iron_gate"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/bucket_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "audio/armor_break",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "barrel_zombie",
-    "name": "火药桶僵尸",
-    "type": "explosive",
-    "stats": {
-      "health": 35,
-      "maxHealth": 35,
-      "defense": 0,
-      "speed": 30.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 45.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 30.0,
-      "attackSpeed": 0.3,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 3.0,
-      "attackType": "melee",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/008",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/tombstone"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/barrel_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "audio/barrel_fuse",
-      "volume": 1.0
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/008",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "props/tombstone"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/barrel_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "audio/barrel_fuse"
-    },
-    "boss": {
-      "is_boss": false,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.0,
-      "rage_speed_multiplier": 1.0
-    }
-  },
-  {
-    "id": "boss1_gatekeeper",
-    "name": "BOSS1",
-    "type": "boss",
-    "stats": {
-      "health": 500,
-      "maxHealth": 500,
-      "defense": 2,
-      "speed": 10.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 25.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 30.0,
-      "attackSpeed": 0.2,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 4.0,
-      "attackType": "gate_slam",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/009",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": "props/cyber_arm"
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/boss1_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "specialAbilities": [
-      {
-        "type": "charge_attack",
-        "damage": 1,
-        "range": 150.0,
-        "cooldown": 8.0
-      },
-      {
-        "type": "area_attack",
-        "damage": 2,
-        "range": 100.0,
-        "cooldown": 12.0
-      }
-    ],
-    "bossConfig": {
-      "isBoss": true,
-      "phases": 1,
-      "enrageThreshold": 0.3,
-      "enrageDamageMultiplier": 1.5,
-      "enrageSpeedMultiplier": 1.3
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/009",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "props/cyber_arm"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/boss1_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": true,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.5,
-      "rage_speed_multiplier": 1.3
-    }
-  },
-  {
-    "id": "boss2_gravedigger",
-    "name": "BOSS2",
-    "type": "boss",
-    "stats": {
-      "health": 500,
-      "maxHealth": 500,
-      "defense": 3,
-      "speed": 10.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 20.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 30.0,
-      "attackSpeed": 0.2,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 5.0,
-      "attackType": "tombstone_smash",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/010",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/boss2_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "specialAbilities": [
-      {
-        "type": "charge_attack",
-        "damage": 1,
-        "range": 150.0,
-        "cooldown": 8.0
-      },
-      {
-        "type": "area_attack",
-        "damage": 2,
-        "range": 100.0,
-        "cooldown": 12.0
-      }
-    ],
-    "bossConfig": {
-      "isBoss": true,
-      "phases": 1,
-      "enrageThreshold": 0.3,
-      "enrageDamageMultiplier": 1.5,
-      "enrageSpeedMultiplier": 1.3
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/010",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "nan"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/boss2_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": true,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.5,
-      "rage_speed_multiplier": 1.3
-    }
-  },
-  {
-    "id": "boss3_cyborg",
-    "name": "BOSS3",
-    "type": "boss",
-    "stats": {
-      "health": 250,
-      "maxHealth": 250,
-      "defense": 1,
-      "speed": 10.0
-    },
-    "movement": {
-      "pattern": "direct",
-      "speed": 35.0,
-      "patrolRange": 100,
-      "chaseRange": 200,
-      "rotationSpeed": 180.0,
-      "moveType": "straight",
-      "swingAmplitude": 0.0,
-      "swingFrequency": 0.0,
-      "speedVariation": 0.1
-    },
-    "combat": {
-      "attackDamage": 1,
-      "attackRange": 80.0,
-      "attackSpeed": 0.2,
-      "canBlock": false,
-      "blockChance": 0.0,
-      "blockDamageReduction": 0.5,
-      "attackCooldown": 4.0,
-      "attackType": "cyber_arm_combo",
-      "attackDelay": 1.0,
-      "weaponType": "none",
-      "projectileType": "none",
-      "projectileSpeed": 100.0
-    },
-    "visualConfig": {
-      "spritePath": "Animation/EnemyAni/011",
-      "scale": 1.0,
-      "animationSpeed": 1.0,
-      "flipX": false,
-      "tint": "#FFFFFF",
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weaponProp": ""
-    },
-    "audioConfig": {
-      "attackSound": "enemy_attack",
-      "deathSound": "enemy_death",
-      "hitSound": "enemy_hit",
-      "walkSound": "audio/boss3_walk",
-      "blockSound": "",
-      "stealthSound": "",
-      "armorBreakSound": "",
-      "fuseSound": "",
-      "volume": 1.0
-    },
-    "specialAbilities": [
-      {
-        "type": "charge_attack",
-        "damage": 1,
-        "range": 150.0,
-        "cooldown": 8.0
-      },
-      {
-        "type": "area_attack",
-        "damage": 2,
-        "range": 100.0,
-        "cooldown": 12.0
-      }
-    ],
-    "bossConfig": {
-      "isBoss": true,
-      "phases": 1,
-      "enrageThreshold": 0.3,
-      "enrageDamageMultiplier": 1.5,
-      "enrageSpeedMultiplier": 1.3
-    },
-    "visual": {
-      "sprite_path": "Animation/EnemyAni/011",
-      "scale": 1.0,
-      "animation_speed": 1.0,
-      "flip_horizontal": false,
-      "animations": {
-        "idle": "idle",
-        "walk": "walk",
-        "attack": "attack",
-        "death": "dead"
-      },
-      "weapon_prop": "nan"
-    },
-    "audio": {
-      "attack_sound": "enemy_attack",
-      "death_sound": "enemy_death",
-      "hit_sound": "enemy_hit",
-      "walk_sound": "audio/boss3_walk",
-      "block_sound": "nan",
-      "stealth_sound": "nan",
-      "armor_break_sound": "nan",
-      "fuse_sound": "nan"
-    },
-    "boss": {
-      "is_boss": true,
-      "phases": 1,
-      "rage_threshold": 0.3,
-      "rage_damage_multiplier": 1.5,
-      "rage_speed_multiplier": 1.3
-    }
-  }
-]

BIN
assets/resources/data/excel/__pycache__/weapon_config_manager.cpython-313.pyc


+ 331 - 0
assets/resources/data/excel/generate_excel_from_json.py

@@ -0,0 +1,331 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+从weapons.json生成Excel配置表
+确保Excel配置与JSON配置保持同步
+"""
+
+import json
+import os
+from pathlib import Path
+from datetime import datetime
+
+try:
+    import pandas as pd
+    PANDAS_AVAILABLE = True
+except ImportError:
+    PANDAS_AVAILABLE = False
+    print("错误: pandas未安装,无法生成Excel文件")
+    print("请运行: pip install pandas openpyxl")
+    exit(1)
+
+class WeaponExcelGenerator:
+    """从weapons.json生成Excel配置表的工具类"""
+    
+    def __init__(self, json_file_path=None, excel_output_path=None):
+        """初始化生成器
+        
+        Args:
+            json_file_path: weapons.json文件路径
+            excel_output_path: 输出Excel文件路径
+        """
+        self.script_dir = Path(__file__).parent
+        
+        # 设置默认路径
+        if json_file_path is None:
+            self.json_file = self.script_dir.parent / "weapons.json"
+        else:
+            self.json_file = Path(json_file_path)
+            
+        if excel_output_path is None:
+            self.excel_file = self.script_dir / "方块武器配置" / "方块武器配置表.xlsx"
+        else:
+            self.excel_file = Path(excel_output_path)
+            
+        print(f"JSON文件路径: {self.json_file}")
+        print(f"Excel输出路径: {self.excel_file}")
+        
+        # 确保输出目录存在
+        self.excel_file.parent.mkdir(parents=True, exist_ok=True)
+    
+    def load_weapons_json(self):
+        """加载weapons.json文件"""
+        try:
+            if not self.json_file.exists():
+                raise FileNotFoundError(f"JSON文件不存在: {self.json_file}")
+                
+            with open(self.json_file, 'r', encoding='utf-8') as f:
+                config = json.load(f)
+                
+            print(f"成功加载JSON配置,包含 {len(config.get('weapons', []))} 个武器")
+            return config
+            
+        except Exception as e:
+            print(f"加载JSON配置失败: {e}")
+            raise
+    
+    def create_weapon_base_config_sheet(self, weapons_data):
+        """创建武器基础配置工作表"""
+        base_config_data = []
+        
+        # 表头
+        headers = [
+            'ID', '名称', '类型', '稀有度', '权重', 
+            '伤害', '射速', '射程', '子弹速度', '子弹数量',
+            '子弹轨迹类型', '子弹速度值', '穿透数', '反弹次数',
+            '精灵路径', '音效路径'
+        ]
+        
+        for weapon in weapons_data:
+            # 提取基础信息
+            weapon_id = weapon.get('id', '')
+            name = weapon.get('name', '')
+            weapon_type = weapon.get('type', '')
+            rarity = weapon.get('rarity', '')
+            weight = weapon.get('weight', 0)
+            
+            # 提取统计信息
+            stats = weapon.get('stats', {})
+            damage = stats.get('damage', 0)
+            fire_rate = stats.get('fireRate', 0.0)
+            weapon_range = stats.get('range', 0)
+            bullet_speed = stats.get('bulletSpeed', 0)
+            
+            # 提取子弹配置
+            bullet_config = weapon.get('bulletConfig', {})
+            bullet_count = bullet_config.get('bulletCount', 1)
+            
+            # 提取轨迹配置
+            trajectory = bullet_config.get('trajectory', {})
+            trajectory_type = trajectory.get('type', '')
+            trajectory_speed = trajectory.get('speed', 0)
+            pierce_count = trajectory.get('pierceCount', 0)
+            bounce_count = trajectory.get('bounceCount', 0)
+            
+            # 提取视觉配置
+            visuals = weapon.get('visuals', {})
+            sprite_path = visuals.get('spritePath', '')
+            sound_path = visuals.get('soundPath', '')
+            
+            base_config_data.append([
+                weapon_id, name, weapon_type, rarity, weight,
+                damage, fire_rate, weapon_range, bullet_speed, bullet_count,
+                trajectory_type, trajectory_speed, pierce_count, bounce_count,
+                sprite_path, sound_path
+            ])
+        
+        # 创建DataFrame
+        df = pd.DataFrame(base_config_data, columns=headers)
+        return df
+    
+    def create_upgrade_cost_sheet(self, weapons_data):
+        """创建武器升级费用配置工作表"""
+        upgrade_data = []
+        
+        # 表头:武器ID + 等级1-10费用 + 等级1-10伤害
+        headers = ['武器ID', '武器名称', '基础伤害', '最大伤害']
+        
+        # 添加等级1-10的费用列
+        for level in range(1, 11):
+            headers.append(f'等级{level}费用')
+        
+        # 添加等级1-10的伤害列
+        for level in range(1, 11):
+            headers.append(f'等级{level}伤害')
+        
+        for weapon in weapons_data:
+            weapon_id = weapon.get('id', '')
+            weapon_name = weapon.get('name', '')
+            base_damage = weapon.get('stats', {}).get('damage', 0)
+            
+            # 获取升级配置
+            upgrade_config = weapon.get('upgradeConfig', {})
+            levels = upgrade_config.get('levels', {})
+            
+            row_data = [weapon_id, weapon_name, base_damage]
+            
+            # 计算最大伤害
+            max_damage = base_damage
+            for level in range(1, 11):
+                level_config = levels.get(str(level), {})
+                level_damage = level_config.get('damage', base_damage)
+                if level_damage > max_damage:
+                    max_damage = level_damage
+            
+            row_data.append(max_damage)
+            
+            # 添加等级1-10的费用
+            for level in range(1, 11):
+                level_config = levels.get(str(level), {})
+                cost = level_config.get('cost', '')
+                row_data.append(cost)
+            
+            # 添加等级1-10的伤害
+            for level in range(1, 11):
+                level_config = levels.get(str(level), {})
+                damage = level_config.get('damage', base_damage)
+                row_data.append(damage)
+            
+            upgrade_data.append(row_data)
+        
+        # 创建DataFrame
+        df = pd.DataFrame(upgrade_data, columns=headers)
+        return df
+    
+    def create_game_cost_sheet(self, weapons_data):
+        """创建游戏内成本配置工作表"""
+        cost_data = []
+        
+        # 表头
+        headers = [
+            '武器ID', '武器名称', '武器基础售价',
+            'I形状成本', 'H-I形状成本', 'L形状成本', 
+            'S形状成本', 'D-T形状成本', 'O形状成本',
+            'T形状成本', 'Z形状成本', 'J形状成本', 'U形状成本'
+        ]
+        
+        for weapon in weapons_data:
+            weapon_id = weapon.get('id', '')
+            weapon_name = weapon.get('name', '')
+            
+            # 获取游戏内成本配置
+            cost_config = weapon.get('inGameCostConfig', {})
+            base_cost = cost_config.get('baseCost', 5)
+            shape_costs = cost_config.get('shapeCosts', {})
+            
+            row_data = [weapon_id, weapon_name, base_cost]
+            
+            # 添加各形状成本
+            shape_keys = ['I', 'H-I', 'L', 'S', 'D-T', 'O', 'T', 'Z', 'J', 'U']
+            for shape_key in shape_keys:
+                cost = shape_costs.get(shape_key, '')
+                row_data.append(cost)
+            
+            cost_data.append(row_data)
+        
+        # 创建DataFrame
+        df = pd.DataFrame(cost_data, columns=headers)
+        return df
+    
+    def create_rarity_weights_sheet(self, config_data):
+        """创建稀有度权重配置工作表"""
+        rarity_weights = config_data.get('rarityWeights', {})
+        
+        rarity_data = []
+        headers = ['稀有度', '权重', '描述']
+        
+        # 稀有度描述映射
+        rarity_descriptions = {
+            'common': '普通',
+            'uncommon': '不常见',
+            'rare': '稀有',
+            'epic': '史诗'
+        }
+        
+        for rarity, weight in rarity_weights.items():
+            description = rarity_descriptions.get(rarity, '')
+            rarity_data.append([rarity, weight, description])
+        
+        # 创建DataFrame
+        df = pd.DataFrame(rarity_data, columns=headers)
+        return df
+    
+    def create_block_shapes_sheet(self, config_data):
+        """创建方块形状配置工作表"""
+        block_sizes = config_data.get('blockSizes', [])
+        
+        shape_data = []
+        headers = ['ID', '名称', '形状矩阵', '占用格数', '成本倍数', '描述']
+        
+        for shape in block_sizes:
+            shape_id = shape.get('id', '')
+            name = shape.get('name', '')
+            shape_matrix = str(shape.get('shape', []))
+            grid_count = shape.get('gridCount', 0)
+            cost_multiplier = shape.get('costMultiplier', 1)
+            description = shape.get('description', '')
+            
+            shape_data.append([
+                shape_id, name, shape_matrix, grid_count, cost_multiplier, description
+            ])
+        
+        # 创建DataFrame
+        df = pd.DataFrame(shape_data, columns=headers)
+        return df
+    
+    def generate_excel_file(self):
+        """生成Excel配置文件"""
+        try:
+            # 加载JSON配置
+            config_data = self.load_weapons_json()
+            weapons_data = config_data.get('weapons', [])
+            
+            if not weapons_data:
+                print("警告: 没有找到武器数据")
+                return False
+            
+            print(f"开始生成Excel文件,包含 {len(weapons_data)} 个武器...")
+            
+            # 创建Excel写入器
+            with pd.ExcelWriter(self.excel_file, engine='openpyxl') as writer:
+                # 创建武器基础配置工作表
+                base_config_df = self.create_weapon_base_config_sheet(weapons_data)
+                base_config_df.to_excel(writer, sheet_name='武器基础配置', index=False)
+                print("✓ 创建武器基础配置工作表")
+                
+                # 创建武器升级费用配置工作表
+                upgrade_cost_df = self.create_upgrade_cost_sheet(weapons_data)
+                upgrade_cost_df.to_excel(writer, sheet_name='武器升级费用配置', index=False)
+                print("✓ 创建武器升级费用配置工作表")
+                
+                # 创建游戏内成本配置工作表
+                game_cost_df = self.create_game_cost_sheet(weapons_data)
+                game_cost_df.to_excel(writer, sheet_name='游戏内成本配置', index=False)
+                print("✓ 创建游戏内成本配置工作表")
+                
+                # 创建稀有度权重配置工作表
+                rarity_weights_df = self.create_rarity_weights_sheet(config_data)
+                rarity_weights_df.to_excel(writer, sheet_name='稀有度权重配置', index=False)
+                print("✓ 创建稀有度权重配置工作表")
+                
+                # 创建方块形状配置工作表
+                block_shapes_df = self.create_block_shapes_sheet(config_data)
+                block_shapes_df.to_excel(writer, sheet_name='方块形状配置', index=False)
+                print("✓ 创建方块形状配置工作表")
+            
+            print(f"\n✅ Excel文件生成成功: {self.excel_file}")
+            print(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+            return True
+            
+        except Exception as e:
+            print(f"❌ 生成Excel文件失败: {e}")
+            return False
+
+def main():
+    """主函数"""
+    print("=== 从weapons.json生成Excel配置表 ===")
+    print(f"开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+    print()
+    
+    # 创建生成器
+    generator = WeaponExcelGenerator()
+    
+    # 生成Excel文件
+    success = generator.generate_excel_file()
+    
+    if success:
+        print("\n🎉 Excel配置表生成完成!")
+        print("\n生成的工作表包括:")
+        print("  1. 武器基础配置 - 包含所有武器的基本属性")
+        print("  2. 武器升级费用配置 - 包含武器升级的费用和伤害配置")
+        print("  3. 游戏内成本配置 - 包含武器在游戏中的购买成本")
+        print("  4. 稀有度权重配置 - 包含武器稀有度的权重分布")
+        print("  5. 方块形状配置 - 包含所有方块形状的定义")
+    else:
+        print("\n❌ Excel配置表生成失败!")
+        return 1
+    
+    return 0
+
+if __name__ == '__main__':
+    exit(main())

+ 12 - 0
assets/resources/data/excel/generate_excel_from_json.py.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.0.0",
+  "importer": "*",
+  "imported": true,
+  "uuid": "2e575893-20c2-4a7e-bcc4-3f75ebd771f7",
+  "files": [
+    ".json",
+    ".py"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 129 - 7
assets/resources/data/excel/weapon_config_manager.py

@@ -874,6 +874,133 @@ class WeaponConfigManager:
             print(f"导入武器配置失败: {e}")
             return False
 
+    def sync_json_to_excel(self):
+        """将JSON配置同步到Excel文件"""
+        try:
+            print("开始将JSON配置同步到Excel文件...")
+            
+            # 导入生成器模块
+            from generate_excel_from_json import WeaponExcelGenerator
+            
+            # 创建Excel生成器
+            generator = WeaponExcelGenerator(
+                json_file_path=str(self.json_file),
+                excel_output_path=str(self.excel_file)
+            )
+            
+            # 生成Excel文件
+            success = generator.generate_excel_file()
+            
+            if success:
+                print("✓ JSON配置已成功同步到Excel文件")
+                return True
+            else:
+                print("✗ JSON配置同步到Excel文件失败")
+                return False
+                
+        except Exception as e:
+            print(f"同步JSON到Excel失败: {e}")
+            return False
+    
+    def sync_excel_to_json(self):
+        """将Excel配置同步到JSON文件"""
+        try:
+            print("开始将Excel配置同步到JSON文件...")
+            
+            # 使用现有的导入方法
+            success = self.import_weapon_config()
+            
+            if success:
+                print("✓ Excel配置已成功同步到JSON文件")
+                return True
+            else:
+                print("✗ Excel配置同步到JSON文件失败")
+                return False
+                
+        except Exception as e:
+            print(f"同步Excel到JSON失败: {e}")
+            return False
+    
+    def show_sync_menu(self):
+        """显示同步菜单"""
+        while True:
+            print("\n武器配置同步工具")
+            print("=" * 50)
+            print("1. 从JSON同步到Excel (推荐)")
+            print("2. 从Excel同步到JSON")
+            print("3. 查看文件状态")
+            print("4. 退出")
+            print("=" * 50)
+            
+            choice = input("请选择操作 (1-4): ").strip()
+            
+            if choice == '1':
+                print("\n正在从JSON同步到Excel...")
+                success = self.sync_json_to_excel()
+                if success:
+                    print("🎉 同步完成!Excel文件已更新")
+                else:
+                    print("❌ 同步失败!")
+                    
+            elif choice == '2':
+                print("\n正在从Excel同步到JSON...")
+                success = self.sync_excel_to_json()
+                if success:
+                    print("🎉 同步完成!JSON文件已更新")
+                else:
+                    print("❌ 同步失败!")
+                    
+            elif choice == '3':
+                self.show_file_status()
+                
+            elif choice == '4':
+                print("\n再见!")
+                break
+                
+            else:
+                print("\n❌ 无效选择,请重新输入")
+    
+    def show_file_status(self):
+        """显示文件状态"""
+        print("\n文件状态信息")
+        print("-" * 30)
+        
+        # JSON文件状态
+        if self.json_file.exists():
+            json_mtime = datetime.fromtimestamp(self.json_file.stat().st_mtime)
+            print(f"✓ JSON文件: {self.json_file}")
+            print(f"  最后修改: {json_mtime.strftime('%Y-%m-%d %H:%M:%S')}")
+            
+            try:
+                with open(self.json_file, 'r', encoding='utf-8') as f:
+                    config = json.load(f)
+                    weapon_count = len(config.get('weapons', []))
+                    print(f"  武器数量: {weapon_count}")
+            except Exception as e:
+                print(f"  读取失败: {e}")
+        else:
+            print(f"❌ JSON文件不存在: {self.json_file}")
+        
+        print()
+        
+        # Excel文件状态
+        if self.excel_file.exists():
+            excel_mtime = datetime.fromtimestamp(self.excel_file.stat().st_mtime)
+            print(f"✓ Excel文件: {self.excel_file}")
+            print(f"  最后修改: {excel_mtime.strftime('%Y-%m-%d %H:%M:%S')}")
+            
+            try:
+                if PANDAS_AVAILABLE:
+                    sheets = pd.read_excel(self.excel_file, sheet_name=None)
+                    print(f"  工作表数量: {len(sheets)}")
+                    print(f"  工作表名称: {list(sheets.keys())}")
+                else:
+                    print("  无法读取详细信息 (pandas未安装)")
+            except Exception as e:
+                print(f"  读取失败: {e}")
+        else:
+            print(f"❌ Excel文件不存在: {self.excel_file}")
+
 def main():
     """主函数"""
     print("武器配置管理器")
@@ -882,13 +1009,8 @@ def main():
     # 创建武器配置管理器
     manager = WeaponConfigManager()
     
-    # 导入配置
-    success = manager.import_weapon_config()
-    
-    if success:
-        print("\n✓ 武器配置导入完成")
-    else:
-        print("\n✗ 武器配置导入失败")
+    # 显示同步菜单
+    manager.show_sync_menu()
 
 if __name__ == "__main__":
     main()

BIN
assets/resources/data/excel/方块武器配置/方块武器配置表.xlsx


+ 112 - 0
assets/resources/data/weapon_shape_position_offsets.json

@@ -0,0 +1,112 @@
+{
+  "weapon_shape_position_offsets": {
+    "pea_shooter": {
+      "I": { "x": 4, "y": -3 },
+      "H-I": { "x": 0, "y": 5 },
+      "L": { "x": 1, "y": -10 },
+      "L2": { "x": 10, "y": -10 },
+      "L3": { "x": -5, "y": -5 },
+      "L4": { "x": 5, "y": -5 },
+      "S": { "x": 5, "y": -1 },
+      "S-F": { "x": -5, "y": -1 },
+      "D-T": { "x": 4, "y": -1 },
+      "T": { "x": 10, "y": 1 }
+    },
+    "sharp_carrot": {
+      "I": { "x": 0, "y": -1 },
+      "H-I": { "x": 0, "y": 0 },
+      "L": { "x": -1, "y": -7 },
+      "L2": { "x": 1, "y": -7 },
+      "L3": { "x": -1, "y": -3 },
+      "L4": { "x": 1, "y": -3 },
+      "S": { "x": 1, "y": -1 },
+      "S-F": { "x": -1, "y": -1 },
+      "D-T": { "x": 0, "y": -1 },
+      "T": { "x": 0, "y": 1 }
+    },
+    "saw_grass": {
+      "I": { "x": 0, "y": -1 },
+      "H-I": { "x": 0, "y": 0 },
+      "L": { "x": -1, "y": -1 },
+      "L2": { "x": 1, "y": -1 },
+      "L3": { "x": -1, "y": 1 },
+      "L4": { "x": 1, "y": 1 },
+      "S": { "x": 1, "y": -1 },
+      "S-F": { "x": -1, "y": -1 },
+      "D-T": { "x": 0, "y": -5 },
+      "T": { "x": 0, "y": 5 }
+    },
+    "watermelon_bomb": {
+      "I": { "x": 0, "y": -1 },
+      "H-I": { "x": 0, "y": 0 },
+      "L": { "x": -1, "y": -1 },
+      "L2": { "x": 1, "y": -1 },
+      "L3": { "x": -1, "y": 1 },
+      "L4": { "x": 1, "y": 1 },
+      "S": { "x": 1, "y": -1 },
+      "S-F": { "x": -1, "y": -1 },
+      "D-T": { "x": 0, "y": -7 },
+      "T": { "x": 0, "y": 7 }
+    },
+    "boomerang_plant": {
+      "I": { "x": 0, "y": -1 },
+      "H-I": { "x": 0, "y": 0 },
+      "L": { "x": -1, "y": -8 },
+      "L2": { "x": 1, "y": -8 },
+      "L3": { "x": -5, "y": -4 },
+      "L4": { "x": 1, "y": -4 },
+      "S": { "x": 1, "y": -1 },
+      "S-F": { "x": -1, "y": -1 },
+      "D-T": { "x": -5, "y": -10 },
+      "T": { "x": 10, "y": 7 }
+    },
+    "hot_pepper": {
+      "I": { "x": 0, "y": 5 },
+      "H-I": { "x": 0, "y": 0 },
+      "L": { "x": -1, "y": -1 },
+      "L2": { "x": 1, "y": -1 },
+      "L3": { "x": -1, "y": 6 },
+      "L4": { "x": 1, "y": 6 },
+      "S": { "x": 1, "y": -1 },
+      "S-F": { "x": -1, "y": -1 },
+      "D-T": { "x": 0, "y": 0 },
+      "T": { "x": 0, "y": 0 }
+    },
+    "cactus_shotgun": {
+      "I": { "x": 0, "y": -1 },
+      "H-I": { "x": 0, "y": 0 },
+      "L": { "x": -1, "y": -3 },
+      "L2": { "x": 1, "y": -3 },
+      "L3": { "x": -1, "y": 1 },
+      "L4": { "x": 1, "y": 1 },
+      "S": { "x": 1, "y": -1 },
+      "S-F": { "x": -1, "y": -1 },
+      "D-T": { "x": 0, "y": -1 },
+      "T": { "x": 0, "y": 1 }
+    },
+    "okra_missile": {
+      "I": { "x": -4, "y": 3 },
+      "H-I": { "x": 0, "y": -3 },
+      "L": { "x": -5, "y": -9 },
+      "L2": { "x": 1, "y": -12 },
+      "L3": { "x": -3, "y": -5 },
+      "L4": { "x": -10, "y": -3 },
+      "S": { "x": -6, "y": 0 },
+      "S-F": { "x": 6, "y": 0 },
+      "D-T": { "x": -3, "y": 3 },
+      "T": { "x": 3, "y": -3 }
+    },
+    "mace_club": {
+      "I": { "x": 0, "y": -1 },
+      "H-I": { "x": 1, "y": 0 },
+      "L": { "x": -1, "y": -1 },
+      "L2": { "x": 1, "y": -1 },
+      "L3": { "x": -1, "y": 1 },
+      "L4": { "x": 1, "y": 1 },
+      "S": { "x": 1, "y": -1 },
+      "S-F": { "x": -1, "y": -1 },
+      "D-T": { "x": 0, "y": -5 },
+      "T": { "x": 0, "y": 5 }
+    }
+  }
+}

+ 11 - 0
assets/resources/data/weapon_shape_position_offsets.json.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "2.0.1",
+  "importer": "json",
+  "imported": true,
+  "uuid": "fb9a0105-f68e-4ae5-b313-5d761d5d2612",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 132 - 72
assets/resources/data/weapons.json

@@ -99,13 +99,7 @@
       },
       "inGameCostConfig": {
         "baseCost": 5,
-        "shapeCosts": {
-          "I": 10,
-          "H-I": 10,
-          "L": 15,
-          "S": 20,
-          "D-T": 20
-        }
+        "shapeCosts": {}
       }
     },
     {
@@ -209,13 +203,7 @@
       },
       "inGameCostConfig": {
         "baseCost": 6,
-        "shapeCosts": {
-          "I": 12,
-          "H-I": 12,
-          "L": 18,
-          "S": 24,
-          "D-T": 24
-        }
+        "shapeCosts": {}
       }
     },
     {
@@ -325,13 +313,7 @@
       },
       "inGameCostConfig": {
         "baseCost": 6,
-        "shapeCosts": {
-          "I": 12,
-          "H-I": 12,
-          "L": 18,
-          "S": 24,
-          "D-T": 24
-        }
+        "shapeCosts": {}
       }
     },
     {
@@ -436,13 +418,7 @@
       },
       "inGameCostConfig": {
         "baseCost": 10,
-        "shapeCosts": {
-          "I": 20,
-          "H-I": 20,
-          "L": 30,
-          "S": 40,
-          "D-T": 40
-        }
+        "shapeCosts": {}
       }
     },
     {
@@ -545,13 +521,7 @@
       },
       "inGameCostConfig": {
         "baseCost": 6,
-        "shapeCosts": {
-          "I": 12,
-          "H-I": 12,
-          "L": 18,
-          "S": 24,
-          "D-T": 24
-        }
+        "shapeCosts": {}
       }
     },
     {
@@ -661,13 +631,7 @@
       },
       "inGameCostConfig": {
         "baseCost": 10,
-        "shapeCosts": {
-          "I": 20,
-          "H-I": 20,
-          "L": 30,
-          "S": 40,
-          "D-T": 40
-        }
+        "shapeCosts": {}
       }
     },
     {
@@ -770,13 +734,7 @@
       },
       "inGameCostConfig": {
         "baseCost": 10,
-        "shapeCosts": {
-          "I": 20,
-          "H-I": 20,
-          "L": 30,
-          "S": 40,
-          "D-T": 40
-        }
+        "shapeCosts": {}
       }
     },
     {
@@ -881,13 +839,115 @@
       },
       "inGameCostConfig": {
         "baseCost": 15,
-        "shapeCosts": {
-          "I": 30,
-          "H-I": 30,
-          "L": 45,
-          "S": 60,
-          "D-T": 60
+        "shapeCosts": {}
+      }
+    },
+    {
+      "id": "mace_club",
+      "name": "狼牙棒",
+      "type": "melee",
+      "rarity": "uncommon",
+      "weight": 20,
+      "stats": {
+        "damage": 25,
+        "fireRate": 8.0,
+        "range": 200,
+        "bulletSpeed": 35
+      },
+      "bulletConfig": {
+        "count": {
+          "type": "single",
+          "amount": 1,
+          "spreadAngle": 0,
+          "burstCount": 1,
+          "burstDelay": 0
+        },
+        "trajectory": {
+          "type": "straight",
+          "speed": 250,
+          "gravity": 0,
+          "arcHeight": 0,
+          "homingStrength": 0,
+          "homingDelay": 0
+        },
+        "hitEffects": [
+          {
+            "type": "normal_damage",
+            "priority": 1,
+            "damage": 25
+          },
+          {
+            "type": "knockback",
+            "priority": 2,
+            "force": 150
+          }
+        ],
+        "lifecycle": {
+          "type": "range_limit",
+          "maxLifetime": 3.0,
+          "penetration": 2,
+          "ricochetCount": 0,
+          "returnToOrigin": false,
+          "maxRange": 200
+        },
+        "visual": {
+          "bulletImages": "images/PlantsSprite/009",
+          "hitEffect": "Animation/WeaponTx/tx0002/tx0002",
+          "trailEffect": true
         }
+      },
+      "visualConfig": {
+        "weaponSprites": "images/PlantsSprite/009",
+        "attackSound": "data/弹球音效/mace_club_hit"
+      },
+      "upgradeConfig": {
+        "maxLevel": 10,
+        "levels": {
+          "1": {
+            "cost": 140,
+            "damage": 25
+          },
+          "2": {
+            "cost": 210,
+            "damage": 28
+          },
+          "3": {
+            "cost": 280,
+            "damage": 31
+          },
+          "4": {
+            "cost": 350,
+            "damage": 34
+          },
+          "5": {
+            "cost": 420,
+            "damage": 37
+          },
+          "6": {
+            "cost": 490,
+            "damage": 40
+          },
+          "7": {
+            "cost": 560,
+            "damage": 43
+          },
+          "8": {
+            "cost": 630,
+            "damage": 46
+          },
+          "9": {
+            "cost": 700,
+            "damage": 49
+          },
+          "10": {
+            "cost": 770,
+            "damage": 52
+          }
+        }
+      },
+      "inGameCostConfig": {
+        "baseCost": 8,
+        "shapeCosts": {}
       }
     }
   ],
@@ -903,7 +963,7 @@
           0
         ],
         [
-          1,
+          0,
           0,
           0,
           0
@@ -936,8 +996,8 @@
           0
         ],
         [
-          1,
-          1,
+          0,
+          0,
           0,
           0
         ],
@@ -969,7 +1029,7 @@
           0
         ],
         [
-          1,
+          0,
           0,
           0,
           0
@@ -1002,8 +1062,8 @@
           0
         ],
         [
-          1,
-          1,
+          0,
+          0,
           0,
           0
         ],
@@ -1035,9 +1095,9 @@
           0
         ],
         [
-          1,
-          1,
-          1,
+          0,
+          0,
+          0,
           0
         ],
         [
@@ -1069,7 +1129,7 @@
         ],
         [
           0,
-          1,
+          0,
           0,
           0
         ],
@@ -1101,8 +1161,8 @@
           0
         ],
         [
-          1,
-          1,
+          0,
+          0,
           0,
           0
         ],
@@ -1134,8 +1194,8 @@
           0
         ],
         [
-          1,
-          1,
+          0,
+          0,
           0,
           0
         ],
@@ -1168,8 +1228,8 @@
         ],
         [
           0,
-          1,
-          1,
+          0,
+          0,
           0
         ],
         [
@@ -1201,7 +1261,7 @@
         ],
         [
           0,
-          1,
+          0,
           0,
           0
         ],

+ 65 - 145
assets/scripts/CombatSystem/BlockManager.ts

@@ -1,4 +1,4 @@
-import { _decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, Color, Vec2, UITransform, find, Rect, Label, Size, Sprite, SpriteFrame, resources, Button, Collider2D, Material, tween } from 'cc';
+import { _decorator, Component, Node, Prefab, instantiate, Vec3, EventTouch, Color, Vec2, UITransform, find, Rect, Label, Size, Sprite, SpriteFrame, resources, Button, Collider2D, Material, tween, JsonAsset } from 'cc';
 import { ConfigManager, WeaponConfig } from '../Core/ConfigManager';
 import { SaveDataManager } from '../LevelSystem/SaveDataManager';
 import { LevelSessionManager } from '../Core/LevelSessionManager';
@@ -11,7 +11,7 @@ const { ccclass, property } = _decorator;
 
 @ccclass('BlockManager')
 export class BlockManager extends Component {
-    // 预制体数组,存储5个预制体
+    // 预制体数组,存储10个预制体
     @property([Prefab])
     public blockPrefabs: Prefab[] = [];
     
@@ -43,6 +43,7 @@ export class BlockManager extends Component {
     })
     public placedBlocksContainer: Node = null;
     
+    
     // 游戏是否已开始
     public gameStarted: boolean = false;
     
@@ -93,13 +94,13 @@ export class BlockManager extends Component {
     // 配置是否已预加载的标志
     private isWeaponsConfigPreloaded: boolean = false;
     
+
+    
     // 调试绘制相关
     // 调试绘制功能已迁移到GameBlockSelection
     
     /** 冷却机制已废弃,方块随时可移动 */
 
-
-
     // 清除所有冷却(游戏重置时调用)
     public clearAllCooldowns() { /* no-op */ }
     
@@ -120,6 +121,8 @@ export class BlockManager extends Component {
             this.isWeaponsConfigPreloaded = false;
         }
     }
+
+
     
     /**
      * 获取预加载的武器配置,如果没有预加载则返回null
@@ -1355,7 +1358,7 @@ export class BlockManager extends Component {
 
     
     // 加载武器图标
-    private loadWeaponIcon(block: Node, weaponConfig: WeaponConfig) {
+    private async loadWeaponIcon(block: Node, weaponConfig: WeaponConfig) {
         // 根据预制体结构:WeaponBlock -> B1 -> Weapon
         const b1Node = block.getChildByName('B1');
         if (!b1Node) {
@@ -1393,101 +1396,21 @@ export class BlockManager extends Component {
             }
             
             // Add comprehensive null safety checks before setting spriteFrame
-        if (weaponSprite && weaponSprite.isValid && 
-            weaponNode && weaponNode.isValid && 
-            block && block.isValid && 
-            spriteFrame && spriteFrame.isValid) {
-            weaponSprite.spriteFrame = spriteFrame;
-            
-            // 检查方块是否在kuang区域,如果是则缩放植物图标至0.45倍
-            const blockLocation = this.blockLocations.get(block);
-            if (blockLocation === 'kuang') {
-                weaponNode.setScale(0.45, 0.45, 1);
-                console.log(`[BlockManager] 设置kuang区域植物图标缩放: 0.45倍`);
+            if (weaponSprite && weaponSprite.isValid && 
+                weaponNode && weaponNode.isValid && 
+                block && block.isValid && 
+                spriteFrame && spriteFrame.isValid) {
+                weaponSprite.spriteFrame = spriteFrame;
+                
+                // 武器图标已加载
+                
+                // 应用武器图标的旋转(不再使用位置偏移)
+                const blockShape = this.getBlockShape(block);
+                this.rotateWeaponIconByShape(weaponNode, blockShape, weaponConfig.id);
             }
-            
-            // 应用武器图标的位置偏移和旋转
-            this.rotateWeaponIconByShape(weaponNode, weaponConfig.id);
-        }
         });
     }
     
-    // 武器类型和方块形状组合的位置偏移配置(相对于方块中心的偏移量)
-    private readonly WEAPON_SHAPE_POSITION_OFFSETS: { [weaponId: string]: { [shapeId: string]: { x: number, y: number } } } = {
-        'pea_shooter': {
-            'I': { x: 4, y: -3 },      // 毛豆射手竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: 5 },     // 毛豆射手横条形状,居中
-            'L': { x: 1, y: -10 },     // 毛豆射手L型,轻微向左下偏移
-            'S': { x: 5, y: -1 },      // 毛豆射手S型,轻微向右下偏移
-            'D-T': { x: 4, y: -1 }     // 毛豆射手倒T型,轻微向下偏移
-        },
-        'sharp_carrot': {
-            'I': { x: 0, y: -1 },      // 尖胡萝卜竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: 0 },     // 尖胡萝卜横条形状,居中
-            'L': { x: -1, y: -7 },     // 尖胡萝卜L型,轻微向左下偏移
-            'S': { x: 1, y: -1 },      // 尖胡萝卜S型,轻微向右下偏移
-            'D-T': { x: 0, y: -1 }     // 尖胡萝卜倒T型,轻微向下偏移
-        },
-        'saw_grass': {
-            'I': { x: 0, y: -1 },      // 锯齿草竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: 0 },     // 锯齿草横条形状,居中
-            'L': { x: -1, y: -1 },     // 锯齿草L型,轻微向左下偏移
-            'S': { x: 1, y: -1 },      // 锯齿草S型,轻微向右下偏移
-            'D-T': { x: 0, y: -5 }     // 锯齿草倒T型,轻微向下偏移
-        },
-        'watermelon_bomb': {
-            'I': { x: 0, y: -1 },      // 西瓜炸弹竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: 0 },     // 西瓜炸弹横条形状,居中
-            'L': { x: -1, y: -1 },     // 西瓜炸弹L型,轻微向左下偏移
-            'S': { x: 1, y: -1 },      // 西瓜炸弹S型,轻微向右下偏移
-            'D-T': { x: 0, y: -7 }     // 西瓜炸弹倒T型,轻微向下偏移
-        },
-        'boomerang_plant': {
-            'I': { x: 0, y: -1 },      // 回旋镖植物竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: 0 },     // 回旋镖植物横条形状,居中
-            'L': { x: -1, y: -8 },     // 回旋镖植物L型,轻微向左下偏移
-            'S': { x: 1, y: -1 },      // 回旋镖植物S型,轻微向右下偏移
-            'D-T': { x: -10, y: -13 }     // 回旋镖植物倒T型,轻微向下偏移
-        },
-        'hot_pepper': {
-            'I': { x: 0, y: 5 },      // 辣椒竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: 0 },     // 辣椒横条形状,居中
-            'L': { x: -1, y: -1 },     // 辣椒L型,轻微向左下偏移
-            'S': { x: 1, y: -1 },      // 辣椒S型,轻微向右下偏移
-            'D-T': { x: 0, y: 0 }     // 辣椒倒T型,轻微向下偏移
-        },
-        'cactus_shotgun': {
-            'I': { x: 0, y: -1 },      // 仙人掌霰弹枪竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: 0 },     // 仙人掌霰弹枪横条形状,居中
-            'L': { x: -1, y: -3 },     // 仙人掌霰弹枪L型,轻微向左下偏移
-            'S': { x: 1, y: -1 },      // 仙人掌霰弹枪S型,轻微向右下偏移
-            'D-T': { x: 0, y: -1 }     // 仙人掌霰弹枪倒T型,轻微向下偏移
-        },
-        'okra_missile': {
-            'I': { x: -4, y:3 },      // 秋葵导弹竖条形状,轻微向下偏移
-            'H-I': { x: 0, y: -3 },     // 秋葵导弹横条形状,居中
-            'L': { x: -1, y: -9 },     // 秋葵导弹L型,轻微向左下偏移
-            'S': { x: -6, y: 0 },      // 秋葵导弹S型,轻微向右下偏移
-            'D-T': { x: -3, y: 3 }     // 秋葵导弹倒T型,轻微向下偏移
-        },
-        'mace_club': {
-            'I': { x: 0, y: -1 },      // 狼牙棒竖条形状,轻微向下偏移
-            'H-I': { x: 1, y: 0 },     // 狼牙棒横条形状,居中
-            'L': { x: -1, y: -1 },     // 狼牙棒L型,轻微向左下偏移
-            'S': { x: 1, y: -1 },      // 狼牙棒S型,轻微向右下偏移
-            'D-T': { x: 0, y: -5 }     // 狼牙棒倒T型,轻微向下偏移
-        }
-    };
-    
-    // 默认位置偏移配置(当武器类型未配置时使用)
-    private readonly DEFAULT_SHAPE_POSITION_OFFSETS: { [key: string]: { x: number, y: number } } = {
-        'I': { x: 0, y: -1 },      // 竖条形状,轻微向下偏移
-        'H-I': { x: 0, y: 0 },     // 横I型,居中
-        'L': { x: -1, y: -1 },     // L型,轻微向左下偏移
-        'S': { x: 1, y: -1 },      // S型,轻微向右下偏移
-        'D-T': { x: 0, y: -1 }     // 倒T型,轻微向下偏移
-    };
-    
     // 武器类型和方块形状组合的旋转角度配置
     private readonly WEAPON_SHAPE_ROTATION_ANGLES: { [weaponId: string]: { [shapeId: string]: number } } = {
         'pea_shooter': {
@@ -1564,32 +1487,55 @@ export class BlockManager extends Component {
         'D-T': 0     // 倒T型,保持原始方向
     };
     
-    // 根据武器类型和方块形状调整武器图标位置和旋转
+    // 根据武器类型和方块形状调整武器图标位置(完全保留预制体原始旋转值,不应用额外旋转)
     private rotateWeaponIconByShape(weaponNode: Node, shapeId: string | null, weaponId?: string) {
         if (!weaponNode || !shapeId) return;
         
+        // 保存预制体的原始旋转角度
+        const originalAngle = weaponNode.angle;
+        
+        // let additionalRotationAngle = 0;
+        
+        // 注释掉旋转逻辑,完全保留预制体设置
+        /*
+        // 如果提供了武器ID,尝试获取特定武器的旋转角度
+        if (weaponId) {
+            additionalRotationAngle = this.getWeaponShapeRotationAngle(weaponId, shapeId);
+            console.log(`为武器 ${weaponId} 形状 ${shapeId} 设置特定旋转角度: ${additionalRotationAngle}度,原始角度: ${originalAngle}度`);
+        } else {
+            // 使用默认配置
+            additionalRotationAngle = this.DEFAULT_SHAPE_ROTATION_ANGLES[shapeId] || 0;
+            console.log(`为形状 ${shapeId} 设置默认旋转角度: ${additionalRotationAngle}度,原始角度: ${originalAngle}度`);
+        }
+        
+        // 应用旋转角度:叠加预制体原始角度和形状配置角度
+        weaponNode.angle = originalAngle + additionalRotationAngle;
+        */
+        
+        console.log(`保留预制体原始旋转角度: ${originalAngle}度,不应用额外旋转`);
+    }
+
+    // 注释掉的原始方法(覆盖预制体旋转值的版本)
+    /*
+    private rotateWeaponIconByShape_Original(weaponNode: Node, shapeId: string | null, weaponId?: string) {
+        if (!weaponNode || !shapeId) return;
+        
         let rotationAngle = 0;
-        let positionOffset = { x: 0, y: 0 };
         
-        // 如果提供了武器ID,尝试获取特定武器的配置
-        if (weaponId && this.WEAPON_SHAPE_ROTATION_ANGLES[weaponId]) {
-            rotationAngle = this.WEAPON_SHAPE_ROTATION_ANGLES[weaponId][shapeId] || 0;
-            positionOffset = this.WEAPON_SHAPE_POSITION_OFFSETS[weaponId]?.[shapeId] || { x: 0, y: 0 };
-            console.log(`为武器 ${weaponId} 形状 ${shapeId} 设置特定配置: 旋转${rotationAngle}度, 偏移(${positionOffset.x}, ${positionOffset.y})`);
+        // 如果提供了武器ID,尝试获取特定武器的旋转角度
+        if (weaponId) {
+            rotationAngle = this.getWeaponShapeRotationAngle(weaponId, shapeId);
+            console.log(`为武器 ${weaponId} 形状 ${shapeId} 设置特定旋转角度: ${rotationAngle}度`);
         } else {
             // 使用默认配置
             rotationAngle = this.DEFAULT_SHAPE_ROTATION_ANGLES[shapeId] || 0;
-            positionOffset = this.DEFAULT_SHAPE_POSITION_OFFSETS[shapeId] || { x: 0, y: 0 };
-            console.log(`为形状 ${shapeId} 设置默认配置: 旋转${rotationAngle}度, 偏移(${positionOffset.x}, ${positionOffset.y})`);
+            console.log(`为形状 ${shapeId} 设置默认旋转角度: ${rotationAngle}度`);
         }
         
-        // 应用旋转
-        weaponNode.setRotationFromEuler(0, 0, rotationAngle);
-        
-        // 应用位置偏移
-        const currentPos = weaponNode.position;
-        weaponNode.setPosition(currentPos.x + positionOffset.x, currentPos.y + positionOffset.y, currentPos.z);
+        // 应用旋转角度(直接覆盖,会丢失预制体设置)
+        weaponNode.angle = rotationAngle;
     }
+    */
     
     // 设置特定武器和形状的旋转角度
     public setWeaponShapeRotationAngle(weaponId: string, shapeId: string, angle: number) {
@@ -1606,20 +1552,7 @@ export class BlockManager extends Component {
         console.log(`已更新默认形状 ${shapeId} 的旋转角度为: ${angle}度`);
     }
     
-    // 设置特定武器和形状的位置偏移
-    public setWeaponShapePositionOffset(weaponId: string, shapeId: string, offset: { x: number, y: number }) {
-        if (!this.WEAPON_SHAPE_POSITION_OFFSETS[weaponId]) {
-            this.WEAPON_SHAPE_POSITION_OFFSETS[weaponId] = {};
-        }
-        this.WEAPON_SHAPE_POSITION_OFFSETS[weaponId][shapeId] = offset;
-        console.log(`已更新武器 ${weaponId} 形状 ${shapeId} 的位置偏移为: (${offset.x}, ${offset.y})`);
-    }
-    
-    // 设置默认形状的位置偏移
-    public setDefaultShapePositionOffset(shapeId: string, offset: { x: number, y: number }) {
-        this.DEFAULT_SHAPE_POSITION_OFFSETS[shapeId] = offset;
-        console.log(`已更新默认形状 ${shapeId} 的位置偏移为: (${offset.x}, ${offset.y})`);
-    }
+
     
     // 获取特定武器和形状的旋转角度
     public getWeaponShapeRotationAngle(weaponId: string, shapeId: string): number {
@@ -1634,31 +1567,18 @@ export class BlockManager extends Component {
         return this.DEFAULT_SHAPE_ROTATION_ANGLES[shapeId] || 0;
     }
     
-    // 获取特定武器和形状的位置偏移
-    public getWeaponShapePositionOffset(weaponId: string, shapeId: string): { x: number, y: number } {
-        if (this.WEAPON_SHAPE_POSITION_OFFSETS[weaponId]) {
-            return this.WEAPON_SHAPE_POSITION_OFFSETS[weaponId][shapeId] || { x: 0, y: 0 };
-        }
-        return { x: 0, y: 0 };
-    }
-    
-    // 获取默认形状的位置偏移
-    public getDefaultShapePositionOffset(shapeId: string): { x: number, y: number } {
-        return this.DEFAULT_SHAPE_POSITION_OFFSETS[shapeId] || { x: 0, y: 0 };
-    }
+
     
-    // 同时设置特定武器和形状的位置偏移和旋转角度
-    public setWeaponShapeTransform(weaponId: string, shapeId: string, offset: { x: number, y: number }, angle: number) {
-        this.setWeaponShapePositionOffset(weaponId, shapeId, offset);
+    // 设置特定武器和形状的旋转角度
+    public setWeaponShapeTransform(weaponId: string, shapeId: string, angle: number) {
         this.setWeaponShapeRotationAngle(weaponId, shapeId, angle);
-        console.log(`已更新武器 ${weaponId} 形状 ${shapeId} 的完整变换: 偏移(${offset.x}, ${offset.y}), 旋转${angle}度`);
+        console.log(`已更新武器 ${weaponId} 形状 ${shapeId} 的旋转角度: ${angle}度`);
     }
     
-    // 同时设置默认形状的位置偏移和旋转角度
-    public setDefaultShapeTransform(shapeId: string, offset: { x: number, y: number }, angle: number) {
-        this.setDefaultShapePositionOffset(shapeId, offset);
+    // 设置默认形状的旋转角度
+    public setDefaultShapeTransform(shapeId: string, angle: number) {
         this.setDefaultShapeRotationAngle(shapeId, angle);
-        console.log(`已更新默认形状 ${shapeId} 的完整变换: 偏移(${offset.x}, ${offset.y}), 旋转${angle}度`);
+        console.log(`已更新默认形状 ${shapeId} 的旋转角度: ${angle}度`);
     }
     
     // 重新应用所有已放置方块的武器图标位置和旋转

+ 621 - 0
assets/scripts/TestScene/WeaponBlockTestScript.ts

@@ -0,0 +1,621 @@
+import { _decorator, Component, Node, Prefab, instantiate, Vec3, find, JsonAsset, Sprite, Color, SpriteFrame, resources, UITransform } from 'cc';
+import { ConfigManager, WeaponConfig } from '../Core/ConfigManager';
+
+const { ccclass, property } = _decorator;
+
+/**
+ * 武器方块测试脚本
+ * 用于自动生成所有武器和方块形状的组合,使用自适应缩放和居中逻辑
+ */
+@ccclass('WeaponBlockTestScript')
+export class WeaponBlockTestScript extends Component {
+    
+    @property({
+        type: Node,
+        tooltip: '测试容器节点,用于放置生成的测试方块'
+    })
+    public testContainer: Node = null;
+    
+
+    
+    @property([Prefab])
+    public blockPrefabs: Prefab[] = [];
+    
+    @property({
+        type: JsonAsset,
+        tooltip: '武器和方块配置JSON文件'
+    })
+    public weaponsConfigAsset: JsonAsset = null;
+    
+    // 所有武器类型
+    private readonly WEAPON_TYPES = [
+        'pea_shooter',
+        'sharp_carrot', 
+        'saw_grass',
+        'watermelon_bomb',
+        'boomerang_plant',
+        'hot_pepper',
+        'cactus_shotgun',
+        'okra_missile',
+        'mace_club'
+    ];
+    
+    // 所有方块形状
+    private readonly BLOCK_SHAPES = [
+        'I', 'H-I', 'L', 'L2', 'L3', 'L4', 'S', 'S-F', 'D-T', 'T'
+    ];
+    
+    // 稀有度列表
+    private readonly RARITIES = ['common', 'uncommon', 'rare', 'epic', 'legendary'];
+    
+    private configManager: ConfigManager = null;
+    private weaponsConfig: any = null;
+    private blockSizesConfig: any = null;
+    
+    start() {
+        this.initializeComponents();
+        this.loadConfigurations();
+        // 配置加载完成后自动生成武器方块组合
+        this.scheduleOnce(() => {
+            this.generateAllWeaponBlockCombinations();
+        }, 0.1);
+    }
+    
+    private initializeComponents() {
+        // 查找组件引用
+        if (!this.testContainer) {
+            this.testContainer = find('TestContainer');
+        }
+        
+        // 移除 blockManager 初始化
+        
+
+        
+        this.configManager = ConfigManager.getInstance();
+        
+        this.updateStatus('组件初始化完成');
+    }
+    
+    private loadConfigurations() {
+        try {
+            this.updateStatus('加载配置文件中...');
+            
+            // 从装饰器挂载的资源加载武器和方块配置
+            if (this.weaponsConfigAsset) {
+                const configData = this.weaponsConfigAsset.json;
+                console.log('[WeaponBlockTestScript] 原始配置数据:', configData);
+                console.log('[WeaponBlockTestScript] configData类型:', typeof configData);
+                console.log('[WeaponBlockTestScript] configData.weapons存在:', !!configData.weapons);
+                console.log('[WeaponBlockTestScript] configData.weapons类型:', typeof configData.weapons);
+                console.log('[WeaponBlockTestScript] configData.weapons长度:', configData.weapons?.length);
+                
+                // 直接使用configData,因为weapons.json的结构是 {weapons: [...], blockSizes: [...]}
+                this.weaponsConfig = configData;
+                this.blockSizesConfig = configData;
+                
+                console.log('[WeaponBlockTestScript] 设置后的武器配置:', this.weaponsConfig);
+                console.log('[WeaponBlockTestScript] 设置后的方块配置:', this.blockSizesConfig);
+                console.log('[WeaponBlockTestScript] 预制体数量:', this.blockPrefabs?.length || 0);
+                
+                // 验证第一个武器配置
+                if (configData.weapons && configData.weapons.length > 0) {
+                    console.log('[WeaponBlockTestScript] 第一个武器配置:', configData.weapons[0]);
+                    console.log('[WeaponBlockTestScript] 第一个武器ID:', configData.weapons[0].id);
+                }
+            } else {
+                console.warn('[WeaponBlockTestScript] 武器和方块配置资源未挂载');
+            }
+            
+            this.updateStatus('配置文件加载完成');
+        } catch (error) {
+            console.error('[WeaponBlockTestScript] 加载配置失败:', error);
+            this.updateStatus('配置文件加载失败: ' + error.message);
+        }
+    }
+    
+    /**
+     * 生成所有武器方块组合
+     */
+    public async generateAllWeaponBlockCombinations() {
+        console.log('[WeaponBlockTestScript] 开始生成武器方块组合');
+        console.log('[WeaponBlockTestScript] 武器配置状态:', !!this.weaponsConfig);
+        console.log('[WeaponBlockTestScript] 方块配置状态:', !!this.blockSizesConfig);
+        console.log('[WeaponBlockTestScript] 容器节点状态:', !!this.testContainer);
+        
+        if (!this.weaponsConfig || !this.blockSizesConfig) {
+            console.error('[WeaponBlockTestScript] 配置未加载,无法生成测试方块');
+            this.updateStatus('配置未加载,无法生成测试方块');
+            return;
+        }
+        
+        if (!this.testContainer) {
+            console.error('[WeaponBlockTestScript] 测试容器节点未找到');
+            this.updateStatus('测试容器节点未找到');
+            return;
+        }
+        
+        if (!this.blockPrefabs || this.blockPrefabs.length === 0) {
+            console.error('[WeaponBlockTestScript] 没有可用的方块预制体');
+            this.updateStatus('没有可用的方块预制体');
+            return;
+        }
+        
+        this.clearTestContainer();
+        this.updateStatus('开始生成所有武器方块组合...');
+        
+        let totalGenerated = 0;
+        const startX = -500;
+        const startY = 300;
+        const spacingX = 120;
+        const spacingY = 150;
+        const itemsPerRow = 10;
+        
+        for (let weaponIndex = 0; weaponIndex < this.WEAPON_TYPES.length; weaponIndex++) {
+            const weaponType = this.WEAPON_TYPES[weaponIndex];
+            
+            for (let shapeIndex = 0; shapeIndex < this.BLOCK_SHAPES.length; shapeIndex++) {
+                const shapeId = this.BLOCK_SHAPES[shapeIndex];
+                
+                // 计算位置
+                const row = Math.floor(totalGenerated / itemsPerRow);
+                const col = totalGenerated % itemsPerRow;
+                const posX = startX + col * spacingX;
+                const posY = startY - row * spacingY;
+                
+                // 生成测试方块
+                await this.generateTestBlock(weaponType, shapeId, new Vec3(posX, posY, 0));
+                
+                totalGenerated++;
+                
+                // 更新状态
+                this.updateStatus(`生成进度: ${totalGenerated}/${this.WEAPON_TYPES.length * this.BLOCK_SHAPES.length}`);
+                
+                // 每生成10个方块暂停一帧,避免卡顿
+                if (totalGenerated % 10 === 0) {
+                    await this.waitOneFrame();
+                }
+            }
+        }
+        
+        this.updateStatus(`生成完成!共生成 ${totalGenerated} 个测试方块`);
+    }
+    
+    /**
+     * 生成特定武器和形状的测试方块
+     */
+    private async generateTestBlock(weaponType: string, shapeId: string, position: Vec3) {
+        try {
+            // 获取武器配置
+            const weaponConfig = this.getWeaponConfig(weaponType);
+            if (!weaponConfig) {
+                console.warn(`[WeaponBlockTestScript] 未找到武器配置: ${weaponType}`);
+                return;
+            }
+            
+            // 获取形状配置
+            const shapeConfig = this.getShapeConfig(shapeId);
+            if (!shapeConfig) {
+                console.warn(`[WeaponBlockTestScript] 未找到形状配置: ${shapeId}`);
+                return;
+            }
+            
+            // 查找匹配的预制体
+            const prefab = this.findMatchingPrefab(shapeConfig);
+            if (!prefab) {
+                console.warn(`[WeaponBlockTestScript] 未找到匹配的预制体: ${shapeId}`);
+                return;
+            }
+            
+            // 实例化方块
+            const block = instantiate(prefab);
+            block.setParent(this.testContainer);
+            block.setPosition(position);
+            
+            // 设置武器配置
+            this.setupBlockWeapon(block, weaponConfig);
+            
+            // 设置形状信息
+            this.setupBlockShape(block, shapeConfig);
+            
+            // 设置稀有度(固定使用common)
+            const rarity = 'common';
+            this.setupBlockRarity(block, rarity);
+        } catch (error) {
+            console.error(`[WeaponBlockTestScript] 生成测试方块失败 ${weaponType}-${shapeId}:`, error);
+        }
+    }
+    
+    private getWeaponConfig(weaponType: string): WeaponConfig | null {
+        console.log(`[WeaponBlockTestScript] 查找武器配置: ${weaponType}`);
+        console.log('[WeaponBlockTestScript] 当前武器配置结构:', this.weaponsConfig);
+        
+        if (!this.weaponsConfig) {
+            console.warn('[WeaponBlockTestScript] 武器配置为空');
+            return null;
+        }
+        
+        // weapons.json的结构是 {weapons: [...], blockSizes: [...]}
+        // 所以我们需要访问 this.weaponsConfig.weapons
+        let weaponsList = null;
+        if (this.weaponsConfig.weapons && Array.isArray(this.weaponsConfig.weapons)) {
+            weaponsList = this.weaponsConfig.weapons;
+            console.log(`[WeaponBlockTestScript] 使用weapons数组,长度: ${weaponsList.length}`);
+        } else if (Array.isArray(this.weaponsConfig)) {
+            weaponsList = this.weaponsConfig;
+            console.log(`[WeaponBlockTestScript] 直接使用配置数组,长度: ${weaponsList.length}`);
+        } else {
+            console.warn('[WeaponBlockTestScript] 无法识别的武器配置结构');
+            console.log('[WeaponBlockTestScript] weaponsConfig类型:', typeof this.weaponsConfig);
+            console.log('[WeaponBlockTestScript] weaponsConfig.weapons存在:', !!this.weaponsConfig.weapons);
+            return null;
+        }
+        
+        console.log(`[WeaponBlockTestScript] 在${weaponsList.length}个武器中查找: ${weaponType}`);
+        
+        // 打印前几个武器的ID用于调试
+        if (weaponsList.length > 0) {
+            console.log('[WeaponBlockTestScript] 前3个武器ID:', weaponsList.slice(0, 3).map((w: any) => w.id));
+        }
+        
+        const result = weaponsList.find((weapon: any) => weapon.id === weaponType) || null;
+        console.log(`[WeaponBlockTestScript] 武器配置查找结果 ${weaponType}:`, result ? '找到' : '未找到');
+        if (result) {
+            console.log(`[WeaponBlockTestScript] 找到的武器名称: ${result.name}`);
+        }
+        return result;
+    }
+    
+    private getShapeConfig(shapeId: string): any {
+        console.log(`[WeaponBlockTestScript] 查找形状配置: ${shapeId}`);
+        console.log('[WeaponBlockTestScript] 当前方块配置结构:', this.blockSizesConfig);
+        
+        if (!this.blockSizesConfig) {
+            console.warn('[WeaponBlockTestScript] 方块配置为空');
+            return null;
+        }
+        
+        // 尝试不同的配置结构
+        let shapesList = null;
+        if (this.blockSizesConfig.blockSizes) {
+            shapesList = this.blockSizesConfig.blockSizes;
+        } else if (Array.isArray(this.blockSizesConfig)) {
+            shapesList = this.blockSizesConfig;
+        } else {
+            console.warn('[WeaponBlockTestScript] 无法识别的方块配置结构');
+            return null;
+        }
+        
+        const result = shapesList.find((shape: any) => shape.id === shapeId) || null;
+        console.log(`[WeaponBlockTestScript] 形状配置查找结果 ${shapeId}:`, result);
+        return result;
+    }
+    
+    private findMatchingPrefab(shapeConfig: any): Prefab | null {
+        if (!this.blockPrefabs || this.blockPrefabs.length === 0) {
+            console.warn('[WeaponBlockTestScript] 没有可用的方块预制体');
+            return null;
+        }
+        
+        console.log(`[WeaponBlockTestScript] 查找预制体,形状: ${shapeConfig.id}, 网格数: ${shapeConfig.gridCount}`);
+        console.log(`[WeaponBlockTestScript] 可用预制体数量: ${this.blockPrefabs.length}`);
+        
+        // 根据网格数量匹配预制体
+        const targetGridCount = shapeConfig.gridCount || 4;
+        
+        // 如果只有一个预制体,直接使用它
+        if (this.blockPrefabs.length === 1) {
+            console.log('[WeaponBlockTestScript] 只有一个预制体,直接使用');
+            return this.blockPrefabs[0];
+        }
+        
+        // 尝试根据网格数量匹配
+        for (let i = 0; i < this.blockPrefabs.length; i++) {
+            const prefab = this.blockPrefabs[i];
+            if (prefab) {
+                console.log(`[WeaponBlockTestScript] 使用预制体索引: ${i}`);
+                // 这里可以添加更精确的形状匹配逻辑
+                // 暂时根据索引循环使用不同的预制体
+                const shapeIndex = this.BLOCK_SHAPES.indexOf(shapeConfig.id);
+                if (shapeIndex >= 0 && shapeIndex < this.blockPrefabs.length) {
+                    return this.blockPrefabs[shapeIndex];
+                }
+                return prefab;
+            }
+        }
+        
+        return this.blockPrefabs[0] || null;
+    }
+    
+    private setupBlockWeapon(block: Node, weaponConfig: WeaponConfig) {
+        // 存储武器配置到方块节点
+        block['weaponConfig'] = weaponConfig;
+        block['weaponId'] = weaponConfig.id;
+        
+        // 直接调用武器外观设置方法
+        this.setupBlockWeaponVisual(block, weaponConfig);
+    }
+    
+    private setupBlockShape(block: Node, shapeConfig: any) {
+        // 存储形状配置到方块节点
+        block['shapeConfig'] = shapeConfig;
+        block['shapeId'] = shapeConfig.id;
+        block['shapeName'] = shapeConfig.name;
+    }
+    
+    private setupBlockRarity(block: Node, rarity: string) {
+        // 存储稀有度到方块节点
+        block['rarity'] = rarity;
+        
+        // 直接调用稀有度颜色应用方法
+        this.applyBlockRarityColor(block, rarity);
+    }
+    
+    // 设置方块的武器外观
+    private setupBlockWeaponVisual(block: Node, weaponConfig: WeaponConfig) {
+        // 确保方块节点上也有 weaponConfig 属性
+        block['weaponConfig'] = weaponConfig;
+        
+        // 设置方块的稀有度颜色
+        this.applyBlockRarityColor(block, weaponConfig.rarity || 'common');
+        
+        // 加载武器图标
+        this.loadWeaponIcon(block, weaponConfig);
+    }
+    
+    // 应用方块稀有度颜色
+    private applyBlockRarityColor(block: Node, rarity: string) {
+        // Add null safety check for block
+        if (!block || !block.isValid) {
+            return;
+        }
+        
+        const sprite = block.getComponent(Sprite);
+        if (!sprite || !sprite.isValid) {
+            return;
+        }
+        
+        // 根据稀有度设置颜色
+        let color: Color;
+        switch (rarity) {
+            case 'common':
+                color = new Color(255, 255, 255); // 白色
+                break;
+            case 'uncommon':
+                color = new Color(0, 255, 0); // 绿色
+                break;
+            case 'rare':
+                color = new Color(0, 100, 255); // 蓝色
+                break;
+            case 'epic':
+                color = new Color(160, 32, 240); // 紫色
+                break;
+            case 'legendary':
+                color = new Color(255, 165, 0); // 橙色
+                break;
+            default:
+                color = new Color(255, 255, 255); // 默认白色
+        }
+        
+        sprite.color = color;
+        console.log(`[WeaponBlockTestScript] 设置方块稀有度颜色: ${rarity}`, color);
+    }
+    
+    // 加载武器图标
+    /**
+     * 应用自适应缩放和居中逻辑
+     * 基于武器精灵的原始尺寸和方块的ContentSize自动计算缩放比例
+     * 并将武器图标居中显示
+     */
+    private applyAdaptiveScalingAndCentering(weaponNode: Node, block: Node): void {
+        if (!weaponNode || !block) {
+            console.warn('[WeaponBlockTestScript] applyAdaptiveScalingAndCentering: 无效的节点参数');
+            return;
+        }
+
+        const weaponTransform = weaponNode.getComponent(UITransform);
+        const blockTransform = block.getComponent(UITransform);
+        
+        if (!weaponTransform || !blockTransform) {
+            console.warn('[WeaponBlockTestScript] applyAdaptiveScalingAndCentering: 缺少UITransform组件');
+            return;
+        }
+
+        // 获取武器精灵的原始尺寸
+        const weaponSprite = weaponNode.getComponent(Sprite);
+        if (!weaponSprite || !weaponSprite.spriteFrame) {
+            console.warn('[WeaponBlockTestScript] applyAdaptiveScalingAndCentering: 武器精灵或SpriteFrame无效');
+            return;
+        }
+
+        const originalSize = weaponSprite.spriteFrame.originalSize;
+        const blockContentSize = blockTransform.contentSize;
+        
+        // 计算缩放比例,保持10%的边距
+        const marginFactor = 0.9; // 90%的空间用于武器图标,10%作为边距
+        const scaleX = (blockContentSize.width * marginFactor) / originalSize.width;
+        const scaleY = (blockContentSize.height * marginFactor) / originalSize.height;
+        const finalScale = Math.min(scaleX, scaleY); // 使用较小的缩放比例以保持宽高比
+        
+        // 应用缩放
+        weaponNode.setScale(finalScale, finalScale, 1);
+        
+        // 居中武器图标
+        weaponNode.setPosition(0, 0, 0);
+        
+        console.log(`[WeaponBlockTestScript] 自适应缩放应用: 原始尺寸(${originalSize.width}x${originalSize.height}), 方块尺寸(${blockContentSize.width}x${blockContentSize.height}), 最终缩放: ${finalScale.toFixed(3)}`);
+    }
+
+    private loadWeaponIcon(block: Node, weaponConfig: WeaponConfig) {
+        // 根据预制体结构:WeaponBlock -> B1 -> Weapon
+        const b1Node = block.getChildByName('B1');
+        if (!b1Node) {
+            console.warn('[WeaponBlockTestScript] 找不到B1节点');
+            return;
+        }
+        
+        const weaponNode = b1Node.getChildByName('Weapon');
+        if (!weaponNode) {
+            console.warn('[WeaponBlockTestScript] 找不到Weapon节点');
+            return;
+        }
+        
+        const weaponSprite = weaponNode.getComponent(Sprite);
+        if (!weaponSprite) {
+            console.warn('[WeaponBlockTestScript] Weapon节点上没有Sprite组件');
+            return;
+        }
+        
+        // 获取武器配置中的图片路径
+        const spritePath = weaponConfig.visualConfig?.weaponSprites;
+        if (!spritePath) {
+            console.warn(`[WeaponBlockTestScript] 武器 ${weaponConfig.name} 没有配置图片信息`);
+            return;
+        }
+        
+        // 正确的SpriteFrame子资源路径
+        const spriteFramePath = `${spritePath}/spriteFrame`;
+        
+        // 加载SpriteFrame子资源
+        resources.load(spriteFramePath, SpriteFrame, (err, spriteFrame) => {
+            if (err) {
+                console.warn(`[WeaponBlockTestScript] 加载武器图片失败: ${spriteFramePath}`, err);
+                return;
+            }
+            
+            // Add comprehensive null safety checks before setting spriteFrame
+            if (weaponSprite && weaponSprite.isValid && 
+                weaponNode && weaponNode.isValid && 
+                block && block.isValid && 
+                spriteFrame && spriteFrame.isValid) {
+                weaponSprite.spriteFrame = spriteFrame;
+                
+                // 应用自适应缩放和居中逻辑
+                this.applyAdaptiveScalingAndCentering(weaponNode, block);
+                
+                console.log(`[WeaponBlockTestScript] 成功加载武器图标: ${weaponConfig.name}`);
+            }
+        });
+    }
+    
+    /**
+     * 生成特定武器类型的所有形状组合
+     */
+    public async generateWeaponShapeCombinations(weaponType: string) {
+        if (this.WEAPON_TYPES.indexOf(weaponType) === -1) {
+            this.updateStatus(`无效的武器类型: ${weaponType}`);
+            return;
+        }
+        
+        this.clearTestContainer();
+        this.updateStatus(`生成武器 ${weaponType} 的所有形状组合...`);
+        
+        const startX = -400;
+        const startY = 200;
+        const spacingX = 100;
+        const spacingY = 120;
+        const itemsPerRow = 5;
+        
+        for (let i = 0; i < this.BLOCK_SHAPES.length; i++) {
+            const shapeId = this.BLOCK_SHAPES[i];
+            
+            const row = Math.floor(i / itemsPerRow);
+            const col = i % itemsPerRow;
+            const posX = startX + col * spacingX;
+            const posY = startY - row * spacingY;
+            
+            await this.generateTestBlock(weaponType, shapeId, new Vec3(posX, posY, 0));
+            
+            this.updateStatus(`生成进度: ${i + 1}/${this.BLOCK_SHAPES.length}`);
+            
+            if ((i + 1) % 5 === 0) {
+                await this.waitOneFrame();
+            }
+        }
+        
+        this.updateStatus(`${weaponType} 的所有形状组合生成完成!`);
+    }
+    
+    /**
+     * 生成特定形状的所有武器组合
+     */
+    public async generateShapeWeaponCombinations(shapeId: string) {
+        if (this.BLOCK_SHAPES.indexOf(shapeId) === -1) {
+            this.updateStatus(`无效的形状ID: ${shapeId}`);
+            return;
+        }
+        
+        this.clearTestContainer();
+        this.updateStatus(`生成形状 ${shapeId} 的所有武器组合...`);
+        
+        const startX = -400;
+        const startY = 200;
+        const spacingX = 100;
+        const spacingY = 120;
+        const itemsPerRow = 3;
+        
+        for (let i = 0; i < this.WEAPON_TYPES.length; i++) {
+            const weaponType = this.WEAPON_TYPES[i];
+            
+            const row = Math.floor(i / itemsPerRow);
+            const col = i % itemsPerRow;
+            const posX = startX + col * spacingX;
+            const posY = startY - row * spacingY;
+            
+            await this.generateTestBlock(weaponType, shapeId, new Vec3(posX, posY, 0));
+            
+            this.updateStatus(`生成进度: ${i + 1}/${this.WEAPON_TYPES.length}`);
+            
+            if ((i + 1) % 3 === 0) {
+                await this.waitOneFrame();
+            }
+        }
+        
+        this.updateStatus(`形状 ${shapeId} 的所有武器组合生成完成!`);
+    }
+    
+    /**
+     * 清空测试容器
+     */
+    public clearTestContainer() {
+        if (this.testContainer) {
+            this.testContainer.removeAllChildren();
+        }
+    }
+    
+    /**
+     * 更新状态显示
+     */
+    private updateStatus(message: string) {
+        console.log(`[WeaponBlockTestScript] ${message}`);
+    }
+    
+    /**
+     * 等待一帧
+     */
+    private waitOneFrame(): Promise<void> {
+        return new Promise(resolve => {
+            this.scheduleOnce(() => {
+                resolve();
+            }, 0);
+        });
+    }
+    
+    /**
+     * 导出当前测试结果为JSON(用于调试)
+     */
+    public exportTestResults(): string {
+        const results = {
+            timestamp: new Date().toISOString(),
+            weaponTypes: this.WEAPON_TYPES,
+            blockShapes: this.BLOCK_SHAPES,
+            rarities: this.RARITIES,
+            totalCombinations: this.WEAPON_TYPES.length * this.BLOCK_SHAPES.length,
+            generatedBlocks: this.testContainer ? this.testContainer.children.length : 0
+        };
+        
+        const jsonString = JSON.stringify(results, null, 2);
+        console.log('[WeaponBlockTestScript] 测试结果:', jsonString);
+        
+        return jsonString;
+    }
+}

+ 1 - 1
assets/scripts/TestScene/TestPelletTrail.ts.meta → assets/scripts/TestScene/WeaponBlockTestScript.ts.meta

@@ -2,7 +2,7 @@
   "ver": "4.0.24",
   "importer": "typescript",
   "imported": true,
-  "uuid": "02abff67-f7bd-4edb-940c-ffbfd1b0ce5a",
+  "uuid": "de769292-4d42-4e00-8384-18f78777b711",
   "files": [],
   "subMetas": {},
   "userData": {}