瀏覽代碼

#add 优化随机算法生成

hanpeng.zhp 2 天之前
父節點
當前提交
d59efbb332

+ 12 - 0
assets/editor.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "e9e712fc-618a-4e9d-964c-e542415cd381",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "bundleConfigID": "c2DHb/LN5EVqRUC6vbP6V9",
+    "isBundle": true
+  }
+}

+ 9 - 0
assets/editor/image.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "980a2343-b400-4479-9afe-5f9d5716a17c",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

二進制
assets/editor/image/bg1.jpg


+ 134 - 0
assets/editor/image/bg1.jpg.meta

@@ -0,0 +1,134 @@
+{
+  "ver": "1.0.27",
+  "importer": "image",
+  "imported": true,
+  "uuid": "eab31623-2705-4800-abab-5c8914753a77",
+  "files": [
+    ".jpg",
+    ".json"
+  ],
+  "subMetas": {
+    "6c48a": {
+      "importer": "texture",
+      "uuid": "eab31623-2705-4800-abab-5c8914753a77@6c48a",
+      "displayName": "bg1",
+      "id": "6c48a",
+      "name": "texture",
+      "userData": {
+        "wrapModeS": "clamp-to-edge",
+        "wrapModeT": "clamp-to-edge",
+        "imageUuidOrDatabaseUri": "eab31623-2705-4800-abab-5c8914753a77",
+        "isUuid": true,
+        "visible": false,
+        "minfilter": "linear",
+        "magfilter": "linear",
+        "mipfilter": "none",
+        "anisotropy": 0
+      },
+      "ver": "1.0.22",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {}
+    },
+    "f9941": {
+      "importer": "sprite-frame",
+      "uuid": "eab31623-2705-4800-abab-5c8914753a77@f9941",
+      "displayName": "bg1",
+      "id": "f9941",
+      "name": "spriteFrame",
+      "userData": {
+        "trimThreshold": 1,
+        "rotated": false,
+        "offsetX": 0,
+        "offsetY": 0,
+        "trimX": 0,
+        "trimY": 0,
+        "width": 900,
+        "height": 1200,
+        "rawWidth": 900,
+        "rawHeight": 1200,
+        "borderTop": 0,
+        "borderBottom": 0,
+        "borderLeft": 0,
+        "borderRight": 0,
+        "packable": true,
+        "pixelsToUnit": 100,
+        "pivotX": 0.5,
+        "pivotY": 0.5,
+        "meshType": 0,
+        "vertices": {
+          "rawPosition": [
+            -450,
+            -600,
+            0,
+            450,
+            -600,
+            0,
+            -450,
+            600,
+            0,
+            450,
+            600,
+            0
+          ],
+          "indexes": [
+            0,
+            1,
+            2,
+            2,
+            1,
+            3
+          ],
+          "uv": [
+            0,
+            1200,
+            900,
+            1200,
+            0,
+            0,
+            900,
+            0
+          ],
+          "nuv": [
+            0,
+            0,
+            1,
+            0,
+            0,
+            1,
+            1,
+            1
+          ],
+          "minPos": [
+            -450,
+            -600,
+            0
+          ],
+          "maxPos": [
+            450,
+            600,
+            0
+          ]
+        },
+        "isUuid": true,
+        "imageUuidOrDatabaseUri": "eab31623-2705-4800-abab-5c8914753a77@6c48a",
+        "atlasUuid": "",
+        "trimType": "auto"
+      },
+      "ver": "1.0.12",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {}
+    }
+  },
+  "userData": {
+    "type": "sprite-frame",
+    "hasAlpha": false,
+    "fixAlphaTransparencyArtifacts": false,
+    "redirect": "eab31623-2705-4800-abab-5c8914753a77@6c48a"
+  }
+}

+ 528 - 0
assets/editor/prefab/LvlContainer.prefab

