181404010226 před 2 měsíci
rodič
revize
5ffd3dcb6b

binární
assets/Animation/EnemyAni/003/ball.png


+ 32 - 32
assets/Animation/EnemyAni/003/ball.png.meta

@@ -43,12 +43,12 @@
         "rotated": false,
         "offsetX": 0,
         "offsetY": 0,
-        "trimX": 1,
-        "trimY": 1,
-        "width": 130,
-        "height": 129,
-        "rawWidth": 132,
-        "rawHeight": 131,
+        "trimX": 0,
+        "trimY": 0,
+        "width": 65,
+        "height": 65,
+        "rawWidth": 65,
+        "rawHeight": 65,
         "borderTop": 0,
         "borderBottom": 0,
         "borderLeft": 0,
@@ -60,17 +60,17 @@
         "meshType": 0,
         "vertices": {
           "rawPosition": [
-            -65,
-            -64.5,
+            -32.5,
+            -32.5,
             0,
-            65,
-            -64.5,
+            32.5,
+            -32.5,
             0,
-            -65,
-            64.5,
+            -32.5,
+            32.5,
             0,
-            65,
-            64.5,
+            32.5,
+            32.5,
             0
           ],
           "indexes": [
@@ -82,33 +82,33 @@
             3
           ],
           "uv": [
+            0,
+            65,
+            65,
+            65,
+            0,
+            0,
+            65,
+            0
+          ],
+          "nuv": [
+            0,
+            0,
             1,
-            130,
-            131,
-            130,
+            0,
+            0,
             1,
             1,
-            131,
             1
           ],
-          "nuv": [
-            0.007575757575757576,
-            0.007633587786259542,
-            0.9924242424242424,
-            0.007633587786259542,
-            0.007575757575757576,
-            0.9923664122137404,
-            0.9924242424242424,
-            0.9923664122137404
-          ],
           "minPos": [
-            -65,
-            -64.5,
+            -32.5,
+            -32.5,
             0
           ],
           "maxPos": [
-            65,
-            64.5,
+            32.5,
+            32.5,
             0
           ]
         },

+ 2 - 2
assets/NewbieGuidePlugin-v1.0.0/NewbieGuidePlugin-v1.0.0/scripts/GuideDataManager.ts

