Compare commits
2 Commits
f99bc12f52
...
45bb6b35ae
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45bb6b35ae | ||
|
|
b05ef71368 |
@@ -474,6 +474,10 @@
|
|||||||
"__uuid__": "8611dbdc-4749-49f1-97ca-aedae3d16320",
|
"__uuid__": "8611dbdc-4749-49f1-97ca-aedae3d16320",
|
||||||
"__expectedType__": "cc.Prefab"
|
"__expectedType__": "cc.Prefab"
|
||||||
},
|
},
|
||||||
|
"toastPrefab": {
|
||||||
|
"__uuid__": "cff2809d-6daa-4749-a911-bb99e97b4b54",
|
||||||
|
"__expectedType__": "cc.Prefab"
|
||||||
|
},
|
||||||
"_id": "c2b3nbzv9JuZmP2jxQyN72"
|
"_id": "c2b3nbzv9JuZmP2jxQyN72"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { _decorator, Component, Prefab } from 'cc';
|
import { _decorator, Component, Prefab } from 'cc';
|
||||||
import { ViewManager } from './scripts/core/ViewManager';
|
import { ViewManager } from './scripts/core/ViewManager';
|
||||||
|
import { ToastManager } from './scripts/utils/ToastManager';
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,6 +15,9 @@ export class main extends Component {
|
|||||||
@property({ type: Prefab, tooltip: '关卡页面预制体' })
|
@property({ type: Prefab, tooltip: '关卡页面预制体' })
|
||||||
pageLevelPrefab: Prefab | null = null;
|
pageLevelPrefab: Prefab | null = null;
|
||||||
|
|
||||||
|
@property({ type: Prefab, tooltip: 'Toast 预制体' })
|
||||||
|
toastPrefab: Prefab | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onLoad 比 start 更早执行
|
* onLoad 比 start 更早执行
|
||||||
* 确保 ViewManager 在 PageLoading.start() 之前初始化
|
* 确保 ViewManager 在 PageLoading.start() 之前初始化
|
||||||
@@ -45,5 +49,10 @@ export class main extends Component {
|
|||||||
zIndex: 1
|
zIndex: 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初始化 Toast 管理器
|
||||||
|
if (this.toastPrefab) {
|
||||||
|
ToastManager.instance.init(this.toastPrefab, this.node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { StorageManager } from 'db://assets/scripts/utils/StorageManager';
|
|||||||
import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
|
import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
|
||||||
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
|
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
|
||||||
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
|
import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes';
|
||||||
|
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,6 +173,9 @@ export class PageLevel extends BaseView {
|
|||||||
// 更新倒计时显示
|
// 更新倒计时显示
|
||||||
this.updateClockLabel();
|
this.updateClockLabel();
|
||||||
|
|
||||||
|
// 预加载下一关图片(静默加载,不阻塞)
|
||||||
|
LevelDataManager.instance.preloadNextLevel(this.currentLevelIndex);
|
||||||
|
|
||||||
console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}, 答案长度: ${config.answer.length}`);
|
console.log(`[PageLevel] 初始化关卡 ${this.currentLevelIndex + 1}, 答案长度: ${config.answer.length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,6 +665,9 @@ export class PageLevel extends BaseView {
|
|||||||
|
|
||||||
// 触发手机震动
|
// 触发手机震动
|
||||||
WxSDK.vibrateLong();
|
WxSDK.vibrateLong();
|
||||||
|
|
||||||
|
// 显示 Toast 提示
|
||||||
|
ToastManager.show('答案错误,再试试吧!');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
317
assets/prefabs/PassModal.prefab
Normal file
317
assets/prefabs/PassModal.prefab
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"__type__": "cc.Prefab",
|
||||||
|
"_name": "PassModal",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_native": "",
|
||||||
|
"data": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"optimizationPolicy": 0,
|
||||||
|
"persistent": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "PassModal",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": null,
|
||||||
|
"_children": [
|
||||||
|
{
|
||||||
|
"__id__": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 12
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 14
|
||||||
|
},
|
||||||
|
"_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.Node",
|
||||||
|
"_name": "Bg",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 9
|
||||||
|
},
|
||||||
|
"_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__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 4
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 1080,
|
||||||
|
"height": 2160
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "b2ImI0id9G+qoAVz1SKMGE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 6
|
||||||
|
},
|
||||||
|
"_customMaterial": null,
|
||||||
|
"_srcBlendFactor": 2,
|
||||||
|
"_dstBlendFactor": 4,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 0,
|
||||||
|
"g": 0,
|
||||||
|
"b": 0,
|
||||||
|
"a": 79
|
||||||
|
},
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "7d8f9b89-4fd1-4c9f-a3ab-38ec7cded7ca@f9941",
|
||||||
|
"__expectedType__": "cc.SpriteFrame"
|
||||||
|
},
|
||||||
|
"_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": "50Mt/bMuNG3YNBb+HD1/Xc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Widget",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 8
|
||||||
|
},
|
||||||
|
"_alignFlags": 45,
|
||||||
|
"_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": 1080,
|
||||||
|
"_originalHeight": 2160,
|
||||||
|
"_alignMode": 2,
|
||||||
|
"_lockFlags": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "4devqNmdRDJY0Xex13oISf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "a82tQt7zpLnbCUsfQMQKDG",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null,
|
||||||
|
"nestedPrefabInstanceRoots": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.UITransform",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 11
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 1080,
|
||||||
|
"height": 2160
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "8fmJjY1EtCTZq9Mq7pjhT+"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Widget",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 13
|
||||||
|
},
|
||||||
|
"_alignFlags": 45,
|
||||||
|
"_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": 1080,
|
||||||
|
"_originalHeight": 2160,
|
||||||
|
"_alignMode": 2,
|
||||||
|
"_lockFlags": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "7fIHnHRk5G7pY0zPQKjszk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "c46/YsCPVOJYA4mWEpNYRx",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null
|
||||||
|
}
|
||||||
|
]
|
||||||
13
assets/prefabs/PassModal.prefab.meta
Normal file
13
assets/prefabs/PassModal.prefab.meta
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.1.50",
|
||||||
|
"importer": "prefab",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "29ff0bfc-d5cf-4ad1-b8cb-61bdfd4850ef",
|
||||||
|
"files": [
|
||||||
|
".json"
|
||||||
|
],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {
|
||||||
|
"syncNodeName": "PassModal"
|
||||||
|
}
|
||||||
|
}
|
||||||
14
assets/prefabs/PassModal.ts
Normal file
14
assets/prefabs/PassModal.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { _decorator, Component, Node } from 'cc';
|
||||||
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
|
@ccclass('PassModal')
|
||||||
|
export class PassModal extends Component {
|
||||||
|
start() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
update(deltaTime: number) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
9
assets/prefabs/PassModal.ts.meta
Normal file
9
assets/prefabs/PassModal.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "c08bfab3-d14b-4398-bf27-afde6770b665",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
425
assets/prefabs/Toast.prefab
Normal file
425
assets/prefabs/Toast.prefab
Normal file
@@ -0,0 +1,425 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"__type__": "cc.Prefab",
|
||||||
|
"_name": "Toast",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_native": "",
|
||||||
|
"data": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"optimizationPolicy": 0,
|
||||||
|
"persistent": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "Toast",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": null,
|
||||||
|
"_children": [
|
||||||
|
{
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 8
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 14
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 18
|
||||||
|
},
|
||||||
|
"_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.Node",
|
||||||
|
"_name": "Bg",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 7
|
||||||
|
},
|
||||||
|
"_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__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 4
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 600,
|
||||||
|
"height": 100.2
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "eb34X6nKREI5sW484fCbxJ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 6
|
||||||
|
},
|
||||||
|
"_customMaterial": null,
|
||||||
|
"_srcBlendFactor": 2,
|
||||||
|
"_dstBlendFactor": 4,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 0,
|
||||||
|
"g": 0,
|
||||||
|
"b": 0,
|
||||||
|
"a": 81
|
||||||
|
},
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "7d8f9b89-4fd1-4c9f-a3ab-38ec7cded7ca@f9941",
|
||||||
|
"__expectedType__": "cc.SpriteFrame"
|
||||||
|
},
|
||||||
|
"_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": "ccLTaXNAxNN5+PbNTb0/4j"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "bbXTIr965Gx7L1svMvPPuy",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null,
|
||||||
|
"nestedPrefabInstanceRoots": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "Content",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 11
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 13
|
||||||
|
},
|
||||||
|
"_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__": 8
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 10
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 240,
|
||||||
|
"height": 50.4
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "7fiEDGRW9OSKl45B3f5V9U"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Label",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 8
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 12
|
||||||
|
},
|
||||||
|
"_customMaterial": null,
|
||||||
|
"_srcBlendFactor": 2,
|
||||||
|
"_dstBlendFactor": 4,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_string": "这是一个提示",
|
||||||
|
"_horizontalAlign": 1,
|
||||||
|
"_verticalAlign": 1,
|
||||||
|
"_actualFontSize": 40,
|
||||||
|
"_fontSize": 40,
|
||||||
|
"_fontFamily": "Arial",
|
||||||
|
"_lineHeight": 40,
|
||||||
|
"_overflow": 0,
|
||||||
|
"_enableWrapText": true,
|
||||||
|
"_font": null,
|
||||||
|
"_isSystemFontUsed": true,
|
||||||
|
"_spacingX": 0,
|
||||||
|
"_isItalic": false,
|
||||||
|
"_isBold": false,
|
||||||
|
"_isUnderline": false,
|
||||||
|
"_underlineHeight": 2,
|
||||||
|
"_cacheMode": 0,
|
||||||
|
"_enableOutline": false,
|
||||||
|
"_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": "7c1OW3o5JEg7hHN4XokTfS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "67pbvD85ZOx75N+pmBJOuz",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null,
|
||||||
|
"nestedPrefabInstanceRoots": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.UITransform",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 15
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 1080,
|
||||||
|
"height": 2160
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "5aGKm9R8JK3o+0MgSZhQCU"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "64bceXnkCpDdZDL3fRWV2/3",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 17
|
||||||
|
},
|
||||||
|
"contentLabel": {
|
||||||
|
"__id__": 11
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "f9bSb/raBCPIvJVb+jhlpc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "c46/YsCPVOJYA4mWEpNYRx",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null
|
||||||
|
}
|
||||||
|
]
|
||||||
13
assets/prefabs/Toast.prefab.meta
Normal file
13
assets/prefabs/Toast.prefab.meta
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.1.50",
|
||||||
|
"importer": "prefab",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "cff2809d-6daa-4749-a911-bb99e97b4b54",
|
||||||
|
"files": [
|
||||||
|
".json"
|
||||||
|
],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {
|
||||||
|
"syncNodeName": "Toast"
|
||||||
|
}
|
||||||
|
}
|
||||||
49
assets/prefabs/Toast.ts
Normal file
49
assets/prefabs/Toast.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { _decorator, Component, Label, tween, UIOpacity } from 'cc';
|
||||||
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
|
@ccclass('Toast')
|
||||||
|
export class Toast extends Component {
|
||||||
|
@property(Label)
|
||||||
|
contentLabel: Label | null = null;
|
||||||
|
|
||||||
|
private _uiOpacity: UIOpacity | null = null;
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
// 获取或添加 UIOpacity 组件用于透明度动画
|
||||||
|
this._uiOpacity = this.node.getComponent(UIOpacity);
|
||||||
|
if (!this._uiOpacity) {
|
||||||
|
this._uiOpacity = this.node.addComponent(UIOpacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示 Toast
|
||||||
|
* @param content 提示内容
|
||||||
|
* @param duration 显示时长(毫秒),默认 2000ms
|
||||||
|
*/
|
||||||
|
show(content: string, duration: number = 2000): void {
|
||||||
|
if (this.contentLabel) {
|
||||||
|
this.contentLabel.string = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置透明度
|
||||||
|
this._uiOpacity!.opacity = 255;
|
||||||
|
|
||||||
|
// 延迟后执行渐隐动画
|
||||||
|
this.scheduleOnce(() => {
|
||||||
|
this._fadeOut();
|
||||||
|
}, duration / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渐隐动画并销毁
|
||||||
|
*/
|
||||||
|
private _fadeOut(): void {
|
||||||
|
tween(this._uiOpacity!)
|
||||||
|
.to(0.3, { opacity: 0 })
|
||||||
|
.call(() => {
|
||||||
|
this.node.destroy();
|
||||||
|
})
|
||||||
|
.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
9
assets/prefabs/Toast.ts.meta
Normal file
9
assets/prefabs/Toast.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "64bce5e7-902a-4375-90cb-ddf456576ff7",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ export type ProgressCallback = (progress: number, message: string) => void;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 关卡数据管理器
|
* 关卡数据管理器
|
||||||
* 单例模式,负责从 API 获取关卡数据并预加载图片
|
* 单例模式,负责从 API 获取关卡数据并按需加载图片
|
||||||
*/
|
*/
|
||||||
export class LevelDataManager {
|
export class LevelDataManager {
|
||||||
private static _instance: LevelDataManager | null = null;
|
private static _instance: LevelDataManager | null = null;
|
||||||
@@ -22,8 +22,11 @@ export class LevelDataManager {
|
|||||||
/** 请求超时时间(毫秒) */
|
/** 请求超时时间(毫秒) */
|
||||||
private readonly REQUEST_TIMEOUT = 8000;
|
private readonly REQUEST_TIMEOUT = 8000;
|
||||||
|
|
||||||
/** 运行时关卡配置缓存 */
|
/** API 返回的原始关卡数据 */
|
||||||
private _levelConfigs: RuntimeLevelConfig[] = [];
|
private _apiData: ApiLevelData[] = [];
|
||||||
|
|
||||||
|
/** 运行时关卡配置缓存(按需填充) */
|
||||||
|
private _levelConfigs: Map<number, RuntimeLevelConfig> = new Map();
|
||||||
|
|
||||||
/** 是否已成功从 API 获取数据 */
|
/** 是否已成功从 API 获取数据 */
|
||||||
private _hasApiData: boolean = false;
|
private _hasApiData: boolean = false;
|
||||||
@@ -31,6 +34,9 @@ export class LevelDataManager {
|
|||||||
/** 图片缓存:URL -> SpriteFrame */
|
/** 图片缓存:URL -> SpriteFrame */
|
||||||
private _imageCache: Map<string, SpriteFrame> = new Map();
|
private _imageCache: Map<string, SpriteFrame> = new Map();
|
||||||
|
|
||||||
|
/** 正在加载中的关卡索引集合 */
|
||||||
|
private _loadingLevels: Set<number> = new Set();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取单例实例
|
* 获取单例实例
|
||||||
*/
|
*/
|
||||||
@@ -47,7 +53,7 @@ export class LevelDataManager {
|
|||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化:从 API 获取数据并预加载图片
|
* 初始化:从 API 获取数据并预加载第一关图片
|
||||||
* @param onProgress 进度回调
|
* @param onProgress 进度回调
|
||||||
* @returns 是否初始化成功
|
* @returns 是否初始化成功
|
||||||
*/
|
*/
|
||||||
@@ -55,34 +61,37 @@ export class LevelDataManager {
|
|||||||
console.log('[LevelDataManager] 开始初始化');
|
console.log('[LevelDataManager] 开始初始化');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 阶段1: 获取 API 数据 (0-20%)
|
// 阶段1: 获取 API 数据 (0-30%)
|
||||||
onProgress?.(0, '正在获取关卡数据...');
|
onProgress?.(0, '正在获取关卡数据...');
|
||||||
const apiData = await this._fetchApiData();
|
const apiData = await this._fetchApiData();
|
||||||
|
|
||||||
if (!apiData || apiData.length === 0) {
|
if (!apiData || apiData.length === 0) {
|
||||||
console.warn('[LevelDataManager] API 返回空数据');
|
console.warn('[LevelDataManager] API 返回空数据');
|
||||||
onProgress?.(0.2, 'API 数据为空,使用本地配置');
|
onProgress?.(0.3, 'API 数据为空,使用本地配置');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[LevelDataManager] 获取到 ${apiData.length} 个关卡数据`);
|
console.log(`[LevelDataManager] 获取到 ${apiData.length} 个关卡数据`);
|
||||||
onProgress?.(0.2, `获取到 ${apiData.length} 个关卡`);
|
this._apiData = apiData;
|
||||||
|
|
||||||
// 阶段2: 预加载所有图片 (20-80%)
|
|
||||||
const configs = await this._preloadImages(apiData, (progress) => {
|
|
||||||
onProgress?.(0.2 + progress * 0.6, '正在加载关卡资源...');
|
|
||||||
});
|
|
||||||
|
|
||||||
this._levelConfigs = configs;
|
|
||||||
this._hasApiData = true;
|
this._hasApiData = true;
|
||||||
|
onProgress?.(0.3, `获取到 ${apiData.length} 个关卡`);
|
||||||
|
|
||||||
console.log('[LevelDataManager] 初始化完成');
|
// 阶段2: 只预加载第一关图片 (30-80%)
|
||||||
onProgress?.(0.8, '关卡资源加载完成');
|
const firstLevel = apiData[0];
|
||||||
|
onProgress?.(0.3, '正在加载第一关资源...');
|
||||||
|
|
||||||
|
const spriteFrame = await this._loadImage(firstLevel.imageUrl);
|
||||||
|
if (spriteFrame) {
|
||||||
|
this._levelConfigs.set(0, this._createRuntimeConfig(firstLevel, spriteFrame));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('[LevelDataManager] 初始化完成,第一关资源已加载');
|
||||||
|
onProgress?.(0.8, '第一关资源加载完成');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[LevelDataManager] 初始化失败:', error);
|
console.error('[LevelDataManager] 初始化失败:', error);
|
||||||
onProgress?.(0.2, '获取数据失败,使用本地配置');
|
onProgress?.(0.3, '获取数据失败,使用本地配置');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,24 +101,107 @@ export class LevelDataManager {
|
|||||||
* @param index 关卡索引
|
* @param index 关卡索引
|
||||||
*/
|
*/
|
||||||
getLevelConfig(index: number): RuntimeLevelConfig | null {
|
getLevelConfig(index: number): RuntimeLevelConfig | null {
|
||||||
if (index < 0 || index >= this._levelConfigs.length) {
|
return this._levelConfigs.get(index) ?? null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this._levelConfigs[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取关卡总数
|
* 获取关卡总数
|
||||||
*/
|
*/
|
||||||
getLevelCount(): number {
|
getLevelCount(): number {
|
||||||
return this._levelConfigs.length;
|
return this._apiData.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否有 API 数据
|
* 检查是否有 API 数据
|
||||||
*/
|
*/
|
||||||
hasApiData(): boolean {
|
hasApiData(): boolean {
|
||||||
return this._hasApiData && this._levelConfigs.length > 0;
|
return this._hasApiData && this._apiData.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查指定关卡图片是否已加载
|
||||||
|
* @param index 关卡索引
|
||||||
|
*/
|
||||||
|
isLevelImageLoaded(index: number): boolean {
|
||||||
|
return this._levelConfigs.has(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保指定关卡资源已准备好
|
||||||
|
* 如果资源未加载,会立即加载
|
||||||
|
* @param index 关卡索引
|
||||||
|
* @returns 加载的关卡配置,失败返回 null
|
||||||
|
*/
|
||||||
|
async ensureLevelReady(index: number): Promise<RuntimeLevelConfig | null> {
|
||||||
|
// 检查索引有效性
|
||||||
|
if (index < 0 || index >= this._apiData.length) {
|
||||||
|
console.warn(`[LevelDataManager] 关卡索引无效: ${index}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查缓存
|
||||||
|
const cached = this._levelConfigs.get(index);
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否正在加载
|
||||||
|
if (this._loadingLevels.has(index)) {
|
||||||
|
console.log(`[LevelDataManager] 关卡 ${index} 正在加载中...`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始加载
|
||||||
|
this._loadingLevels.add(index);
|
||||||
|
console.log(`[LevelDataManager] 开始加载关卡 ${index} 资源...`);
|
||||||
|
|
||||||
|
const data = this._apiData[index];
|
||||||
|
const spriteFrame = await this._loadImage(data.imageUrl);
|
||||||
|
this._loadingLevels.delete(index);
|
||||||
|
|
||||||
|
if (!spriteFrame) {
|
||||||
|
console.error(`[LevelDataManager] 加载关卡 ${index} 图片失败`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = this._createRuntimeConfig(data, spriteFrame);
|
||||||
|
this._levelConfigs.set(index, config);
|
||||||
|
console.log(`[LevelDataManager] 关卡 ${index} 资源加载完成`);
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预加载下一关图片(静默加载,不阻塞)
|
||||||
|
* 在进入当前关卡后调用,提前加载下一关资源
|
||||||
|
* @param currentIndex 当前关卡索引
|
||||||
|
*/
|
||||||
|
preloadNextLevel(currentIndex: number): void {
|
||||||
|
const nextIndex = currentIndex + 1;
|
||||||
|
|
||||||
|
// 检查是否有下一关
|
||||||
|
if (nextIndex >= this._apiData.length) {
|
||||||
|
console.log('[LevelDataManager] 没有下一关了');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否已加载
|
||||||
|
if (this._levelConfigs.has(nextIndex)) {
|
||||||
|
console.log(`[LevelDataManager] 下一关 ${nextIndex} 已加载`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否正在加载
|
||||||
|
if (this._loadingLevels.has(nextIndex)) {
|
||||||
|
console.log(`[LevelDataManager] 下一关 ${nextIndex} 正在加载中`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步加载,不等待
|
||||||
|
console.log(`[LevelDataManager] 开始预加载下一关 ${nextIndex}...`);
|
||||||
|
this.ensureLevelReady(nextIndex).catch(err => {
|
||||||
|
console.error(`[LevelDataManager] 预加载下一关失败:`, err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,35 +224,20 @@ export class LevelDataManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预加载所有图片
|
* 创建运行时关卡配置
|
||||||
* @param apiData API 返回的关卡数据
|
* @param data API 关卡数据
|
||||||
* @param onProgress 进度回调
|
* @param spriteFrame 已加载的精灵帧
|
||||||
*/
|
*/
|
||||||
private async _preloadImages(
|
private _createRuntimeConfig(data: ApiLevelData, spriteFrame: SpriteFrame | null): RuntimeLevelConfig {
|
||||||
apiData: ApiLevelData[],
|
return {
|
||||||
onProgress?: (progress: number) => void
|
id: data.id,
|
||||||
): Promise<RuntimeLevelConfig[]> {
|
name: `第${data.level}关`,
|
||||||
const configs: RuntimeLevelConfig[] = [];
|
spriteFrame: spriteFrame,
|
||||||
const total = apiData.length;
|
clue1: data.hint1,
|
||||||
|
clue2: data.hint2,
|
||||||
for (let i = 0; i < total; i++) {
|
clue3: data.hint3,
|
||||||
const data = apiData[i];
|
answer: data.answer
|
||||||
const spriteFrame = await this._loadImage(data.imageUrl);
|
};
|
||||||
|
|
||||||
configs.push({
|
|
||||||
id: data.id,
|
|
||||||
name: `第${data.level}关`,
|
|
||||||
spriteFrame: spriteFrame,
|
|
||||||
clue1: data.hint1,
|
|
||||||
clue2: data.hint2,
|
|
||||||
clue3: data.hint3,
|
|
||||||
answer: data.answer
|
|
||||||
});
|
|
||||||
|
|
||||||
onProgress?.((i + 1) / total);
|
|
||||||
}
|
|
||||||
|
|
||||||
return configs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,8 +246,9 @@ export class LevelDataManager {
|
|||||||
*/
|
*/
|
||||||
private async _loadImage(url: string): Promise<SpriteFrame | null> {
|
private async _loadImage(url: string): Promise<SpriteFrame | null> {
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
if (this._imageCache.has(url)) {
|
const cached = this._imageCache.get(url);
|
||||||
return this._imageCache.get(url)!;
|
if (cached) {
|
||||||
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
@@ -199,7 +277,9 @@ export class LevelDataManager {
|
|||||||
* 清除缓存
|
* 清除缓存
|
||||||
*/
|
*/
|
||||||
clearCache(): void {
|
clearCache(): void {
|
||||||
this._levelConfigs = [];
|
this._apiData = [];
|
||||||
|
this._levelConfigs.clear();
|
||||||
|
this._loadingLevels.clear();
|
||||||
this._hasApiData = false;
|
this._hasApiData = false;
|
||||||
this._imageCache.clear();
|
this._imageCache.clear();
|
||||||
console.log('[LevelDataManager] 缓存已清除');
|
console.log('[LevelDataManager] 缓存已清除');
|
||||||
|
|||||||
58
assets/scripts/utils/ToastManager.ts
Normal file
58
assets/scripts/utils/ToastManager.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { Node, Prefab, instantiate, find } from 'cc';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toast 管理器
|
||||||
|
* 单例模式,统一管理 Toast 提示的显示
|
||||||
|
*/
|
||||||
|
export class ToastManager {
|
||||||
|
private static _instance: ToastManager | null = null;
|
||||||
|
private _prefab: Prefab | null = null;
|
||||||
|
private _container: Node | null = null;
|
||||||
|
|
||||||
|
static get instance(): ToastManager {
|
||||||
|
if (!this._instance) {
|
||||||
|
this._instance = new ToastManager();
|
||||||
|
}
|
||||||
|
return this._instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化 Toast 管理器
|
||||||
|
* @param prefab Toast 预制体
|
||||||
|
* @param container Toast 容器节点(默认为 Canvas)
|
||||||
|
*/
|
||||||
|
init(prefab: Prefab, container?: Node): void {
|
||||||
|
this._prefab = prefab;
|
||||||
|
this._container = container ?? find('Canvas');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示 Toast 提示
|
||||||
|
* @param content 提示内容
|
||||||
|
* @param duration 显示时长(毫秒),默认 2000ms
|
||||||
|
*/
|
||||||
|
show(content: string, duration: number = 2000): void {
|
||||||
|
if (!this._prefab || !this._container) {
|
||||||
|
console.error('[ToastManager] 未初始化,请先调用 init()');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = instantiate(this._prefab);
|
||||||
|
this._container.addChild(node);
|
||||||
|
|
||||||
|
// 动态获取 Toast 组件
|
||||||
|
const toast = node.getComponent('Toast') as any;
|
||||||
|
if (toast && typeof toast.show === 'function') {
|
||||||
|
toast.show(content, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 静态快捷方法
|
||||||
|
*/
|
||||||
|
static show(content: string, duration: number = 2000): void {
|
||||||
|
ToastManager.instance.show(content, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
9
assets/scripts/utils/ToastManager.ts.meta
Normal file
9
assets/scripts/utils/ToastManager.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "0ea3615a-071b-4938-81aa-be8615bd5322",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user