@@ -0,0 +1,528 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "LvlContainer",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "persistent": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "LvlContainer",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": null,
+    "_children": [
+      {
+        "__id__": 2
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 20
+      },
+      {
+        "__id__": 22
+      }
+    ],
+    "_prefab": {
+      "__id__": 24
+    },
+    "_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": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Mask",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [
+      {
+        "__id__": 3
+      },
+      {
+        "__id__": 9
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 13
+      },
+      {
+        "__id__": 15
+      },
+      {
+        "__id__": 17
+      }
+    ],
+    "_prefab": {
+      "__id__": 19
+    },
+    "_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": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Bg",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 4
+      },
+      {
+        "__id__": 6
+      }
+    ],
+    "_prefab": {
+      "__id__": 8
+    },
+    "_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": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 3
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 5
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 900,
+      "height": 1200
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "57uRjvv7lNSaQaYVK5ka/h"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_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
+    },
+    "_spriteFrame": null,
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "69Tp3fh8pEbr9+FGGTGRe4"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "74TExUeTFGf6fUjx72ABrE",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "ItemContainer",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 10
+      }
+    ],
+    "_prefab": {
+      "__id__": 12
+    },
+    "_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": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 9
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 11
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 100
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "3aBL9gA9RI/KqqsFEuTd1q"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "37X7rGtx1I8p2Mf2UsTn0I",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 14
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 700,
+      "height": 900
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "78/6A90d9D77UI2huIEoA9"
+  },
+  {
+    "__type__": "cc.Mask",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 16
+    },
+    "_type": 0,
+    "_inverted": false,
+    "_segments": 64,
+    "_alphaThreshold": 0.1,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "e27W+gI8tD476/r3VgLAkM"
+  },
+  {
+    "__type__": "cc.Graphics",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 18
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_lineWidth": 1,
+    "_strokeColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_lineJoin": 2,
+    "_lineCap": 0,
+    "_fillColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 0
+    },
+    "_miterLimit": 10,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "5b/7DBSftD755gdb6TNVSO"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "15No7uo31GJrQDpzj5bGS9",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 21
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 100
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "e9xRuYJjdFt7ecH35S+jQr"
+  },
+  {
+    "__type__": "24e29wazQdN96eX9Dbu6URB",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 23
+    },
+    "mask": {
+      "__id__": 2
+    },
+    "lvlBg": {
+      "__id__": 6
+    },
+    "findItemPrefab": {
+      "__uuid__": "4adbc36f-8ee3-4681-939e-abc0c25bb481",
+      "__expectedType__": "cc.Prefab"
+    },
+    "minScale": 0.1,
+    "maxScale": 1.5,
+    "itemContainer": {
+      "__id__": 9
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "6cGReOyFFBs7p+K9qdgRaD"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "c3fAiNsf1KjKbe4v/V4vhI",
+    "targetOverrides": []
+  }
+]

+ 13 - 0
assets/editor/prefab/LvlContainer.prefab.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.50",
+  "importer": "prefab",
+  "imported": true,
+  "uuid": "30887653-2e12-4e46-8673-4b9704b4586d",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {
+    "syncNodeName": "LvlContainer"
+  }
+}

+ 9 - 0
assets/editor/prefab/spine.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "a0567f2b-f1a5-4cc5-b31c-af6a82c4dc51",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 146 - 0
assets/editor/prefab/spine/spine01.prefab