@@ -137,14 +137,14 @@ export class GuideDataManager {
     public isGuideCompleted(): boolean {
         // 可以根据具体需求定义完成条件
         // 这里简单地认为索引大于等于某个值就是完成
-        return this._guideIndex >= 10; // 假设有10个引导步骤
+        return this._guideIndex >= 9; // 假设有9个引导步骤
     }
     
     /**
      * 获取引导完成百分比
      */
     public getGuideProgress(): number {
-        const totalSteps = 10; // 总步骤数,可以根据实际情况调整
+        const totalSteps = 9; // 总步骤数,已调整为 9
         return Math.min(this._guideIndex / totalSteps, 1.0);
     }
     

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 297 - 582
assets/NewbieGuidePlugin-v1.0.0/NewbieGuidePlugin-v1.0.0/scripts/GuideUIController.ts


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 297 - 362
assets/Scenes/GameLevel.scene


+ 1437 - 0
assets/Scenes/WeaponNode_pea_shooter.prefab

@@ -0,0 +1,1437 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "WeaponNode_pea_shooter",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "persistent": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "WeaponNode_pea_shooter",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": null,
+    "_children": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 40
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 58
+      }
+    ],
+    "_prefab": {
+      "__id__": 60
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": -265.5,
+      "y": 484.5,
+      "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": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Sprite",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [
+      {
+        "__id__": 3
+      },
+      {
+        "__id__": 11
+      },
+      {
+        "__id__": 19
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 33
+      },
+      {
+        "__id__": 35
+      },
+      {
+        "__id__": 37
+      }
+    ],
+    "_prefab": {
+      "__id__": 39
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 11,
+      "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": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Name",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 4
+      },
+      {
+        "__id__": 6
+      },
+      {
+        "__id__": 8
+      }
+    ],
+    "_prefab": {
+      "__id__": 10
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": -89.6,
+      "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": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 3
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 5
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 6,
+      "height": 38.76
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "2aLuaO6+9DkrTNAc7/Wx9J"
+  },
+  {
+    "__type__": "cc.Label",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 3
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 7
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_string": "毛豆射手",
+    "_horizontalAlign": 1,
+    "_verticalAlign": 1,
+    "_actualFontSize": 26,
+    "_fontSize": 26,
+    "_fontFamily": "Adobe 黑体 Std",
+    "_lineHeight": 0,
+    "_overflow": 0,
+    "_enableWrapText": true,
+    "_font": null,
+    "_isSystemFontUsed": true,
+    "_spacingX": 0,
+    "_isItalic": false,
+    "_isBold": false,
+    "_isUnderline": false,
+    "_underlineHeight": 2,
+    "_cacheMode": 0,
+    "_enableOutline": true,
+    "_outlineColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_outlineWidth": 3,
+    "_enableShadow": false,
+    "_shadowColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_shadowOffset": {
+      "__type__": "cc.Vec2",
+      "x": 2,
+      "y": 2
+    },
+    "_shadowBlur": 2,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "fbbvDA8FVNSZ5KdHkHEiLB"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 3
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 9
+    },
+    "_alignFlags": 20,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 17.520000000000003,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "1fOXnptgxIsqFx4NuxWzfA"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "d6NT2VZZRAUr5MFflAm5/E",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "WeaponSprite",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 12
+      },
+      {
+        "__id__": 14
+      },
+      {
+        "__id__": 16
+      }
+    ],
+    "_prefab": {
+      "__id__": 18
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 19.369,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 0.8,
+      "y": 0.8,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 11
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 13
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 117,
+      "height": 165
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "3cDK92csRM5Y6nLR9yvp17"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 11
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 15
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "f24e38d6-88df-4dab-bdd0-f8d47663d951@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 1,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "a9R7XTZyFJc4+P0ejZ8wQS"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 11
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 17
+    },
+    "_alignFlags": 20,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 79.869,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "5a0n+X2JJKBqVAfkhiQgTD"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "de+wIi4/hFW45OMSOFOU7o",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Level",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [
+      {
+        "__id__": 20
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 26
+      },
+      {
+        "__id__": 28
+      },
+      {
+        "__id__": 30
+      }
+    ],
+    "_prefab": {
+      "__id__": 32
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 125.9,
+      "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": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Label",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 19
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 21
+      },
+      {
+        "__id__": 23
+      }
+    ],
+    "_prefab": {
+      "__id__": 25
+    },
+    "_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": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 20
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 22
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 18.4599609375,
+      "height": 36.76
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "d49a64PUtL2a+JT/4CQ4Jj"
+  },
+  {
+    "__type__": "cc.Label",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 20
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 24
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_string": "1",
+    "_horizontalAlign": 1,
+    "_verticalAlign": 1,
+    "_actualFontSize": 26,
+    "_fontSize": 26,
+    "_fontFamily": "Arial",
+    "_lineHeight": 0,
+    "_overflow": 0,
+    "_enableWrapText": true,
+    "_font": null,
+    "_isSystemFontUsed": true,
+    "_spacingX": 0,
+    "_isItalic": false,
+    "_isBold": false,
+    "_isUnderline": false,
+    "_underlineHeight": 2,
+    "_cacheMode": 0,
+    "_enableOutline": true,
+    "_outlineColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_outlineWidth": 2,
+    "_enableShadow": false,
+    "_shadowColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_shadowOffset": {
+      "__type__": "cc.Vec2",
+      "x": 2,
+      "y": 2
+    },
+    "_shadowBlur": 2,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "c9ehvy2YdFjocasiAB+hIr"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "c8CYmss0hE1IqnEynwb6OC",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 19
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 27
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 64,
+      "height": 64
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "234CdIxHdAzK5nl+jhab7Y"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 19
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 29
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "6aa1358f-5aca-4615-9727-118044a23009@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 1,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "0bJEV4oi9I04qRs5gmjVHD"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 19
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 31
+    },
+    "_alignFlags": 17,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": -31.4,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "beAMOTeuxIoZmZVMctFpHk"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "bf0x1E5gVAQbITjkuJhsh6",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 34
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 189,
+      "height": 253
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "daTc3h1exHWYoML/QWLmBu"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 36
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "8fc5f63e-69d4-4a72-9a12-49db5603a717@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 1,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "fcjJLMhJJKe5yTtF5SADWT"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 38
+    },
+    "_alignFlags": 12,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 67,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "3ekST7Y3VIm7QtktsoTeLF"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "1e/67JDwxJeJ46enfIX1+r",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Upgrade",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [
+      {
+        "__id__": 41
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 49
+      },
+      {
+        "__id__": 51
+      },
+      {
+        "__id__": 53
+      },
+      {
+        "__id__": 55
+      }
+    ],
+    "_prefab": {
+      "__id__": 57
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": -154,
+      "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": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Label",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 40
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 42
+      },
+      {
+        "__id__": 44
+      },
+      {
+        "__id__": 46
+      }
+    ],
+    "_prefab": {
+      "__id__": 48
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 1.1400000000000041,
+      "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": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 41
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 43
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 86.7734375,
+      "height": 36.76
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "5corVPcU9F5qSsVz4BDU+w"
+  },
+  {
+    "__type__": "cc.Label",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 41
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 45
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_string": "升  级",
+    "_horizontalAlign": 1,
+    "_verticalAlign": 1,
+    "_actualFontSize": 26,
+    "_fontSize": 26,
+    "_fontFamily": "Adobe 黑体 Std",
+    "_lineHeight": 0,
+    "_overflow": 0,
+    "_enableWrapText": true,
+    "_font": null,
+    "_isSystemFontUsed": true,
+    "_spacingX": 0,
+    "_isItalic": false,
+    "_isBold": false,
+    "_isUnderline": false,
+    "_underlineHeight": 2,
+    "_cacheMode": 0,
+    "_enableOutline": true,
+    "_outlineColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_outlineWidth": 2,
+    "_enableShadow": false,
+    "_shadowColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_shadowOffset": {
+      "__type__": "cc.Vec2",
+      "x": 2,
+      "y": 2
+    },
+    "_shadowBlur": 3,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "48Kwa0GEtLz4iNCsDTZqXi"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 41
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 47
+    },
+    "_alignFlags": 20,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 11.260000000000003,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "5fyjIGKdxFKbUt98QKOeNE"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "7c+SQcdgJLCq5BihrfVL4k",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 40
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 50
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 184,
+      "height": 57
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "13V2Pt6FVBcblGM7oXxFIc"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 40
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 52
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "9c1dfc7d-edba-450c-8bd8-d22447d565e8@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 1,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "1bRvT/ZPBIAp5dG17f108a"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 40
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 54
+    },
+    "_alignFlags": 20,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "92qA88+xNGRYMIhDqixEIb"
+  },
+  {
+    "__type__": "cc.Button",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 40
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 56
+    },
+    "clickEvents": [],
+    "_interactable": true,
+    "_transition": 0,
+    "_normalColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_hoverColor": {
+      "__type__": "cc.Color",
+      "r": 211,
+      "g": 211,
+      "b": 211,
+      "a": 255
+    },
+    "_pressedColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_disabledColor": {
+      "__type__": "cc.Color",
+      "r": 124,
+      "g": 124,
+      "b": 124,
+      "a": 255
+    },
+    "_normalSprite": null,
+    "_hoverSprite": null,
+    "_pressedSprite": null,
+    "_disabledSprite": null,
+    "_duration": 0.1,
+    "_zoomScale": 1.2,
+    "_target": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "318r8pTLxOh75ye+qP0Ncj"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "f9as9n5pVJYJvzCfYxHvTm",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 59
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 189,
+      "height": 365
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "caKDmJgTNGCYqV/CyULGB8"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "86DeWqroNEdKQe8K6cu6jz",
+    "targetOverrides": null
+  }
+]

