diff --git a/assets/main.scene b/assets/main.scene index 99c5127..3e58bd1 100644 --- a/assets/main.scene +++ b/assets/main.scene @@ -474,6 +474,10 @@ "__uuid__": "8611dbdc-4749-49f1-97ca-aedae3d16320", "__expectedType__": "cc.Prefab" }, + "toastPrefab": { + "__uuid__": "cff2809d-6daa-4749-a911-bb99e97b4b54", + "__expectedType__": "cc.Prefab" + }, "_id": "c2b3nbzv9JuZmP2jxQyN72" }, { diff --git a/assets/main.ts b/assets/main.ts index 51f5e8d..5094859 100644 --- a/assets/main.ts +++ b/assets/main.ts @@ -1,5 +1,6 @@ import { _decorator, Component, Prefab } from 'cc'; import { ViewManager } from './scripts/core/ViewManager'; +import { ToastManager } from './scripts/utils/ToastManager'; const { ccclass, property } = _decorator; /** @@ -14,6 +15,9 @@ export class main extends Component { @property({ type: Prefab, tooltip: '关卡页面预制体' }) pageLevelPrefab: Prefab | null = null; + @property({ type: Prefab, tooltip: 'Toast 预制体' }) + toastPrefab: Prefab | null = null; + /** * onLoad 比 start 更早执行 * 确保 ViewManager 在 PageLoading.start() 之前初始化 @@ -45,5 +49,10 @@ export class main extends Component { zIndex: 1 }); } + + // 初始化 Toast 管理器 + if (this.toastPrefab) { + ToastManager.instance.init(this.toastPrefab, this.node); + } } } diff --git a/assets/prefabs/PageLevel.ts b/assets/prefabs/PageLevel.ts index 4efb61e..748fa57 100644 --- a/assets/prefabs/PageLevel.ts +++ b/assets/prefabs/PageLevel.ts @@ -5,6 +5,7 @@ import { StorageManager } from 'db://assets/scripts/utils/StorageManager'; import { WxSDK } from 'db://assets/scripts/utils/WxSDK'; import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager'; import { RuntimeLevelConfig } from 'db://assets/scripts/types/LevelTypes'; +import { ToastManager } from 'db://assets/scripts/utils/ToastManager'; const { ccclass, property } = _decorator; /** @@ -664,6 +665,9 @@ export class PageLevel extends BaseView { // 触发手机震动 WxSDK.vibrateLong(); + + // 显示 Toast 提示 + ToastManager.show('答案错误,再试试吧!'); } /** diff --git a/assets/prefabs/PassModal.prefab b/assets/prefabs/PassModal.prefab new file mode 100644 index 0000000..e5c4f57 --- /dev/null +++ b/assets/prefabs/PassModal.prefab @@ -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 + } +] \ No newline at end of file diff --git a/assets/prefabs/PassModal.prefab.meta b/assets/prefabs/PassModal.prefab.meta new file mode 100644 index 0000000..0c4f079 --- /dev/null +++ b/assets/prefabs/PassModal.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "29ff0bfc-d5cf-4ad1-b8cb-61bdfd4850ef", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "PassModal" + } +} diff --git a/assets/prefabs/PassModal.ts b/assets/prefabs/PassModal.ts new file mode 100644 index 0000000..306faaa --- /dev/null +++ b/assets/prefabs/PassModal.ts @@ -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) { + + } +} + diff --git a/assets/prefabs/PassModal.ts.meta b/assets/prefabs/PassModal.ts.meta new file mode 100644 index 0000000..ccaaa23 --- /dev/null +++ b/assets/prefabs/PassModal.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "c08bfab3-d14b-4398-bf27-afde6770b665", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/prefabs/Toast.prefab b/assets/prefabs/Toast.prefab new file mode 100644 index 0000000..3a81867 --- /dev/null +++ b/assets/prefabs/Toast.prefab @@ -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 + } +] \ No newline at end of file diff --git a/assets/prefabs/Toast.prefab.meta b/assets/prefabs/Toast.prefab.meta new file mode 100644 index 0000000..2b0fbd0 --- /dev/null +++ b/assets/prefabs/Toast.prefab.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.1.50", + "importer": "prefab", + "imported": true, + "uuid": "cff2809d-6daa-4749-a911-bb99e97b4b54", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "syncNodeName": "Toast" + } +} diff --git a/assets/prefabs/Toast.ts b/assets/prefabs/Toast.ts new file mode 100644 index 0000000..f7834f2 --- /dev/null +++ b/assets/prefabs/Toast.ts @@ -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(); + } +} diff --git a/assets/prefabs/Toast.ts.meta b/assets/prefabs/Toast.ts.meta new file mode 100644 index 0000000..e9a02fc --- /dev/null +++ b/assets/prefabs/Toast.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "64bce5e7-902a-4375-90cb-ddf456576ff7", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/scripts/utils/ToastManager.ts b/assets/scripts/utils/ToastManager.ts new file mode 100644 index 0000000..3ee47a3 --- /dev/null +++ b/assets/scripts/utils/ToastManager.ts @@ -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); + } +} diff --git a/assets/scripts/utils/ToastManager.ts.meta b/assets/scripts/utils/ToastManager.ts.meta new file mode 100644 index 0000000..f23af98 --- /dev/null +++ b/assets/scripts/utils/ToastManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "0ea3615a-071b-4938-81aa-be8615bd5322", + "files": [], + "subMetas": {}, + "userData": {} +}