@@ -0,0 +1,146 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "spine01",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "persistent": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "spine01",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": null,
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 4
+      }
+    ],
+    "_prefab": {
+      "__id__": 6
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": -31.19100000000003,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 0.1,
+      "y": 0.1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 3
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 1083,
+      "height": 1162
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5164912145443791,
+      "y": 0.15754733848900065
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "aeSy2MWy5OW7RlOi8ZS4Ci"
+  },
+  {
+    "__type__": "sp.Skeleton",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 5
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_skeletonData": {
+      "__uuid__": "3bee2366-5c54-46b2-a17b-af20f102db5a",
+      "__expectedType__": "sp.SkeletonData"
+    },
+    "defaultSkin": "default",
+    "defaultAnimation": "loop",
+    "_premultipliedAlpha": false,
+    "_timeScale": 1,
+    "_preCacheMode": 0,
+    "_cacheMode": 0,
+    "_sockets": [],
+    "_useTint": false,
+    "_debugMesh": false,
+    "_debugBones": false,
+    "_debugSlots": false,
+    "_enableBatch": false,
+    "loop": true,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "feMX4JwvtDS5vChNNxCLWj"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "deeVjRN5FDhbuhFFOaV1Ob",
+    "targetOverrides": null
+  }
+]

+ 13 - 0
assets/editor/prefab/spine/spine01.prefab.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.50",
+  "importer": "prefab",
+  "imported": true,
+  "uuid": "4df89a06-9a4a-439d-a357-3a195192db11",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {
+    "syncNodeName": "spine01"
+  }
+}

+ 287 - 0
assets/editor/script/LevelContainer.ts