+ 13 - 0
assets/Scenes/WeaponNode_pea_shooter.prefab.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.50",
+  "importer": "prefab",
+  "imported": true,
+  "uuid": "9c95869e-a82a-4c95-aa2d-9af1a15bdd4b",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {
+    "syncNodeName": "WeaponNode_pea_shooter"
+  }
+}

+ 1 - 1
assets/data/enemies.json

@@ -688,7 +688,7 @@
     },
     "combat": {
       "attackDamage": 1,
-      "attackRange": 120.0,
+      "attackRange": 0.0,
       "attackSpeed": 0.5,
       "canBlock": false,
       "blockChance": 0.0,

+ 2 - 2
assets/data/skill.json

@@ -84,8 +84,8 @@
       "currentLevel": 0,
       "levelEffects": {
         "multiShotChance": [
-          1,
-          1,
+          0,
+          0.1,
           0.2,
           0.3,
           0.4,

+ 16 - 2
assets/scripts/CombatSystem/BlockManager.ts

@@ -341,7 +341,7 @@ export class BlockManager extends Component {
                             console.warn(`[BlockManager] 注入教程第4步拖拽起点失败: ${e}`);
                         }
                         // 使用步骤索引3创建拖拽动画(起点为注入的方块,终点为编辑器配置的目标节点)
-                        this.guideUIController.createDragAnimation('guild_1', undefined, undefined, 3);
+                        this.guideUIController.showDragAnimationForStep(3);
                     }
                     console.log('[BlockManager] 教程进入第4步并显示Block3指引');
                 }
@@ -943,7 +943,11 @@ export class BlockManager extends Component {
     // 新增:教程阶段对场上已放置方块的移动控制
     public canMovePlacedBlocks(): boolean {
         try {
-            // 仅在第4步允许移动,或第6步完成(_tutorialStep >= 7)后恢复自由移动
+            // 非新手引导环境允许自由移动
+            if (!this.isNewbieTutorialContext() && !this.isExtendedTutorialEventContext()) {
+                return true;
+            }
+            // 新手引导阶段:仅在第4步允许移动,或第6步完成(_tutorialStep >= 7)后恢复自由移动
             return this._tutorialStep === 4 || this._tutorialStep >= 7;
         } catch (e) {
             return true;
@@ -1653,6 +1657,16 @@ export class BlockManager extends Component {
             const completed = this.isTutorialPlacementCompleted(block, targetGrid, this._tutorialTargetGrids, expected || undefined);
             if (!completed) return;
             EventBus.getInstance().emit(GameEvents.TUTORIAL_BLOCK_1_PLACED);
+
+            // 运行时注入 Drag[2] 的起点为刚刚放置到场上的方块(Drag[0] 的结果)
+            if (this.guideUIController) {
+                try {
+                    this.guideUIController.setStartNodeForDragConfigIndex(2, block);
+                } catch (e) {
+                    console.warn(`[BlockManager] 注入 Drag[2] 起点失败: ${e}`);
+                }
+            }
+
             this._tutorialStep = 2;
             console.log(`[BlockManager] 教程第一步完成`);
             return;

+ 13 - 1
assets/scripts/CombatSystem/EnemyInstance.ts

@@ -1467,7 +1467,19 @@ export class EnemyInstance extends Component {
         
         for (const wallNode of wallNodes) {
             const wallPos = wallNode.worldPosition;
-            const distance = Vec3.distance(currentPos, wallPos);
+            let distance: number;
+            const ui = wallNode.getComponent(UITransform);
+            if (ui) {
+                const width = ui.contentSize.width * wallNode.scale.x;
+                const height = ui.contentSize.height * wallNode.scale.y;
+                const halfW = width / 2;
+                const halfH = height / 2;
+                const dx = Math.max(Math.abs(currentPos.x - wallPos.x) - halfW, 0);
+                const dy = Math.max(Math.abs(currentPos.y - wallPos.y) - halfH, 0);
+                distance = Math.sqrt(dx * dx + dy * dy);
+            } else {
+                distance = Vec3.distance(currentPos, wallPos);
+            }
             
             if (distance <= detectionDistance) {
                 const attackTypeStr = isRangedAttack ? '远程攻击' : '近战攻击';

+ 6 - 6
assets/scripts/CombatSystem/EnemyWeapon/EnemyProjectile.ts

@@ -58,12 +58,7 @@ export class EnemyProjectile extends Component {
             return null;
         }
         
-        console.log('[EnemyProjectile] 找到EnemyProjectileInstance组件,开始初始化');
-        
-        // 初始化抛掷物
-        projectileComponent.init(config);
-        
-        console.log('[EnemyProjectile] 抛掷物初始化完成,准备添加到Canvas');
+        console.log('[EnemyProjectile] 准备添加到Canvas并设置位置');
         
         // 添加到Canvas
         const canvas = find('Canvas');
@@ -74,6 +69,11 @@ export class EnemyProjectile extends Component {
             // 确保在Canvas坐标系下正确设置位置
             projectileNode.setWorldPosition(config.startPosition);
             
+            console.log('[EnemyProjectile] 已添加到Canvas并设置位置,开始初始化');
+            
+            // 初始化抛掷物(此时位置已正确,避免弧线弹道朝错方向)
+            projectileComponent.init(config);
+            
             console.log(`[EnemyProjectile] 创建抛掷物成功: 类型=${config.projectileType}, 伤害=${config.damage}, 速度=${config.speed}`);
             console.log('[EnemyProjectile] 抛掷物世界坐标:', projectileNode.worldPosition);
             console.log('[EnemyProjectile] 抛掷物本地坐标:', projectileNode.position);

+ 77 - 179
assets/scripts/CombatSystem/EnemyWeapon/EnemyProjectileInstance.ts

@@ -1,4 +1,4 @@
-import { _decorator, Component, Node, Vec3, RigidBody2D, Collider2D, Contact2DType, IPhysics2DContact, Sprite, find } from 'cc';
+import { _decorator, Component, Node, Vec3, RigidBody2D, Collider2D, Contact2DType, IPhysics2DContact, Sprite, find, SpriteFrame } from 'cc';
 import { BundleLoader } from '../../Core/BundleLoader';
 import { Audio } from '../../AudioManager/AudioManager';
 import EventBus, { GameEvents } from '../../Core/EventBus';
@@ -92,6 +92,9 @@ export class EnemyProjectileInstance extends Component {
         // 初始化弧线弹道
         this.initArcTrajectory();
         
+        // 根据类型刷新外观(异步加载)
+        this.setupProjectileSprite();
+        
         console.log(`[EnemyProjectileInstance] 初始化抛掷物完成: 类型=${this.projectileType}, 伤害=${this.damage}, 速度=${this.speed}`);
         console.log('[EnemyProjectileInstance] 起始位置:', config.startPosition);
     }
@@ -126,10 +129,29 @@ export class EnemyProjectileInstance extends Component {
     }
     
     /**
-     * 设置抛掷物外观,使用3.png
+     * 设置抛掷物外观:
+     * - 法师僵尸 (magic_bolt) 使用 Animation/EnemyAni/003/ball.png
+     * - 其它类型保持预制体默认图片
      */
     private async setupProjectileSprite() {
         if (!this.sprite) return;
+
+        try {
+            if (this.projectileType === 'magic_bolt') {
+                const loader = BundleLoader.getInstance();
+                const framePath = 'EnemyAni/003/ball/spriteFrame';
+                const spriteFrame = await loader.loadAssetFromBundle<SpriteFrame>('Animation', framePath, SpriteFrame);
+                if (spriteFrame && this.sprite && this.sprite.isValid) {
+                    this.sprite.spriteFrame = spriteFrame;
+                    console.log('[EnemyProjectileInstance] 已应用法师抛掷物外观: ball.png');
+                }
+            } else {
+                // 保持预制体默认图片(例如弓箭手箭矢),不做修改
+                console.log(`[EnemyProjectileInstance] 使用默认抛掷物外观,类型=${this.projectileType}`);
+            }
+        } catch (err) {
+            console.error('[EnemyProjectileInstance] 加载抛掷物SpriteFrame失败', err);
+        }
     }
     
     /**
@@ -261,219 +283,95 @@ export class EnemyProjectileInstance extends Component {
             }
         }
         
+        // 设置目标墙体位置
         if (nearestWall) {
-            this.targetWallPosition = nearestWall.getWorldPosition();
-            console.log(`[EnemyProjectileInstance] 找到目标墙体: ${nearestWall.name}, 距离: ${nearestDistance.toFixed(2)}`);
-        } else {
-            console.warn('[EnemyProjectileInstance] 未找到可用的墙体目标');
-            // 设置一个默认的目标位置(屏幕中心下方)
-            this.targetWallPosition = new Vec3(0, -200, 0);
+            this.targetWallPosition = nearestWall.getWorldPosition().clone();
         }
     }
-    
-    /**
-     * 更新弧线弹道
-     */
+
     private updateArcTrajectory(deltaTime: number) {
-        if (!this.arcDir || !this.arcTargetDir) return;
-        
-        // 重新寻找墙体目标(动态追踪)
-        if (!this.targetWallPosition) {
-            this.findNearestWall();
-        }
-        
-        // 更新目标方向
-        if (this.targetWallPosition) {
-            const currentPos = this.node.getWorldPosition();
-            const dirToWall = this.targetWallPosition.clone().subtract(currentPos).normalize();
-            this.arcTargetDir.set(dirToWall);
+        if (!this.arcDir || !this.arcTargetDir) {
+            this.moveProjectile(deltaTime);
+            return;
         }
-        
-        // 计算转
-        const rotateFactor = this.rotateSpeed * deltaTime;
-        this.arcDir = this.arcDir.lerp(this.arcTargetDir, rotateFactor).normalize();
-        
-        // 计算移动向量
-        const moveVector = this.arcDir.clone().multiplyScalar(this.speed * deltaTime);
-        
-        // 获取当前位置并添加移动向量
-        const currentPos = this.node.getWorldPosition();
-        const newPos = currentPos.add(moveVector);
-        
-        // 设置新位置
-        this.node.setWorldPosition(newPos);
-        
-        // 更新节点朝向(可选)
-        const angle = Math.atan2(this.arcDir.y, this.arcDir.x) * 180 / Math.PI;
-        this.node.angle = angle;
+
+        // 平滑转向到目标方向
+        const currentDir = this.arcDir.clone();
+        const targetDir = this.arcTargetDir.clone();
+
+        // 插值计算新方向
+        const lerpFactor = Math.min(1, this.rotateSpeed * deltaTime);
+        const newDir = new Vec3(
+            currentDir.x + (targetDir.x - currentDir.x) * lerpFactor,
+            currentDir.y + (targetDir.y - currentDir.y) * lerpFactor,
+            0
+        ).normalize();
+
+        this.arcDir = newDir;
+        this.direction = newDir;
+
+        // 以当前方向移动
+        this.moveProjectile(deltaTime);
     }
-    
-    // 防止重复销毁的标志
+
     private isDestroyed: boolean = false;
 
-    /**
-     * 碰撞开始事件
-     */
     private onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
-        // 如果已经被销毁,不再处理碰撞
-        if (this.isDestroyed) {
-            console.log(`[EnemyProjectileInstance] 抛掷物已被销毁,忽略碰撞事件`);
-            return;
-        }
+        if (this.isDestroyed) return;
 
         const otherNode = otherCollider.node;
-        const nodeName = otherNode.name;
-        
-        console.log(`[EnemyProjectileInstance] 抛掷物碰撞检测 - 碰撞对象: ${nodeName}, 节点路径: ${this.getNodePath(otherNode)}`);
-        
-        // 抛掷物的目标是墙体,检查是否碰到墙体
+        const otherPath = this.getNodePath(otherNode);
+        console.log(`[EnemyProjectileInstance] 碰撞到节点: ${otherNode.name} (${otherPath})`);
+
         if (this.isWallNode(otherNode)) {
-            console.log(`[EnemyProjectileInstance] 抛掷物击中目标墙体: ${nodeName}, 准备销毁`);
+            // 撞到墙体
             this.hitWall();
-            return;
+        } else if (this.isPlayerBlock(otherNode)) {
+            // 撞到玩家方块
+            // TODO: 造成伤害(如果有需要)
+            this.playHitSound();
+            this.destroyProjectile();
         }
-        
-        console.log(`[EnemyProjectileInstance] 抛掷物碰撞到非目标对象: ${nodeName}, 继续飞行`);
     }
 
-    /**
-     * 获取节点的完整路径
-     */
     private getNodePath(node: Node): string {
-        const path = [];
-        let current = node;
+        const names: string[] = [];
+        let current: Node | null = node;
         while (current) {
-            path.unshift(current.name);
+            names.unshift(current.name);
             current = current.parent;
         }
-        return path.join('/');
+        return names.join('/');
     }
-    
-    /**
-     * 检查是否为墙体节点
-     */
+
     private isWallNode(node: Node): boolean {
-        const nodeName = node.name.toLowerCase();
-        
-        // 检查节点名称是否包含墙体关键词
-        const wallKeywords = ['wall', 'fence', 'jiguang', '墙', '围栏'];
-        const isWallByName = wallKeywords.some(keyword => nodeName.includes(keyword));
-        
-        // 检查节点是否有Wall组件
-        const hasWallComponent = node.getComponent('Wall') !== null;
-        
-        return isWallByName || hasWallComponent;
+        const name = node.name.toLowerCase();
+        return name.includes('fence') || name.includes('wall');
     }
-    
-    /**
-     * 检查是否为玩家方块
-     */
+
     private isPlayerBlock(node: Node): boolean {
-        // 检查节点名称或标签
-        return node.name.includes('Block') || node.name.includes('WeaponBlock');
+        const path = this.getNodePath(node);
+        return path.includes('WeaponBlock') || path.includes('Block');
     }
-    
-    /**
-     * 击中墙体
-     */
+
     private hitWall() {
-        // 防止重复销毁
-        if (this.isDestroyed) {
-            console.log(`[EnemyProjectileInstance] 抛掷物已被销毁,忽略hitWall调用`);
-            return;
-        }
-        
-        this.isDestroyed = true;
-        console.log(`[EnemyProjectileInstance] 抛掷物击中墙体,造成 ${this.damage} 点伤害,开始销毁流程`);
-        
-        // 对墙体造成伤害
-        EventBus.getInstance().emit(GameEvents.ENEMY_DAMAGE_WALL, {
-            damage: this.damage,
-            source: this.node
-        });
-        
-        // 播放击中音效
-        this.playHitSound();
-        
-        // 销毁抛掷物
-        this.destroyProjectile();
-    }
-    
-    /**
-     * 击中玩家方块(已移除,抛掷物不攻击玩家方块)
-     */
-    /*
-    private hitPlayerBlock(blockNode: Node) {
-        // 防止重复销毁
-        if (this.isDestroyed) {
-            console.log(`[EnemyProjectileInstance] 抛掷物已被销毁,忽略hitPlayerBlock调用`);
-            return;
-        }
-        
-        this.isDestroyed = true;
-        console.log(`[EnemyProjectileInstance] 抛掷物击中玩家方块: ${blockNode.name},开始销毁流程`);
-        
-        // 对玩家方块造成伤害 - 使用事件系统
-        EventBus.getInstance().emit(GameEvents.ENEMY_DAMAGE_PLAYER_BLOCK, {
-            damage: this.damage,
-            blockNode: blockNode,
-            source: this.node
-        });
-        
-        // 播放击中音效
         this.playHitSound();
-        
-        // 销毁抛掷物
         this.destroyProjectile();
+        EventBus.getInstance().emit(GameEvents.ENEMY_DAMAGE_WALL, { damage: this.damage, source: this.node });
     }
-    */
-    
-    /**
-     * 播放击中音效
-     */
+
     private playHitSound() {
-        // 根据抛掷物类型播放不同音效
-        let soundPath = '';
-        switch (this.projectileType) {
-            case 'arrow':
-                soundPath = 'data/弹球音效/fire';
-                break;
-            case 'magic_bolt':
-                soundPath = 'data/弹球音效/fire';
-                break;
-            default:
-                soundPath = 'data/弹球音效/fire';
-                break;
-        }
-        
-        if (soundPath) {
-            Audio.playWeaponSound(soundPath);
-        }
+        Audio.playEnemySound('data/弹球音效/MagicianAttack.mp3');
     }
-    
-    /**
-     * 销毁抛掷物
-     */
+
     private destroyProjectile() {
-        // 防止重复销毁
-        if (this.isDestroyed && (!this.node || !this.node.isValid)) {
-            console.log('[EnemyProjectileInstance] 抛掷物已被销毁,跳过重复销毁');
-            return;
-        }
-        
+        this.isDestroyed = true;
         if (this.node && this.node.isValid) {
-            console.log('[EnemyProjectileInstance] 销毁抛掷物节点');
             this.node.destroy();
-        } else {
-            console.log('[EnemyProjectileInstance] 抛掷物节点已无效或不存在');
         }
     }
-    
+
     onDestroy() {
-        // 清理碰撞监听
-        if (this.collider) {
-            this.collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
-        }
-        console.log('[EnemyProjectileInstance] 抛掷物实例组件已销毁');
+        // 清理逻辑,如有需要
     }
 }

+ 0 - 4
assets/scripts/Core/EventBus.ts

@@ -80,8 +80,6 @@ export enum GameEvents {
     APPLY_DAMAGE_TO_ENEMY = 'APPLY_DAMAGE_TO_ENEMY',
     BURN_EFFECT_ENDED = 'BURN_EFFECT_ENDED',
     ENEMY_DAMAGE_WALL = 'ENEMY_DAMAGE_WALL',
-    // ENEMY_DAMAGE_PLAYER_BLOCK = 'ENEMY_DAMAGE_PLAYER_BLOCK', // 已移除,抛掷物不攻击玩家方块
-
 
     ENEMY_START_WAVE = 'ENEMY_START_WAVE',
     ENEMY_START_GAME = 'ENEMY_START_GAME',
@@ -90,8 +88,6 @@ export enum GameEvents {
     // 游戏状态检查事件
     GAME_CHECK_OVER = 'GAME_CHECK_OVER',
     
-
-    
     // 方块生成事件
     GENERATE_BLOCKS = 'GENERATE_BLOCKS',
     WAVE_COMPLETED = 'WAVE_COMPLETED',

+ 11 - 0
assets/scripts/FourUI/MainSystem/MainUIControlller.ts

@@ -28,6 +28,7 @@ export class MainUIController extends Component {
   @property(Label) upgradeNextHpLabel: Label = null;     // 升级后血量Label
   @property(Label) upgradeInfoLabel: Label = null;       // 升级信息Label(显示"升级墙壁"或"已满级")
   @property(Node) upgradeArrowNode: Node = null;         // 箭头符号节点xxtb
+  @property(Node) upgradeInfoNode: Node = null;          // Canvas/MainUI/UpgradeInfoNode-001
 
   /* 墙体配置 */
   // @property(JsonAsset) wallConfigAsset: JsonAsset = null;  // 墙体配置JSON资源 - 已改为动态加载
@@ -401,6 +402,11 @@ export class MainUIController extends Component {
         this.upgradeInfoLabel.string = "已满级";
       }
       
+      // 显示满级提示节点
+      if (this.upgradeInfoNode) {
+        this.upgradeInfoNode.active = true;
+      }
+      
       // 隐藏当前血量Label和箭头符号
       if (this.upgradeCurrentHpLabel) {
         this.upgradeCurrentHpLabel.node.active = false;
@@ -428,6 +434,11 @@ export class MainUIController extends Component {
         this.upgradeInfoLabel.string = "升级墙壁";
       }
       
+      // 隐藏满级提示节点
+      if (this.upgradeInfoNode) {
+        this.upgradeInfoNode.active = false;
+      }
+      
       // 显示升级费用
       const cost = this.getWallUpgradeCost(currentLevel);
       if (costLbl) {

+ 47 - 16
assets/scripts/FourUI/UpgradeSystem/UpgradeController.ts

@@ -281,14 +281,23 @@ export class UpgradeController extends Component {
             return;
         }
         
-        // 找到对应的武器节点
-        const weaponNodeIndex = this.weaponNodes.findIndex(node => node.name === `WeaponNode_${weaponId}`);
-        if (weaponNodeIndex === -1) {
-            console.warn(`未找到武器节点: ${weaponId}`);
-            return;
+        // 找到对应的武器节点(优先在已管理列表中,其次在UI层级中查找)
+        const nodeName = `WeaponNode_${weaponId}`;
+        let weaponNodeIndex = this.weaponNodes.findIndex(node => node.name === nodeName);
+        let oldNode: Node = null;
+        if (weaponNodeIndex !== -1) {
+            oldNode = this.weaponNodes[weaponNodeIndex];
+        } else {
+            const contentRoot = this.weaponLayout?.node?.parent;
+            oldNode = (this.weaponLayout?.node?.getChildByName(nodeName))
+                || (contentRoot && contentRoot.getChildByName(nodeName))
+                || find(`Canvas/UpgradeUI/ScrollView/view/content/${nodeName}`);
+            if (!oldNode) {
+                console.warn(`未找到武器节点: ${weaponId}`);
+                return;
+            }
         }
         
-        const oldNode = this.weaponNodes[weaponNodeIndex];
         const isUnlocked = this.saveDataManager.isWeaponUnlocked(weaponId);
         const weaponData = this.saveDataManager.getWeapon(weaponId);
         
@@ -307,19 +316,20 @@ export class UpgradeController extends Component {
         }
         
         if (newNode) {
-            newNode.name = `WeaponNode_${weaponId}`;
+            newNode.name = nodeName;
             
-            // 获取旧节点的位置
+            // 获取旧节点的位置与父节点(保持插入到同一父节点之下)
             const siblingIndex = oldNode.getSiblingIndex();
+            const parentToUse = oldNode.parent || this.weaponLayout.node;
             
-            // 移除旧节点
+            // 移除旧节点并插入新节点
             oldNode.removeFromParent();
+            parentToUse.insertChild(newNode, siblingIndex);
             
-            // 添加新节点到相同位置
-            this.weaponLayout.node.insertChild(newNode, siblingIndex);
-            
-            // 更新节点数组
-            this.weaponNodes[weaponNodeIndex] = newNode;
+            // 更新已管理节点数组(仅当旧节点是我们管理的列表中的一员)
+            if (weaponNodeIndex !== -1) {
+                this.weaponNodes[weaponNodeIndex] = newNode;
+            }
             
             console.log(`武器 ${weaponId} 状态切换完成: ${isUnlocked ? '解锁' : '锁定'}`);
         }
@@ -347,6 +357,27 @@ export class UpgradeController extends Component {
         
         console.log(`设置武器节点 ${index}: ${weaponConfig.name}, 等级: ${weaponData?.level || 0}, 已解锁: ${isUnlocked}`);
         
+        // 若已存在同名节点(例如手动在 content 下创建),则跳过自动生成
+        const nodeName = `WeaponNode_${weaponConfig.id}`;
+        const contentRoot = this.weaponLayout?.node?.parent;
+        const preExisting = (this.weaponLayout?.node?.getChildByName(nodeName))
+            || (contentRoot && contentRoot.getChildByName(nodeName))
+            || find(`Canvas/UpgradeUI/ScrollView/view/content/${nodeName}`);
+        if (preExisting && preExisting.isValid) {
+            console.log(`[UpgradeController] 检测到已存在节点,进行初始化: ${nodeName}`);
+            // 保持命名一致
+            preExisting.name = nodeName;
+            
+            // 根据解锁状态初始化已存在节点(绑定事件与文案)
+            if (isUnlocked) {
+                await this.setupUnlockedWeaponNode(preExisting, weaponConfig, weaponData);
+            } else {
+                this.setupLockedWeaponNode(preExisting, weaponConfig);
+            }
+            // 注意:不加入 this.weaponNodes,避免被 clearWeaponNodes() 清理
+            return;
+        }
+        
         // 根据解锁状态选择合适的预制体
         let weaponNode: Node = null;
         if (isUnlocked) {
@@ -368,9 +399,9 @@ export class UpgradeController extends Component {
         }
         
         // 设置节点名称
-        weaponNode.name = `WeaponNode_${weaponConfig.id}`;
+        weaponNode.name = nodeName;
         
-        // 添加到布局中
+        // 添加到布局中(统一由 Layout 管理自动生成的节点)
         this.weaponLayout.node.addChild(weaponNode);
         this.weaponNodes.push(weaponNode);
     }

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů