feat: 支持关卡详情页 UI

This commit is contained in:
richarjiang
2026-05-09 15:19:07 +08:00
parent 57c4f3d826
commit 99b2928589
13 changed files with 5547 additions and 239 deletions

View File

@@ -9471,6 +9471,36 @@
"titleLevelLabel": {
"__id__": 22
},
"bgNode": {
"__id__": 2
},
"pkBgNode": {
"__id__": 10
},
"titleLevelNode": {
"__id__": 18
},
"pkTitleLevelNode": {
"__id__": 32
},
"pkTitleLevelLabel": {
"__id__": 36
},
"liveNode": {
"__id__": 106
},
"pkLevelProgressNode": {
"__id__": 130
},
"pkLevelProgressLabel": {
"__id__": 140
},
"bottomLayoutNode": {
"__id__": 248
},
"pkNextLevelButton": {
"__id__": 364
},
"clickAudio": {
"__uuid__": "a68a6314-fb7c-48a9-bd6c-0a65ef665d50",
"__expectedType__": "cc.AudioClip"

View File

@@ -132,6 +132,46 @@ export class PageLevel extends BaseView {
@property(Label)
titleLevelLabel: Label | null = null;
/** 普通模式背景 */
@property(Node)
bgNode: Node | null = null;
/** 分享 / PK 模式背景 */
@property(Node)
pkBgNode: Node | null = null;
/** 普通模式标题容器 */
@property(Node)
titleLevelNode: Node | null = null;
/** 分享 / PK 模式标题容器 */
@property(Node)
pkTitleLevelNode: Node | null = null;
/** 分享 / PK 模式标题标签 */
@property(Label)
pkTitleLevelLabel: Label | null = null;
/** 普通模式体力区域容器 */
@property(Node)
liveNode: Node | null = null;
/** 分享 / PK 模式进度容器 */
@property(Node)
pkLevelProgressNode: Node | null = null;
/** 分享 / PK 模式进度标签 */
@property(Label)
pkLevelProgressLabel: Label | null = null;
/** 普通模式底部按钮区域 */
@property(Node)
bottomLayoutNode: Node | null = null;
/** 分享 / PK 模式底部下一题按钮 */
@property(Node)
pkNextLevelButton: Node | null = null;
// ========== 配置属性 ==========
@property(AudioClip)
clickAudio: AudioClip | null = null;
@@ -273,10 +313,12 @@ export class PageLevel extends BaseView {
}
}
this._refreshModeUI();
this.updateStaminaLabel();
this.initIconSetting();
this.initUnlockButtons();
this.initSubmitButton();
this.initPkNextLevelButton();
// 异步加载关卡资源并调用进入关卡接口,完成后启动倒计时
this._enterAndInitLevel().catch(err => {
@@ -289,8 +331,11 @@ export class PageLevel extends BaseView {
*/
onViewShow(): void {
console.log('[PageLevel] onViewShow');
this._refreshModeUI();
this.updateStaminaLabel();
this._startStaminaRecoverTimer();
if (!this._isShareMode) {
this._startStaminaRecoverTimer();
}
}
/**
@@ -319,6 +364,7 @@ export class PageLevel extends BaseView {
this.unLockTipsBtn?.off(Node.EventType.TOUCH_END);
this.addTimeBtn?.off(Node.EventType.TOUCH_END);
this.submitButton?.off(Node.EventType.TOUCH_END, this.onSubmitAnswer, this);
this.pkNextLevelButton?.off(Node.EventType.TOUCH_END, this.onPkNextLevelClick, this);
}
/**
@@ -428,6 +474,7 @@ export class PageLevel extends BaseView {
// 设置关卡标题
this.updateTitleLevelLabel();
this.updatePkLevelProgressLabel();
// 隐藏包袱答案,通关后再按 punchline 展示
this.hidePunchline();
@@ -853,6 +900,24 @@ export class PageLevel extends BaseView {
console.log('[PageLevel] 提交按钮事件已绑定');
}
private initPkNextLevelButton(): void {
if (!this.pkNextLevelButton) {
return;
}
this.pkNextLevelButton.on(Node.EventType.TOUCH_END, this.onPkNextLevelClick, this);
console.log('[PageLevel] PK 下一题按钮事件已绑定');
}
private onPkNextLevelClick(): void {
if (!this._isShareMode) {
return;
}
this.playClickSound();
void this.goToNextLevel();
}
/**
* 点击解锁线索顺序解锁先线索2再线索3全部解锁后切换为查看答案入口
*/
@@ -993,9 +1058,64 @@ export class PageLevel extends BaseView {
}
private updateTitleLevelLabel(): void {
if (!this.titleLevelLabel) return;
const titleText = `${this.getDisplayLevelNumber()}`;
this.titleLevelLabel.string = `${this.getDisplayLevelNumber()}`;
if (this.titleLevelLabel) {
this.titleLevelLabel.string = titleText;
}
if (this.pkTitleLevelLabel) {
this.pkTitleLevelLabel.string = titleText;
}
}
private updatePkLevelProgressLabel(): void {
if (!this.pkLevelProgressLabel) {
return;
}
if (!this._isShareMode) {
this.pkLevelProgressLabel.string = '';
return;
}
const totalLevels = ShareManager.instance.getShareLevelCount();
const currentIndex = this._shareLevelIndex + 1;
this.pkLevelProgressLabel.string = totalLevels > 0
? `${currentIndex}/${totalLevels}`
: `${currentIndex}`;
}
private _refreshModeUI(): void {
const isPkMode = this._isShareMode;
if (this.bgNode) {
this.bgNode.active = !isPkMode;
}
if (this.pkBgNode) {
this.pkBgNode.active = isPkMode;
}
if (this.titleLevelNode) {
this.titleLevelNode.active = !isPkMode;
}
if (this.pkTitleLevelNode) {
this.pkTitleLevelNode.active = isPkMode;
}
if (this.liveNode) {
this.liveNode.active = !isPkMode;
}
if (this.pkLevelProgressNode) {
this.pkLevelProgressNode.active = isPkMode;
}
if (this.bottomLayoutNode) {
this.bottomLayoutNode.active = !isPkMode;
}
if (this.pkNextLevelButton) {
this.pkNextLevelButton.active = isPkMode;
}
this.updateTitleLevelLabel();
this.updatePkLevelProgressLabel();
}
/**
@@ -1434,6 +1554,10 @@ export class PageLevel extends BaseView {
* 更新体力值显示(仅值变化时更新 UI
*/
private updateStaminaLabel(): void {
if (this._isShareMode) {
return;
}
if (this.liveLabel) {
const stamina = StaminaManager.instance.getStamina();
const maxStamina = this._getStaminaMax(stamina);
@@ -1449,6 +1573,10 @@ export class PageLevel extends BaseView {
* 启动体力恢复倒计时 UI
*/
private _startStaminaRecoverTimer(): void {
if (this._isShareMode) {
return;
}
this._stopStaminaRecoverTimer();
const stamina = StaminaManager.instance.getStamina();
@@ -1889,6 +2017,8 @@ export class PageLevel extends BaseView {
ViewManager.instance.replace('PageHome');
return;
}
this._refreshModeUI();
} else {
// 正常模式:使用 complete 返回的 nextLevel
if (!this._nextLevelData) {

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "dd4fde67-0616-40da-b10f-92d9babea9fa",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "dd4fde67-0616-40da-b10f-92d9babea9fa@6c48a",
"displayName": "Banner3",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "dd4fde67-0616-40da-b10f-92d9babea9fa",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "dd4fde67-0616-40da-b10f-92d9babea9fa@f9941",
"displayName": "Banner3",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 828,
"height": 156,
"rawWidth": 828,
"rawHeight": 156,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-414,
-78,
0,
414,
-78,
0,
-414,
78,
0,
414,
78,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
156,
828,
156,
0,
0,
828,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-414,
-78,
0
],
"maxPos": [
414,
78,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "dd4fde67-0616-40da-b10f-92d9babea9fa@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": true,
"fixAlphaTransparencyArtifacts": false,
"redirect": "dd4fde67-0616-40da-b10f-92d9babea9fa@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

View File

@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "4ff19088-ea59-400a-a9f3-2653dbc63acf",
"files": [
".jpg",
".json"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "4ff19088-ea59-400a-a9f3-2653dbc63acf@6c48a",
"displayName": "bg_purple",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "4ff19088-ea59-400a-a9f3-2653dbc63acf",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "4ff19088-ea59-400a-a9f3-2653dbc63acf@f9941",
"displayName": "bg_purple",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 1376,
"height": 3064,
"rawWidth": 1376,
"rawHeight": 3064,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-688,
-1532,
0,
688,
-1532,
0,
-688,
1532,
0,
688,
1532,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
3064,
1376,
3064,
0,
0,
1376,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-688,
-1532,
0
],
"maxPos": [
688,
1532,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "4ff19088-ea59-400a-a9f3-2653dbc63acf@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": false,
"redirect": "4ff19088-ea59-400a-a9f3-2653dbc63acf@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 KiB

View File

@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "b3eda29c-df8d-4d9a-8093-bd91f623da16",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "b3eda29c-df8d-4d9a-8093-bd91f623da16@6c48a",
"displayName": "ChampionPanel",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "b3eda29c-df8d-4d9a-8093-bd91f623da16",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "b3eda29c-df8d-4d9a-8093-bd91f623da16@f9941",
"displayName": "ChampionPanel",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 1471,
"height": 1156,
"rawWidth": 1471,
"rawHeight": 1156,
"borderTop": 443,
"borderBottom": 196,
"borderLeft": 193,
"borderRight": 400,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-735.5,
-578,
0,
735.5,
-578,
0,
-735.5,
578,
0,
735.5,
578,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
1156,
1471,
1156,
0,
0,
1471,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-735.5,
-578,
0
],
"maxPos": [
735.5,
578,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "b3eda29c-df8d-4d9a-8093-bd91f623da16@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": true,
"fixAlphaTransparencyArtifacts": false,
"redirect": "b3eda29c-df8d-4d9a-8093-bd91f623da16@6c48a"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,134 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "754d81bb-f9d1-440c-9e35-206886101438",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "754d81bb-f9d1-440c-9e35-206886101438@6c48a",
"displayName": "capsule",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "754d81bb-f9d1-440c-9e35-206886101438",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "754d81bb-f9d1-440c-9e35-206886101438@f9941",
"displayName": "capsule",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 468,
"height": 163,
"rawWidth": 468,
"rawHeight": 163,
"borderTop": 81,
"borderBottom": 81,
"borderLeft": 100,
"borderRight": 100,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-234,
-81.5,
0,
234,
-81.5,
0,
-234,
81.5,
0,
234,
81.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
163,
468,
163,
0,
0,
468,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-234,
-81.5,
0
],
"maxPos": [
234,
81.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "754d81bb-f9d1-440c-9e35-206886101438@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": true,
"fixAlphaTransparencyArtifacts": false,
"redirect": "754d81bb-f9d1-440c-9e35-206886101438@6c48a"
}
}