@@ -0,0 +1,287 @@
+import { _decorator, Component, Prefab, Sprite, SpriteFrame, instantiate, Node, Vec3, assetManager, AssetManager, resources, randomRangeInt, randomRange, UITransform, Vec2 } from "cc";
+import FindItem, { ItemState } from "./FindItem";
+import { LayerMgr } from "../../script/Manager/LayerMgr";
+import { CCFloat } from "cc";
+const { ccclass, property } = _decorator;
+
+// 关卡模式枚举
+export enum LevelMode {
+    EDIT,      // 编辑模式
+    NORMAL     // 正常选择模式
+}
+
+@ccclass('LevelContainer')
+export class LevelContainer extends Component {
+
+    @property({ type: Node, tooltip: '遮罩' })
+    mask: Node = null;
+
+    @property({ type: Sprite, tooltip: '背景图' })
+    lvlBg: Sprite = null;
+
+    @property({ type: Prefab, tooltip: '物品预制体' })
+    findItemPrefab: Prefab = null;
+
+    @property({ type: CCFloat, tooltip: '最小缩放比例' })
+    minScale: number = 0.1;
+
+    @property({ type: CCFloat, tooltip: '最大缩放比例' })
+    maxScale: number = 1.5;
+
+    @property({ type: Node, tooltip: '物品容器' })
+    itemContainer: Node = null;
+
+    _findItems: FindItem[] = [];
+    _currentMode: LevelMode = LevelMode.NORMAL;
+    _totalItems: number = 0;
+    _foundItems: number = 0;
+    _onLevelComplete: Function = null;
+
+    _bgPath: string = "";
+    _itemSpinePaths: string[] = [];
+    _itemcnt: number = 0;
+    _itemScales: number[] = [];
+
+    _defaultScales: number[] = [1.18, 1.16, 1.14, 0.3976, 0.3690, 0.3029,
+        0.0667, 0.0766, 0.0531, 0.0716];
+
+    // start() {
+    //     LayerMgr.instance.loadBundle("editor", () => {
+    //         this.genLvlContent("image/bg1", ["prefab/spine/spine01"], 10);
+    //     });
+    // }
+
+    /**
+     * 切换编辑模式
+     * @param isEdit 是否为编辑模式
+     */
+    swtichEditMode(isEdit: boolean) {
+        this._currentMode = isEdit ? LevelMode.EDIT : LevelMode.NORMAL;
+
+        // 更新所有物品的状态
+        this._findItems.forEach(item => {
+            if (isEdit) {
+                item.enterEditMode();
+            } else {
+                item.exitEditMode();
+            }
+        });
+
+        // 重置找到的物品计数
+        if (!isEdit) {
+            this._foundItems = 0;
+        }
+    }
+
+
+    /**
+     * 生成关卡内容
+     * @param bgPath 背景图路径
+     * @param Items 物品预制体路径数组
+     * @param itemcnt 物品数量
+     * @param itemScales 物品缩放数组,为空时随机缩放
+     */
+    public genLvlContent(bgPath: string, itemSpinePaths: string[], itemcnt: number, itemScales: number[] = null) {
+        // 清空现有物品
+        this.clearItems();
+        this._bgPath = bgPath;
+        this._totalItems = itemcnt;
+        this._itemSpinePaths = itemSpinePaths;
+        this._itemcnt = itemcnt;
+        this._itemScales = itemScales || this._defaultScales;
+
+        // 加载背景图
+        this.loadSprite(bgPath, (spriteFrame: SpriteFrame) => {
+            console.log("loadSprite", bgPath, spriteFrame);
+            if (this.lvlBg && spriteFrame) {
+                this.lvlBg.spriteFrame = spriteFrame;
+            }
+        });
+
+        // 生成物品
+        for (let i = 0; i < itemcnt; i++) {
+            // 随机选择一个物品
+            var randomIndex = randomRangeInt(0, itemSpinePaths.length - 1);
+            this.createItem(itemSpinePaths[randomIndex], this._itemScales[i]);
+        }
+    }
+
+    /**
+     * 创建物品
+     * @param itemPrefab 物品预制体
+     * @param scale 缩放值,null时随机缩放
+     */
+    private createItem(itemPrefabPath: string, scale: number | null) {
+        const itemNode = instantiate(this.findItemPrefab);
+        itemNode.parent = this.itemContainer || this.node;
+
+        const findItem = itemNode.getComponent(FindItem);
+        if (findItem) {
+            var size = this.mask.getComponent(UITransform).contentSize;
+            // 设置缩放
+            const finalScale = scale !== null ? scale : randomRange(this.minScale, this.maxScale);
+            // 设置随机位置, 不要出边框 
+            var itemSize = itemNode.getComponent(UITransform).contentSize;
+            var w = itemSize.width * finalScale;
+            var h = itemSize.height * finalScale;
+
+            // 随机,并尽量不要重叠
+            let tryCount = 0;
+            let maxTry = 50;
+            let pos: Vec3;
+            let overlap = false;
+            do {
+                overlap = false;
+                const randomX = randomRange(-size.width / 2 + w / 2, size.width / 2 - w / 2);
+                const randomY = randomRange(-size.height / 2 + h / 2, size.height / 2 - h / 2);
+                pos = new Vec3(randomX, randomY, 0);
+
+                // 检查与已放置物品是否重叠
+                for (let other of this._findItems) {
+                    let otherPos = other.node.getPosition();
+                    let otherScale = other.node.scale.x;
+                    let otherSize = other.node.getComponent(UITransform).contentSize;
+                    let otherW = otherSize.width * otherScale;
+                    let otherH = otherSize.height * otherScale;
+
+                    // 简单的AABB重叠检测
+                    if (
+                        Math.abs(pos.x - otherPos.x) < (w + otherW) / 2 &&
+                        Math.abs(pos.y - otherPos.y) < (h + otherH) / 2
+                    ) {
+                        overlap = true;
+                        break;
+                    }
+                }
+                tryCount++;
+            } while (overlap && tryCount < maxTry);
+
+            itemNode.setPosition(pos);
+
+
+            findItem.setData({
+                position: itemNode.getPosition(),
+                scale: finalScale
+            });
+
+            // 添加spine内容
+            this.loadPrefab(itemPrefabPath, (prefab: Prefab) => {
+                findItem.addSpineContentByPrefab(prefab);
+            });
+
+            // 设置状态
+            findItem.setState(this._currentMode === LevelMode.EDIT ? ItemState.EDIT : ItemState.NORMAL);
+
+            // 添加到物品列表
+            this._findItems.push(findItem);
+
+            // 监听物品状态变化
+            this.setupItemListeners(findItem);
+        }
+    }
+
+    /**
+     * 设置物品监听器
+     * @param findItem 物品组件
+     */
+    private setupItemListeners(findItem: FindItem) {
+        // 监听物品点击事件
+        findItem.node.on("itemFound", () => {
+            if (this._currentMode === LevelMode.NORMAL) {
+                this._foundItems++;
+                console.log("itemFound", this._foundItems, this._totalItems);
+                // 检查是否所有物品都被找到
+                if (this._foundItems >= this._totalItems) {
+                    this.onLevelComplete();
+                }
+            }
+        });
+    }
+
+    /**
+     * 关卡完成回调
+     */
+    private onLevelComplete() {
+        if (this._onLevelComplete) {
+            this._onLevelComplete();
+        }
+
+        // 可以在这里添加完成动画或音效
+        console.log("关卡完成!所有物品都已找到");
+    }
+
+    /**
+     * 清空所有物品
+     */
+    private clearItems() {
+        this._findItems.forEach(item => {
+            if (item && item.node) {
+                item.node.destroy();
+            }
+        });
+        this._findItems = [];
+        this._foundItems = 0;
+        this._totalItems = 0;
+    }
+
+    /**
+     * 设置关卡完成回调
+     * @param callback 完成回调函数
+     */
+    public setLevelCompleteCallback(callback: Function) {
+        this._onLevelComplete = callback;
+    }
+
+    /**
+     * 显示提示(高亮未找到的物品)
+     */
+    public showHint() {
+        this._findItems.forEach(item => {
+            if (item.getState() === ItemState.NORMAL) {
+                item.showHint();
+            }
+        });
+    }
+
+    public reset() {
+        this.clearItems();
+        this.swtichEditMode(false);
+        this.genLvlContent(this._bgPath, this._itemSpinePaths, this._itemcnt, this._itemScales);
+    }
+
+    /**
+     * 获取关卡数据(用于保存)
+     */
+    public getLevelData() {
+        return {
+            items: this._findItems.map(item => item.getData()),
+            totalItems: this._totalItems
+        };
+    }
+
+    /**
+     * 加载精灵图片
+     * @param path 图片路径
+     * @param callback 回调函数
+     */
+    loadSprite(path: string, callback: (spriteFrame: SpriteFrame) => void) {
+        LayerMgr.instance.loadSprite("editor", path, callback);
+    }
+
+    prefabMap: Map<string, Prefab> = new Map();
+    /**
+     * 加载预制体
+     * @param path 预制体路径
+     * @param callback 回调函数
+     */
+    loadPrefab(path: string, callback: (prefab: Prefab) => void) {
+        if (this.prefabMap.has(path)) {
+            callback(this.prefabMap.get(path));
+            return;
+        }
+        LayerMgr.instance.loadPrefab("editor", path, (prefab: Prefab) => {
+            this.prefabMap.set(path, prefab);
+            callback(prefab);
+        });
+    }
+}

