feat: 完善新版 UI
This commit is contained in:
32
AGENTS.md
32
AGENTS.md
@@ -19,13 +19,13 @@ Git 历史采用 Conventional Commits,且摘要多为中文,例如 `feat:
|
|||||||
<claude-mem-context>
|
<claude-mem-context>
|
||||||
# Memory Context
|
# Memory Context
|
||||||
|
|
||||||
# [mp-xieyingeng] recent context, 2026-04-24 8:08pm GMT+8
|
# [mp-xieyingeng] recent context, 2026-04-24 9:39pm GMT+8
|
||||||
|
|
||||||
Legend: 🎯session 🔴bugfix 🟣feature 🔄refactor ✅change 🔵discovery ⚖️decision 🚨security_alert 🔐security_note
|
Legend: 🎯session 🔴bugfix 🟣feature 🔄refactor ✅change 🔵discovery ⚖️decision 🚨security_alert 🔐security_note
|
||||||
Format: ID TIME TYPE TITLE
|
Format: ID TIME TYPE TITLE
|
||||||
Fetch details: get_observations([IDs]) | Search: mem-search skill
|
Fetch details: get_observations([IDs]) | Search: mem-search skill
|
||||||
|
|
||||||
Stats: 19 obs (4,277t read) | 178,750t work | 98% savings
|
Stats: 45 obs (10,437t read) | 520,499t work | 98% savings
|
||||||
|
|
||||||
### Apr 24, 2026
|
### Apr 24, 2026
|
||||||
101 8:46a 🟣 Live label display format updated to X/Y format
|
101 8:46a 🟣 Live label display format updated to X/Y format
|
||||||
@@ -47,6 +47,32 @@ Stats: 19 obs (4,277t read) | 178,750t work | 98% savings
|
|||||||
138 " 🔄 PageLevel 输入方式从单框改为逐字格子
|
138 " 🔄 PageLevel 输入方式从单框改为逐字格子
|
||||||
139 " 🔄 谐音梗展示从 Label 改为动态 Block 节点
|
139 " 🔄 谐音梗展示从 Label 改为动态 Block 节点
|
||||||
140 " ✅ PageLevel.prefab 布局位置微调
|
140 " ✅ PageLevel.prefab 布局位置微调
|
||||||
|
165 8:08p 🟣 PageLevel input layout simplified to single-character boxes with auto-distribution
|
||||||
|
167 8:09p 🔵 PageLevel.ts input block structure and callback stubs discovered
|
||||||
|
168 " 🟣 Auto-distribute characters across input boxes and auto-submit on completion implemented
|
||||||
|
169 " 🔴 PageLevel.ts node cleanup now calls removeFromParent before destroy
|
||||||
|
170 8:10p 🔄 PageLevel.ts full diff: single EditBox replaced with per-character block system
|
||||||
|
171 " 🔴 distributeInputText() wrapped in try/finally to guarantee flag reset
|
||||||
|
179 8:23p ✅ Game011_3.ttf font relocated from resources/ to dedicated fonts/ bundle directory
|
||||||
|
180 " 🟣 PageLoading.ts now loads fonts as a dynamic bundle after level data, before UI
|
||||||
|
181 " 🔄 AssetManager import switched to type-only import in PageLoading.ts
|
||||||
|
182 8:31p 🟣 PageLevel input UX improvement: full-string editing support
|
||||||
|
183 " 🟣 PageLevel input UX: full-string editing implemented
|
||||||
|
186 8:34p 🔴 PageLevel: clear input text on wrong answer
|
||||||
|
187 8:35p 🟣 PageLevel: delay pass modal to show punchline
|
||||||
|
189 8:36p 🔄 PageLevel: level completion reporting made fire-and-forget
|
||||||
|
191 8:45p 🔴 PageLevel: punchline block cleanup improved
|
||||||
|
192 8:46p 🟣 PageLevel.ts TitleLevel Label variable reserved
|
||||||
|
193 8:47p 🔵 PageLevel.ts level number tracking mechanism discovered
|
||||||
|
195 " 🟣 PageLevel.ts TitleLevel dynamic label update implemented
|
||||||
|
196 8:53p 🔵 PageLevel punchline not updated from enterLevel API
|
||||||
|
198 " 🔴 LevelDataManager updateLevelDetails now includes punchline
|
||||||
|
199 " 🔴 PageLevel punchline flow and empty state layout fixed
|
||||||
|
200 8:54p 🔴 LevelDataManager preserves existing punchline when enter returns null
|
||||||
|
203 9:06p 🟣 PageLevel.ts 新增图片描述标签绑定字段
|
||||||
|
205 9:07p 🟣 PageLevel.ts 图片描述标签字段对接完成
|
||||||
|
206 9:09p ✅ PageLevel.ts 回退图片描述标签字段命名
|
||||||
|
208 9:11p 🟣 LevelDataManager 增加图片描述字段存储
|
||||||
|
|
||||||
Access 179k tokens of past work via get_observations([IDs]) or mem-search skill.
|
Access 520k tokens of past work via get_observations([IDs]) or mem-search skill.
|
||||||
</claude-mem-context>
|
</claude-mem-context>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { _decorator, Component, ProgressBar, Label } from 'cc';
|
import { _decorator, Component, ProgressBar, Label, assetManager } from 'cc';
|
||||||
|
import type { AssetManager } from 'cc';
|
||||||
import { ViewManager } from './scripts/core/ViewManager';
|
import { ViewManager } from './scripts/core/ViewManager';
|
||||||
import { LevelDataManager } from './scripts/utils/LevelDataManager';
|
import { LevelDataManager } from './scripts/utils/LevelDataManager';
|
||||||
import { AuthManager } from './scripts/utils/AuthManager';
|
import { AuthManager } from './scripts/utils/AuthManager';
|
||||||
@@ -14,6 +15,8 @@ const { ccclass, property } = _decorator;
|
|||||||
*/
|
*/
|
||||||
@ccclass('PageLoading')
|
@ccclass('PageLoading')
|
||||||
export class PageLoading extends Component {
|
export class PageLoading extends Component {
|
||||||
|
private static readonly FONT_BUNDLE_NAME = 'fonts';
|
||||||
|
|
||||||
@property(ProgressBar)
|
@property(ProgressBar)
|
||||||
progressBar: ProgressBar | null = null;
|
progressBar: ProgressBar | null = null;
|
||||||
|
|
||||||
@@ -52,6 +55,12 @@ export class PageLoading extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fontSuccess = await this._loadFontBundle();
|
||||||
|
if (!fontSuccess) {
|
||||||
|
this._updateStatusLabel('字体资源加载失败,请重新打开游戏');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 登录 + 关卡数据都就绪后,用服务端进度覆盖本地进度
|
// 登录 + 关卡数据都就绪后,用服务端进度覆盖本地进度
|
||||||
if (loginSuccess) {
|
if (loginSuccess) {
|
||||||
this._syncProgressFromServer();
|
this._syncProgressFromServer();
|
||||||
@@ -77,10 +86,10 @@ export class PageLoading extends Component {
|
|||||||
console.warn('[PageLoading] 加入分享失败,进入正常模式');
|
console.warn('[PageLoading] 加入分享失败,进入正常模式');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 正常流程:预加载 PageHome (80-100%)
|
// 正常流程:预加载 PageHome (82-100%)
|
||||||
ViewManager.instance.preload('PageHome',
|
ViewManager.instance.preload('PageHome',
|
||||||
(progress) => {
|
(progress) => {
|
||||||
this._updateProgress(0.8 + progress * 0.2);
|
this._updateProgress(0.82 + progress * 0.18);
|
||||||
this._updateStatusLabel('正在加载界面资源...');
|
this._updateStatusLabel('正在加载界面资源...');
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
@@ -112,6 +121,36 @@ export class PageLoading extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载字体分包,避免字体资源进入小游戏主包
|
||||||
|
*/
|
||||||
|
private _loadFontBundle(): Promise<boolean> {
|
||||||
|
const bundleName = PageLoading.FONT_BUNDLE_NAME;
|
||||||
|
const cachedBundle = assetManager.getBundle(bundleName);
|
||||||
|
if (cachedBundle) {
|
||||||
|
console.log(`[PageLoading] 字体分包已加载: ${bundleName}`);
|
||||||
|
this._updateProgress(0.82);
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateStatusLabel('正在加载字体资源...');
|
||||||
|
this._updateProgress(0.8);
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
assetManager.loadBundle(bundleName, (err: Error | null, bundle: AssetManager.Bundle | null) => {
|
||||||
|
if (err || !bundle) {
|
||||||
|
console.error(`[PageLoading] 字体分包加载失败: ${bundleName}`, err);
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[PageLoading] 字体分包加载完成: ${bundleName}`);
|
||||||
|
this._updateProgress(0.82);
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用服务端通关进度同步本地进度
|
* 用服务端通关进度同步本地进度
|
||||||
* 1. 根据 completedLevelIds 标记已通关关卡
|
* 1. 根据 completedLevelIds 标记已通关关卡
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
"ver": "1.2.0",
|
"ver": "1.2.0",
|
||||||
"importer": "directory",
|
"importer": "directory",
|
||||||
"imported": true,
|
"imported": true,
|
||||||
"uuid": "90eed50e-b353-46da-9510-b79d6628f187",
|
"uuid": "fc1f44af-699f-467c-ba2d-f54994551c4d",
|
||||||
"files": [],
|
"files": [],
|
||||||
"subMetas": {},
|
"subMetas": {},
|
||||||
"userData": {}
|
"userData": {
|
||||||
|
"isBundle": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2578,8 +2578,8 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 42.255859375,
|
"width": 100,
|
||||||
"height": 50.4
|
"height": 126
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -2609,22 +2609,25 @@
|
|||||||
"_dstBlendFactor": 4,
|
"_dstBlendFactor": 4,
|
||||||
"_color": {
|
"_color": {
|
||||||
"__type__": "cc.Color",
|
"__type__": "cc.Color",
|
||||||
"r": 255,
|
"r": 75,
|
||||||
"g": 255,
|
"g": 75,
|
||||||
"b": 255,
|
"b": 75,
|
||||||
"a": 255
|
"a": 255
|
||||||
},
|
},
|
||||||
"_string": "label",
|
"_string": "叫",
|
||||||
"_horizontalAlign": 1,
|
"_horizontalAlign": 1,
|
||||||
"_verticalAlign": 1,
|
"_verticalAlign": 1,
|
||||||
"_actualFontSize": 20,
|
"_actualFontSize": 100,
|
||||||
"_fontSize": 20,
|
"_fontSize": 100,
|
||||||
"_fontFamily": "Arial",
|
"_fontFamily": "Arial",
|
||||||
"_lineHeight": 40,
|
"_lineHeight": 100,
|
||||||
"_overflow": 0,
|
"_overflow": 0,
|
||||||
"_enableWrapText": true,
|
"_enableWrapText": true,
|
||||||
"_font": null,
|
"_font": {
|
||||||
"_isSystemFontUsed": true,
|
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
|
||||||
|
"__expectedType__": "cc.TTFFont"
|
||||||
|
},
|
||||||
|
"_isSystemFontUsed": false,
|
||||||
"_spacingX": 0,
|
"_spacingX": 0,
|
||||||
"_isItalic": false,
|
"_isItalic": false,
|
||||||
"_isBold": false,
|
"_isBold": false,
|
||||||
@@ -4588,7 +4591,7 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": -50.312,
|
"x": -33.411,
|
||||||
"y": -660.724,
|
"y": -660.724,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
@@ -4692,7 +4695,7 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": -316.3829999999999,
|
"x": -340.505,
|
||||||
"y": 0,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
@@ -4733,7 +4736,7 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 500,
|
"width": 464.5749969482422,
|
||||||
"height": 500
|
"height": 500
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
@@ -4745,7 +4748,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "183qHdLEFC1ZokLeOAXS4v"
|
"fileId": "22LYNUfANKvbDg/dHkSUwV"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
@@ -4775,7 +4778,7 @@
|
|||||||
},
|
},
|
||||||
"_type": 0,
|
"_type": 0,
|
||||||
"_fillType": 0,
|
"_fillType": 0,
|
||||||
"_sizeMode": 2,
|
"_sizeMode": 0,
|
||||||
"_fillCenter": {
|
"_fillCenter": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
"x": 0,
|
"x": 0,
|
||||||
@@ -4790,7 +4793,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "91zu1RBf9Bt4h8bGbBCEf+"
|
"fileId": "c7gLLXlKVCfYCUhQ+jYwy8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
@@ -4800,7 +4803,7 @@
|
|||||||
"asset": {
|
"asset": {
|
||||||
"__id__": 0
|
"__id__": 0
|
||||||
},
|
},
|
||||||
"fileId": "4659kCML1J8pPiZ6SwLi2f",
|
"fileId": "2b3ocDGTBC97mggTD6nDXO",
|
||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null,
|
"targetOverrides": null,
|
||||||
"nestedPrefabInstanceRoots": null
|
"nestedPrefabInstanceRoots": null
|
||||||
@@ -4828,7 +4831,7 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": -156.798,
|
"x": 104.254,
|
||||||
"y": 0,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
@@ -4869,7 +4872,7 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 183.05624389648438,
|
"width": 700,
|
||||||
"height": 63
|
"height": 63
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
@@ -4881,7 +4884,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "5330d+6qxIN6lu5Q4FQBz1"
|
"fileId": "b0+JAH+KJFTaX6sbxsby5I"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Label",
|
"__type__": "cc.Label",
|
||||||
@@ -4905,14 +4908,14 @@
|
|||||||
"b": 65,
|
"b": 65,
|
||||||
"a": 255
|
"a": 255
|
||||||
},
|
},
|
||||||
"_string": "提示 1:",
|
"_string": "提示 1:待解锁",
|
||||||
"_horizontalAlign": 0,
|
"_horizontalAlign": 0,
|
||||||
"_verticalAlign": 1,
|
"_verticalAlign": 1,
|
||||||
"_actualFontSize": 50,
|
"_actualFontSize": 51,
|
||||||
"_fontSize": 50,
|
"_fontSize": 50,
|
||||||
"_fontFamily": "Arial",
|
"_fontFamily": "Arial",
|
||||||
"_lineHeight": 50,
|
"_lineHeight": 50,
|
||||||
"_overflow": 0,
|
"_overflow": 2,
|
||||||
"_enableWrapText": true,
|
"_enableWrapText": true,
|
||||||
"_font": {
|
"_font": {
|
||||||
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
|
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
|
||||||
@@ -4952,7 +4955,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "78Pcn0jMBHN424ZHHdibDV"
|
"fileId": "c7NNDKisZMy5Fsvl8wdC2E"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
@@ -4962,7 +4965,7 @@
|
|||||||
"asset": {
|
"asset": {
|
||||||
"__id__": 0
|
"__id__": 0
|
||||||
},
|
},
|
||||||
"fileId": "8czInr32FC34vOGyZgOJl/",
|
"fileId": "664aZaWkNEM5bDQ63gCwvW",
|
||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null,
|
"targetOverrides": null,
|
||||||
"nestedPrefabInstanceRoots": null
|
"nestedPrefabInstanceRoots": null
|
||||||
@@ -4993,7 +4996,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "37D6b3G0lPlIkr1GzIzW7S"
|
"fileId": "b5JmT+IIBO2oALlaZ3XK0f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
@@ -5003,7 +5006,7 @@
|
|||||||
"asset": {
|
"asset": {
|
||||||
"__id__": 0
|
"__id__": 0
|
||||||
},
|
},
|
||||||
"fileId": "c16/HqrHNEsam62hN4pFaY",
|
"fileId": "e2UM2IG6dA9r68xaXEUXjU",
|
||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null,
|
"targetOverrides": null,
|
||||||
"nestedPrefabInstanceRoots": null
|
"nestedPrefabInstanceRoots": null
|
||||||
@@ -5085,7 +5088,7 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": -318.81899999999996,
|
"x": -340.505,
|
||||||
"y": 0,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
@@ -5098,8 +5101,8 @@
|
|||||||
},
|
},
|
||||||
"_lscale": {
|
"_lscale": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": 0.517,
|
"x": 0.2,
|
||||||
"y": 0.517,
|
"y": 0.2,
|
||||||
"z": 0.517
|
"z": 0.517
|
||||||
},
|
},
|
||||||
"_mobility": 0,
|
"_mobility": 0,
|
||||||
@@ -5126,8 +5129,8 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 153,
|
"width": 464.5749969482422,
|
||||||
"height": 176
|
"height": 500
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -5138,7 +5141,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "24Muu32rZCxahfvEnv6Lh7"
|
"fileId": "a3hcMCJxVH7qdhcPKmLrrR"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
@@ -5176,14 +5179,14 @@
|
|||||||
},
|
},
|
||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": false,
|
||||||
"_useGrayscale": false,
|
"_useGrayscale": false,
|
||||||
"_atlas": null,
|
"_atlas": null,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "cdz0mOL0lDGqaZ0Fj4ZhzU"
|
"fileId": "66jwZ+mAlCxrMD28cf4lu8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
@@ -5193,7 +5196,7 @@
|
|||||||
"asset": {
|
"asset": {
|
||||||
"__id__": 0
|
"__id__": 0
|
||||||
},
|
},
|
||||||
"fileId": "ddvQFKgzlIN6PN2OGZybmB",
|
"fileId": "a97AobrwtDRYZeDUxWwe9q",
|
||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null,
|
"targetOverrides": null,
|
||||||
"nestedPrefabInstanceRoots": null
|
"nestedPrefabInstanceRoots": null
|
||||||
@@ -5221,7 +5224,7 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": -70.3203125,
|
"x": 104.254,
|
||||||
"y": 0,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
@@ -5262,7 +5265,7 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 342.4312438964844,
|
"width": 700,
|
||||||
"height": 63
|
"height": 63
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
@@ -5301,11 +5304,11 @@
|
|||||||
"_string": "提示 2:待解锁",
|
"_string": "提示 2:待解锁",
|
||||||
"_horizontalAlign": 0,
|
"_horizontalAlign": 0,
|
||||||
"_verticalAlign": 1,
|
"_verticalAlign": 1,
|
||||||
"_actualFontSize": 50,
|
"_actualFontSize": 51,
|
||||||
"_fontSize": 50,
|
"_fontSize": 50,
|
||||||
"_fontFamily": "Arial",
|
"_fontFamily": "Arial",
|
||||||
"_lineHeight": 50,
|
"_lineHeight": 50,
|
||||||
"_overflow": 0,
|
"_overflow": 2,
|
||||||
"_enableWrapText": true,
|
"_enableWrapText": true,
|
||||||
"_font": {
|
"_font": {
|
||||||
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
|
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
|
||||||
@@ -5478,8 +5481,8 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": -314.4599999999999,
|
"x": -340.505,
|
||||||
"y": 1.1368683772161603e-13,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"_lrot": {
|
"_lrot": {
|
||||||
@@ -5491,8 +5494,8 @@
|
|||||||
},
|
},
|
||||||
"_lscale": {
|
"_lscale": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": 0.517,
|
"x": 0.2,
|
||||||
"y": 0.517,
|
"y": 0.2,
|
||||||
"z": 0.517
|
"z": 0.517
|
||||||
},
|
},
|
||||||
"_mobility": 0,
|
"_mobility": 0,
|
||||||
@@ -5519,8 +5522,8 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 153,
|
"width": 464.5749969482422,
|
||||||
"height": 176
|
"height": 500
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -5531,7 +5534,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "b1wA0cLKxDJ4h7bFZLjZL4"
|
"fileId": "50azgTm7pCALtYSMaQYyyF"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
@@ -5569,14 +5572,14 @@
|
|||||||
},
|
},
|
||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": false,
|
||||||
"_useGrayscale": false,
|
"_useGrayscale": false,
|
||||||
"_atlas": null,
|
"_atlas": null,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "26fAcMh7lAaZJs8caeOT/E"
|
"fileId": "006v9WAKhG/JqM9MRgJiRS"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
@@ -5586,7 +5589,7 @@
|
|||||||
"asset": {
|
"asset": {
|
||||||
"__id__": 0
|
"__id__": 0
|
||||||
},
|
},
|
||||||
"fileId": "2bZ2Ap1yhIhbzJDDtNSerr",
|
"fileId": "ad9JJ1JLNHtpnjMaprKGN7",
|
||||||
"instance": null,
|
"instance": null,
|
||||||
"targetOverrides": null,
|
"targetOverrides": null,
|
||||||
"nestedPrefabInstanceRoots": null
|
"nestedPrefabInstanceRoots": null
|
||||||
@@ -5614,8 +5617,8 @@
|
|||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
"x": -70.3203125,
|
"x": 104.254,
|
||||||
"y": 1.1368683772161603e-13,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"_lrot": {
|
"_lrot": {
|
||||||
@@ -5655,7 +5658,7 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 343.4078063964844,
|
"width": 700,
|
||||||
"height": 63
|
"height": 63
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
@@ -5694,11 +5697,11 @@
|
|||||||
"_string": "提示 3:待解锁",
|
"_string": "提示 3:待解锁",
|
||||||
"_horizontalAlign": 0,
|
"_horizontalAlign": 0,
|
||||||
"_verticalAlign": 1,
|
"_verticalAlign": 1,
|
||||||
"_actualFontSize": 50,
|
"_actualFontSize": 51,
|
||||||
"_fontSize": 50,
|
"_fontSize": 50,
|
||||||
"_fontFamily": "Arial",
|
"_fontFamily": "Arial",
|
||||||
"_lineHeight": 50,
|
"_lineHeight": 50,
|
||||||
"_overflow": 0,
|
"_overflow": 2,
|
||||||
"_enableWrapText": true,
|
"_enableWrapText": true,
|
||||||
"_font": {
|
"_font": {
|
||||||
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
|
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
|
||||||
@@ -5872,10 +5875,10 @@
|
|||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 244
|
"__id__": 244
|
||||||
},
|
},
|
||||||
"_alignFlags": 4,
|
"_alignFlags": 44,
|
||||||
"_target": null,
|
"_target": null,
|
||||||
"_left": 0,
|
"_left": 106.589,
|
||||||
"_right": 0,
|
"_right": 173.411,
|
||||||
"_top": 0,
|
"_top": 0,
|
||||||
"_bottom": 249.27599999999995,
|
"_bottom": 249.27599999999995,
|
||||||
"_horizontalCenter": 0,
|
"_horizontalCenter": 0,
|
||||||
@@ -5886,7 +5889,7 @@
|
|||||||
"_isAbsBottom": true,
|
"_isAbsBottom": true,
|
||||||
"_isAbsHorizontalCenter": true,
|
"_isAbsHorizontalCenter": true,
|
||||||
"_isAbsVerticalCenter": true,
|
"_isAbsVerticalCenter": true,
|
||||||
"_originalWidth": 0,
|
"_originalWidth": 800,
|
||||||
"_originalHeight": 0,
|
"_originalHeight": 0,
|
||||||
"_alignMode": 2,
|
"_alignMode": 2,
|
||||||
"_lockFlags": 0,
|
"_lockFlags": 0,
|
||||||
@@ -7933,6 +7936,9 @@
|
|||||||
"liveLabel": {
|
"liveLabel": {
|
||||||
"__id__": 158
|
"__id__": 158
|
||||||
},
|
},
|
||||||
|
"titleLevelLabel": {
|
||||||
|
"__id__": 14
|
||||||
|
},
|
||||||
"currentLevelIndex": 0,
|
"currentLevelIndex": 0,
|
||||||
"clickAudio": {
|
"clickAudio": {
|
||||||
"__uuid__": "a68a6314-fb7c-48a9-bd6c-0a65ef665d50",
|
"__uuid__": "a68a6314-fb7c-48a9-bd6c-0a65ef665d50",
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ export class PageLevel extends BaseView {
|
|||||||
/** 默认体力上限,服务端未返回 max 时使用 */
|
/** 默认体力上限,服务端未返回 max 时使用 */
|
||||||
private static readonly DEFAULT_STAMINA_MAX = 50;
|
private static readonly DEFAULT_STAMINA_MAX = 50;
|
||||||
|
|
||||||
|
/** 答案正确后展示包袱答案的停留时间 */
|
||||||
|
private static readonly PASS_MODAL_DELAY_MS = 2000;
|
||||||
|
|
||||||
|
/** 答案错误后清空输入的延迟,给失败音效和错误答案留出反馈时间 */
|
||||||
|
private static readonly CLEAR_INPUT_DELAY_MS = 500;
|
||||||
|
|
||||||
// ========== 节点引用 ==========
|
// ========== 节点引用 ==========
|
||||||
@property(Node)
|
@property(Node)
|
||||||
inputLayout: Node | null = null;
|
inputLayout: Node | null = null;
|
||||||
@@ -80,6 +86,10 @@ export class PageLevel extends BaseView {
|
|||||||
@property(Label)
|
@property(Label)
|
||||||
liveLabel: Label | null = null;
|
liveLabel: Label | null = null;
|
||||||
|
|
||||||
|
/** 关卡标题标签,显示为“第 N 关” */
|
||||||
|
@property(Label)
|
||||||
|
titleLevelLabel: Label | null = null;
|
||||||
|
|
||||||
// ========== 配置属性 ==========
|
// ========== 配置属性 ==========
|
||||||
@property({
|
@property({
|
||||||
min: 0,
|
min: 0,
|
||||||
@@ -263,6 +273,9 @@ export class PageLevel extends BaseView {
|
|||||||
this.currentLevelIndex,
|
this.currentLevelIndex,
|
||||||
{
|
{
|
||||||
answer: enterData.answer,
|
answer: enterData.answer,
|
||||||
|
image1Description: enterData.image1Description,
|
||||||
|
image2Description: enterData.image2Description,
|
||||||
|
punchline: enterData.punchline,
|
||||||
hint1: enterData.hint1,
|
hint1: enterData.hint1,
|
||||||
hint2: enterData.hint2,
|
hint2: enterData.hint2,
|
||||||
hint3: enterData.hint3,
|
hint3: enterData.hint3,
|
||||||
@@ -308,8 +321,11 @@ export class PageLevel extends BaseView {
|
|||||||
// 设置图片描述
|
// 设置图片描述
|
||||||
this.setImageDescriptions(config.image1Description, config.image2Description);
|
this.setImageDescriptions(config.image1Description, config.image2Description);
|
||||||
|
|
||||||
// 隐藏谐音梗说明(通关后才显示)
|
// 设置关卡标题
|
||||||
this.setPunchline(null);
|
this.updateTitleLevelLabel();
|
||||||
|
|
||||||
|
// 隐藏包袱答案,通关后再按 punchline 展示
|
||||||
|
this.hidePunchline();
|
||||||
|
|
||||||
// 设置线索1(默认解锁,如果有的话)
|
// 设置线索1(默认解锁,如果有的话)
|
||||||
if (config.clue1) {
|
if (config.clue1) {
|
||||||
@@ -381,6 +397,7 @@ export class PageLevel extends BaseView {
|
|||||||
editBox.placeholder = '';
|
editBox.placeholder = '';
|
||||||
editBox.maxLength = chars.length;
|
editBox.maxLength = chars.length;
|
||||||
editBox.string = '';
|
editBox.string = '';
|
||||||
|
editBox.node.on(EditBox.EventType.EDITING_DID_BEGAN, this.onInputEditingBegan, this);
|
||||||
editBox.node.on(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
|
editBox.node.on(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
|
||||||
editBox.node.on(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
|
editBox.node.on(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
|
||||||
}
|
}
|
||||||
@@ -404,6 +421,7 @@ export class PageLevel extends BaseView {
|
|||||||
if (node.isValid) {
|
if (node.isValid) {
|
||||||
const editBox = node.getComponent(EditBox);
|
const editBox = node.getComponent(EditBox);
|
||||||
if (editBox) {
|
if (editBox) {
|
||||||
|
editBox.node.off(EditBox.EventType.EDITING_DID_BEGAN, this.onInputEditingBegan, this);
|
||||||
editBox.node.off(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
|
editBox.node.off(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
|
||||||
editBox.node.off(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
|
editBox.node.off(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
|
||||||
editBox.string = '';
|
editBox.string = '';
|
||||||
@@ -457,42 +475,58 @@ export class PageLevel extends BaseView {
|
|||||||
// ========== EditBox 事件回调 ==========
|
// ========== EditBox 事件回调 ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入框文本变化回调
|
* 输入框开始编辑时,把当前所有格子的内容合并到当前输入框里
|
||||||
*/
|
*/
|
||||||
private onInputTextChanged(editBox: EditBox): void {
|
private onInputEditingBegan(editBox: EditBox): void {
|
||||||
if (this._isSyncingInputText) return;
|
if (this._isSyncingInputText) return;
|
||||||
|
|
||||||
const inputIndex = this._inputNodes.findIndex(node => node === editBox.node);
|
const inputIndex = this._inputNodes.findIndex(node => node === editBox.node);
|
||||||
if (inputIndex < 0) return;
|
if (inputIndex < 0) return;
|
||||||
|
|
||||||
this.distributeInputText(inputIndex, editBox.string);
|
const answer = this.getAnswer();
|
||||||
this.tryAutoSubmitAnswer();
|
this._isSyncingInputText = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (let i = 0; i < this._inputNodes.length; i++) {
|
||||||
|
const itemEditBox = this._inputNodes[i].getComponent(EditBox);
|
||||||
|
if (itemEditBox) {
|
||||||
|
itemEditBox.string = i === inputIndex ? answer : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this._isSyncingInputText = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入框文本变化回调
|
||||||
|
*/
|
||||||
|
private onInputTextChanged(_editBox: EditBox): void {
|
||||||
|
this._lastAutoSubmittedAnswer = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入框编辑结束回调
|
* 输入框编辑结束回调
|
||||||
*/
|
*/
|
||||||
private onInputEditingEnded(_editBox: EditBox): void {
|
private onInputEditingEnded(editBox: EditBox): void {
|
||||||
console.log('[PageLevel] 输入编辑结束');
|
if (this._isSyncingInputText) return;
|
||||||
|
|
||||||
|
const inputIndex = this._inputNodes.findIndex(node => node === editBox.node);
|
||||||
|
if (inputIndex < 0) return;
|
||||||
|
|
||||||
|
this.distributeInputText(editBox.string);
|
||||||
|
this.tryAutoSubmitAnswer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private distributeInputText(startIndex: number, text: string): void {
|
private distributeInputText(text: string): void {
|
||||||
const chars = Array.from(text);
|
const chars = Array.from(text);
|
||||||
this._isSyncingInputText = true;
|
this._isSyncingInputText = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (chars.length <= 1) {
|
for (let i = 0; i < this._inputNodes.length; i++) {
|
||||||
const editBox = this._inputNodes[startIndex]?.getComponent(EditBox);
|
|
||||||
if (editBox) {
|
|
||||||
editBox.string = chars[0] ?? '';
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = startIndex; i < this._inputNodes.length; i++) {
|
|
||||||
const editBox = this._inputNodes[i].getComponent(EditBox);
|
const editBox = this._inputNodes[i].getComponent(EditBox);
|
||||||
if (editBox) {
|
if (editBox) {
|
||||||
editBox.string = chars[i - startIndex] ?? '';
|
editBox.string = chars[i] ?? '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -500,6 +534,22 @@ export class PageLevel extends BaseView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private clearInputText(): void {
|
||||||
|
this._isSyncingInputText = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const node of this._inputNodes) {
|
||||||
|
const editBox = node.getComponent(EditBox);
|
||||||
|
if (editBox) {
|
||||||
|
editBox.string = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._lastAutoSubmittedAnswer = '';
|
||||||
|
} finally {
|
||||||
|
this._isSyncingInputText = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private tryAutoSubmitAnswer(): void {
|
private tryAutoSubmitAnswer(): void {
|
||||||
if (!this._currentConfig || this._isTransitioning) return;
|
if (!this._currentConfig || this._isTransitioning) return;
|
||||||
|
|
||||||
@@ -575,20 +625,20 @@ export class PageLevel extends BaseView {
|
|||||||
const tipsItem = this.getTipsItem(index);
|
const tipsItem = this.getTipsItem(index);
|
||||||
if (!tipsItem) return;
|
if (!tipsItem) return;
|
||||||
|
|
||||||
// 查找 TipsLabel 节点:Content -> TipsLabel
|
const label = this.getTipsLabel(tipsItem);
|
||||||
const contentNode = tipsItem.getChildByName('Content');
|
|
||||||
if (!contentNode) return;
|
|
||||||
|
|
||||||
const tipsLabelNode = contentNode.getChildByName('TipsLabel');
|
|
||||||
if (!tipsLabelNode) return;
|
|
||||||
|
|
||||||
const label = tipsLabelNode.getComponent(Label);
|
|
||||||
if (label) {
|
if (label) {
|
||||||
label.string = `提示 ${index}: ${content}`;
|
label.string = `提示${index}:${content}`;
|
||||||
console.log(`[PageLevel] 设置线索${index}: ${content}`);
|
console.log(`[PageLevel] 设置线索${index}: ${content}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getTipsLabel(tipsItem: Node): Label | null {
|
||||||
|
const directLabel = tipsItem.getChildByName('TipsLabel')?.getComponent(Label);
|
||||||
|
if (directLabel) return directLabel;
|
||||||
|
|
||||||
|
return tipsItem.getChildByName('Content')?.getChildByName('TipsLabel')?.getComponent(Label) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示线索
|
* 显示线索
|
||||||
*/
|
*/
|
||||||
@@ -748,6 +798,12 @@ export class PageLevel extends BaseView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateTitleLevelLabel(): void {
|
||||||
|
if (!this.titleLevelLabel) return;
|
||||||
|
|
||||||
|
this.titleLevelLabel.string = `第 ${this.currentLevelIndex + 1} 关`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置谐音梗说明(通关后逐字展示,未通关时传 null 隐藏)
|
* 设置谐音梗说明(通关后逐字展示,未通关时传 null 隐藏)
|
||||||
*/
|
*/
|
||||||
@@ -756,8 +812,7 @@ export class PageLevel extends BaseView {
|
|||||||
|
|
||||||
const chars = Array.from(punchline ?? '');
|
const chars = Array.from(punchline ?? '');
|
||||||
if (chars.length === 0) {
|
if (chars.length === 0) {
|
||||||
this.punchLayout.active = false;
|
this.hidePunchline();
|
||||||
this.clearPunchBlocks();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -768,6 +823,7 @@ export class PageLevel extends BaseView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.clearPunchBlocks();
|
this.clearPunchBlocks();
|
||||||
|
this.removeUnexpectedPunchLayoutChildren(template);
|
||||||
this.punchLayout.active = true;
|
this.punchLayout.active = true;
|
||||||
|
|
||||||
for (let i = 0; i < chars.length; i++) {
|
for (let i = 0; i < chars.length; i++) {
|
||||||
@@ -778,7 +834,12 @@ export class PageLevel extends BaseView {
|
|||||||
|
|
||||||
const label = this.getPunchBlockLabel(blockNode);
|
const label = this.getPunchBlockLabel(blockNode);
|
||||||
if (label) {
|
if (label) {
|
||||||
|
label.node.active = true;
|
||||||
|
label.enabled = true;
|
||||||
label.string = chars[i];
|
label.string = chars[i];
|
||||||
|
console.log(`[PageLevel] 设置包袱块${i + 1}: ${chars[i]}`);
|
||||||
|
} else {
|
||||||
|
console.warn(`[PageLevel] 包袱块${i + 1} 未找到 Label 组件`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockNode.parent !== this.punchLayout) {
|
if (blockNode.parent !== this.punchLayout) {
|
||||||
@@ -801,6 +862,7 @@ export class PageLevel extends BaseView {
|
|||||||
if (node === template) {
|
if (node === template) {
|
||||||
node.active = false;
|
node.active = false;
|
||||||
} else {
|
} else {
|
||||||
|
node.removeFromParent();
|
||||||
node.destroy();
|
node.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -808,6 +870,42 @@ export class PageLevel extends BaseView {
|
|||||||
this._punchBlockNodes = [];
|
this._punchBlockNodes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private hidePunchline(): void {
|
||||||
|
if (!this.punchLayout) return;
|
||||||
|
|
||||||
|
const template = this.getPunchBlockTemplateNode();
|
||||||
|
if (!template) {
|
||||||
|
this.punchLayout.active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearPunchBlocks();
|
||||||
|
this.removeUnexpectedPunchLayoutChildren(template);
|
||||||
|
this.punchLayout.active = false;
|
||||||
|
template.active = false;
|
||||||
|
template.name = 'block';
|
||||||
|
|
||||||
|
const label = this.getPunchBlockLabel(template);
|
||||||
|
if (label) {
|
||||||
|
label.node.active = true;
|
||||||
|
label.enabled = true;
|
||||||
|
label.string = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
this._punchBlockNodes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private removeUnexpectedPunchLayoutChildren(template: Node): void {
|
||||||
|
if (!this.punchLayout) return;
|
||||||
|
|
||||||
|
for (const child of [...this.punchLayout.children]) {
|
||||||
|
if (child !== template) {
|
||||||
|
child.removeFromParent();
|
||||||
|
child.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private getPunchBlockTemplateNode(): Node | null {
|
private getPunchBlockTemplateNode(): Node | null {
|
||||||
if (this._punchBlockTemplateNode?.isValid) return this._punchBlockTemplateNode;
|
if (this._punchBlockTemplateNode?.isValid) return this._punchBlockTemplateNode;
|
||||||
|
|
||||||
@@ -816,7 +914,19 @@ export class PageLevel extends BaseView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getPunchBlockLabel(blockNode: Node): Label | null {
|
private getPunchBlockLabel(blockNode: Node): Label | null {
|
||||||
return blockNode.getChildByName('Label')?.getComponent(Label) ?? blockNode.getComponent(Label);
|
return this.findLabelInNode(blockNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private findLabelInNode(node: Node): Label | null {
|
||||||
|
const label = node.getComponent(Label);
|
||||||
|
if (label) return label;
|
||||||
|
|
||||||
|
for (const child of node.children) {
|
||||||
|
const childLabel = this.findLabelInNode(child);
|
||||||
|
if (childLabel) return childLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 音效相关方法 ==========
|
// ========== 音效相关方法 ==========
|
||||||
@@ -1023,31 +1133,39 @@ export class PageLevel extends BaseView {
|
|||||||
// 播放成功音效
|
// 播放成功音效
|
||||||
this.playSuccessSound();
|
this.playSuccessSound();
|
||||||
|
|
||||||
// 通关后展示谐音梗说明
|
// 通关后根据 punchline 字数重建包袱答案块
|
||||||
if (this._currentConfig?.punchline) {
|
this.setPunchline(this._currentConfig?.punchline ?? null);
|
||||||
this.setPunchline(this._currentConfig.punchline);
|
|
||||||
}
|
|
||||||
|
|
||||||
const levelId = this._currentConfig?.id ?? '';
|
const levelId = this._currentConfig?.id ?? '';
|
||||||
const timeSpent = Math.max(0, Math.round((Date.now() - this._levelStartTime) / 1000));
|
const timeSpent = Math.max(0, Math.round((Date.now() - this._levelStartTime) / 1000));
|
||||||
|
|
||||||
if (!this._isShareMode) {
|
this.reportLevelCompleted(levelId, timeSpent);
|
||||||
// 上报通关耗时
|
await this.delay(PageLevel.PASS_MODAL_DELAY_MS);
|
||||||
const result = await StaminaManager.instance.completeLevel(levelId, timeSpent);
|
|
||||||
if (result) {
|
|
||||||
console.log(`[PageLevel] 通关上报成功,首次通关: ${result.firstClear}`);
|
|
||||||
}
|
|
||||||
// 标记关卡为已通关(本地缓存)
|
|
||||||
LevelDataManager.instance.markLevelCompleted(this.currentLevelIndex);
|
|
||||||
} else {
|
|
||||||
// fire-and-forget: errors are logged inside reportLevelProgress
|
|
||||||
void ShareManager.instance.reportLevelProgress(levelId, true, timeSpent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示通关弹窗
|
// 显示通关弹窗
|
||||||
this._showPassModal();
|
this._showPassModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private reportLevelCompleted(levelId: string, timeSpent: number): void {
|
||||||
|
if (!this._isShareMode) {
|
||||||
|
// 标记关卡为已通关(本地缓存),通关上报并行执行,不阻塞包袱展示节奏
|
||||||
|
LevelDataManager.instance.markLevelCompleted(this.currentLevelIndex);
|
||||||
|
void StaminaManager.instance.completeLevel(levelId, timeSpent).then((result) => {
|
||||||
|
if (result) {
|
||||||
|
console.log(`[PageLevel] 通关上报成功,首次通关: ${result.firstClear}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire-and-forget: errors are logged inside reportLevelProgress
|
||||||
|
void ShareManager.instance.reportLevelProgress(levelId, true, timeSpent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private delay(ms: number): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示通关弹窗
|
* 显示通关弹窗
|
||||||
* 将弹窗添加到 Canvas 根节点下(而非 PageLevel 子节点)
|
* 将弹窗添加到 Canvas 根节点下(而非 PageLevel 子节点)
|
||||||
@@ -1125,6 +1243,13 @@ export class PageLevel extends BaseView {
|
|||||||
|
|
||||||
// 显示 Toast 提示
|
// 显示 Toast 提示
|
||||||
ToastManager.show('答案错误,再试试吧!');
|
ToastManager.show('答案错误,再试试吧!');
|
||||||
|
|
||||||
|
// 输入识别失败或答案错误后延迟清空,避免错误内容瞬间消失
|
||||||
|
void this.delay(PageLevel.CLEAR_INPUT_DELAY_MS).then(() => {
|
||||||
|
if (!this._isTransitioning) {
|
||||||
|
this.clearInputText();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ export class LevelDataManager {
|
|||||||
/**
|
/**
|
||||||
* 用 enter 接口返回的数据更新运行时关卡配置(填充答案和线索)
|
* 用 enter 接口返回的数据更新运行时关卡配置(填充答案和线索)
|
||||||
*/
|
*/
|
||||||
updateLevelDetails(index: number, details: { answer: string; hint1: string | null; hint2: string | null; hint3: string | null }): void {
|
updateLevelDetails(index: number, details: { answer: string; image1Description: string | null; image2Description: string | null; punchline: string | null; hint1: string | null; hint2: string | null; hint3: string | null }): void {
|
||||||
const config = this._levelConfigs.get(index);
|
const config = this._levelConfigs.get(index);
|
||||||
if (!config) {
|
if (!config) {
|
||||||
console.warn(`[LevelDataManager] 关卡 ${index} 配置不存在,无法更新详情`);
|
console.warn(`[LevelDataManager] 关卡 ${index} 配置不存在,无法更新详情`);
|
||||||
@@ -277,6 +277,9 @@ export class LevelDataManager {
|
|||||||
this._levelConfigs.set(index, {
|
this._levelConfigs.set(index, {
|
||||||
...config,
|
...config,
|
||||||
answer: details.answer,
|
answer: details.answer,
|
||||||
|
image1Description: details.image1Description ?? config.image1Description,
|
||||||
|
image2Description: details.image2Description ?? config.image2Description,
|
||||||
|
punchline: details.punchline ?? config.punchline,
|
||||||
clue1: details.hint1 ?? null,
|
clue1: details.hint1 ?? null,
|
||||||
clue2: details.hint2 ?? null,
|
clue2: details.hint2 ?? null,
|
||||||
clue3: details.hint3 ?? null,
|
clue3: details.hint3 ?? null,
|
||||||
|
|||||||
@@ -1,3 +1,39 @@
|
|||||||
{
|
{
|
||||||
"__version__": "1.3.9"
|
"__version__": "1.3.9",
|
||||||
|
"bundleConfig": {
|
||||||
|
"custom": {
|
||||||
|
"default": {
|
||||||
|
"displayName": "i18n:builder.asset_bundle.defaultConfig",
|
||||||
|
"configs": {
|
||||||
|
"native": {
|
||||||
|
"preferredOptions": {
|
||||||
|
"isRemote": false,
|
||||||
|
"compressionType": "merge_dep"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"preferredOptions": {
|
||||||
|
"isRemote": false,
|
||||||
|
"compressionType": "merge_dep"
|
||||||
|
},
|
||||||
|
"fallbackOptions": {
|
||||||
|
"compressionType": "merge_dep"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"miniGame": {
|
||||||
|
"fallbackOptions": {
|
||||||
|
"isRemote": false,
|
||||||
|
"compressionType": "merge_dep"
|
||||||
|
},
|
||||||
|
"configMode": "overwrite",
|
||||||
|
"overwriteSettings": {
|
||||||
|
"wechatgame": {
|
||||||
|
"compressionType": "subpackage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user