+ 9 - 0
assets/editor/script/LevelContainer.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "24e29c1a-cd07-4df7-a797-f436eee94441",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}

+ 133 - 29
assets/mainscene.scene

@@ -23,7 +23,7 @@
     "_active": true,
     "_components": [],
     "_prefab": {
-      "__id__": 9
+      "__id__": 16
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -54,7 +54,7 @@
     },
     "autoReleaseAssets": false,
     "_globals": {
-      "__id__": 10
+      "__id__": 17
     },
     "_id": "b847552f-7f6d-4f54-8ed4-da3f54a59a13"
   },
@@ -69,21 +69,21 @@
     "_children": [
       {
         "__id__": 3
+      },
+      {
+        "__id__": 5
       }
     ],
     "_active": true,
     "_components": [
       {
-        "__id__": 5
-      },
-      {
-        "__id__": 6
+        "__id__": 13
       },
       {
-        "__id__": 7
+        "__id__": 14
       },
       {
-        "__id__": 8
+        "__id__": 15
       }
     ],
     "_prefab": null,
@@ -207,6 +207,117 @@
     "_trackingType": 0,
     "_id": "63WIch3o5BEYRlXzTT0oWc"
   },
+  {
+    "__type__": "cc.Node",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 2
+    },
+    "_prefab": {
+      "__id__": 6
+    },
+    "__editorExtras__": {}
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 5
+    },
+    "asset": {
+      "__uuid__": "30887653-2e12-4e46-8673-4b9704b4586d",
+      "__expectedType__": "cc.Prefab"
+    },
+    "fileId": "c3fAiNsf1KjKbe4v/V4vhI",
+    "instance": {
+      "__id__": 7
+    },
+    "targetOverrides": [],
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.PrefabInstance",
+    "fileId": "5e5Bn3+8JCGLSOMC4f0kOy",
+    "prefabRootNode": null,
+    "mountedChildren": [],
+    "mountedComponents": [],
+    "propertyOverrides": [
+      {
+        "__id__": 8
+      },
+      {
+        "__id__": 10
+      },
+      {
+        "__id__": 11
+      },
+      {
+        "__id__": 12
+      }
+    ],
+    "removedComponents": []
+  },
+  {
+    "__type__": "CCPropertyOverrideInfo",
+    "targetInfo": {
+      "__id__": 9
+    },
+    "propertyPath": [
+      "_name"
+    ],
+    "value": "LvlContainer"
+  },
+  {
+    "__type__": "cc.TargetInfo",
+    "localID": [
+      "c3fAiNsf1KjKbe4v/V4vhI"
+    ]
+  },
+  {
+    "__type__": "CCPropertyOverrideInfo",
+    "targetInfo": {
+      "__id__": 9
+    },
+    "propertyPath": [
+      "_lpos"
+    ],
+    "value": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    }
+  },
+  {
+    "__type__": "CCPropertyOverrideInfo",
+    "targetInfo": {
+      "__id__": 9
+    },
+    "propertyPath": [
+      "_lrot"
+    ],
+    "value": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    }
+  },
+  {
+    "__type__": "CCPropertyOverrideInfo",
+    "targetInfo": {
+      "__id__": 9
+    },
+    "propertyPath": [
+      "_euler"
+    ],
+    "value": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    }
+  },
   {
     "__type__": "cc.UITransform",
     "_name": "",
@@ -275,51 +386,44 @@
     "_lockFlags": 0,
     "_id": "c5V1EV8IpMtrIvY1OE9t2u"
   },
-  {
-    "__type__": "522d8m1U+9As79YPl61tFUI",
-    "_name": "",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "node": {
-      "__id__": 2
-    },
-    "_enabled": true,
-    "__prefab": null,
-    "_id": "d989rZen5HDpjHhJDji8sq"
-  },
   {
     "__type__": "cc.PrefabInfo",
     "root": null,
     "asset": null,
     "fileId": "b847552f-7f6d-4f54-8ed4-da3f54a59a13",
     "instance": null,
-    "targetOverrides": null
+    "targetOverrides": [],
+    "nestedPrefabInstanceRoots": [
+      {
+        "__id__": 5
+      }
+    ]
   },
   {
     "__type__": "cc.SceneGlobals",
     "ambient": {
-      "__id__": 11
+      "__id__": 18
     },
     "shadows": {
-      "__id__": 12
+      "__id__": 19
     },
     "_skybox": {
-      "__id__": 13
+      "__id__": 20
     },
     "fog": {
-      "__id__": 14
+      "__id__": 21
     },
     "octree": {
-      "__id__": 15
+      "__id__": 22
     },
     "skin": {
-      "__id__": 16
+      "__id__": 23
     },
     "lightProbeInfo": {
-      "__id__": 17
+      "__id__": 24
     },
     "postSettings": {
-      "__id__": 18
+      "__id__": 25
     },
     "bakedWithStationaryMainLight": false,
     "bakedWithHighpLightmap": false