fix: 修复一系列 bug
This commit is contained in:
@@ -5507,7 +5507,7 @@
|
||||
"b": 0,
|
||||
"a": 255
|
||||
},
|
||||
"_string": "还差3题获得冷场小白2级",
|
||||
"_string": "还差3题,解锁新成就等级",
|
||||
"_horizontalAlign": 1,
|
||||
"_verticalAlign": 1,
|
||||
"_actualFontSize": 40,
|
||||
|
||||
@@ -61,7 +61,7 @@ export class PageHome extends BaseView {
|
||||
/** 是否正在播放体力消耗动画 */
|
||||
private _isAnimating: boolean = false;
|
||||
|
||||
/** 进度游标 0% 时的本地 X 坐标,使用 prefab 当前摆放位置作为起点 */
|
||||
/** 进度游标 0% 时的本地 X 坐标,根据 ProgressBar Bar 子节点的左端推导出来 */
|
||||
private _progressAnchorStartX: number | null = null;
|
||||
|
||||
/**
|
||||
@@ -363,11 +363,23 @@ export class PageHome extends BaseView {
|
||||
}
|
||||
|
||||
private _cacheProgressAnchorStartX(): void {
|
||||
if (this._progressAnchorStartX !== null || !this.progressAnchor) {
|
||||
if (this._progressAnchorStartX !== null || !this.titleProgressBar) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._progressAnchorStartX = this.progressAnchor.position.x;
|
||||
const barSprite = this.titleProgressBar.barSprite;
|
||||
if (!barSprite) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bar 节点 anchor 为 (0, 0.5),其本地 position.x 即为进度条可视左端。
|
||||
// ProgressBar 与 ProgressAnchor 共享同一父节点(TitleLevel),
|
||||
// 因此把 Bar 的本地 X 按 ProgressBar 自身的位移与缩放映射到父节点空间,
|
||||
// 才是真正的「0% 起点」。直接拿 progressAnchor.position.x 当起点会导致
|
||||
// 气泡始终被 prefab 摆放偏移量带跑(实测偏右 ~24px)。
|
||||
const progressBarNode = this.titleProgressBar.node;
|
||||
const barLocalX = barSprite.node.position.x;
|
||||
this._progressAnchorStartX = progressBarNode.position.x + barLocalX * progressBarNode.scale.x - 30;
|
||||
}
|
||||
|
||||
private _updateProgressAnchor(progress: number): void {
|
||||
|
||||
@@ -292,6 +292,14 @@ export class PageLevel extends BaseView {
|
||||
/** 是否处于分享挑战模式 */
|
||||
private _isShareMode: boolean = false;
|
||||
|
||||
/**
|
||||
* 当前 PageLevel 实例所处分享挑战的 shareCode 缓存。
|
||||
* PageLevel 注册时 cache: true,复用同一个实例。
|
||||
* 当用户在后台切换好友分享卡片时,ShareManager.shareCode 会发生变化,
|
||||
* onViewShow 通过对比这个值与最新的 ShareManager.shareCode 来判断是否需要 _reinitLevelSession。
|
||||
*/
|
||||
private _activeShareCode: string | null = null;
|
||||
|
||||
/** 体力恢复倒计时定时器 */
|
||||
private _staminaTimerId: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
@@ -335,8 +343,10 @@ export class PageLevel extends BaseView {
|
||||
this._shareSubmissions.clear();
|
||||
this._isSubmittingShareResult = false;
|
||||
this._hasRequestedShareUserInfo = false;
|
||||
this._activeShareCode = ShareManager.instance.shareCode;
|
||||
console.log('[PageLevel] 进入分享挑战模式');
|
||||
} else {
|
||||
this._activeShareCode = null;
|
||||
// 从 AuthManager 获取首关数据(由 PageLoading → game-data 提供)
|
||||
const nextLevel = AuthManager.instance.nextLevel;
|
||||
if (nextLevel) {
|
||||
@@ -373,12 +383,41 @@ export class PageLevel extends BaseView {
|
||||
const params = this.getParams();
|
||||
const desiredShareMode = params?.shareMode === true;
|
||||
|
||||
if (desiredShareMode !== this._isShareMode) {
|
||||
console.log(`[PageLevel] 检测到模式切换 ${this._isShareMode} → ${desiredShareMode},重新初始化关卡会话`);
|
||||
// 当前 ShareManager 中的 shareCode(可能因为后台切到新的分享卡片而变化)
|
||||
const latestShareCode = ShareManager.instance.shareCode;
|
||||
|
||||
const modeChanged = desiredShareMode !== this._isShareMode;
|
||||
// 同样是分享模式,但 ShareManager 中的 shareCode 已经换了一份题单 —— 也必须重建会话
|
||||
const shareCodeChanged = desiredShareMode && latestShareCode !== this._activeShareCode;
|
||||
|
||||
if (modeChanged || shareCodeChanged) {
|
||||
console.log(
|
||||
`[PageLevel] 检测到模式/分享码切换 mode:${this._isShareMode}->${desiredShareMode} ` +
|
||||
`code:${this._activeShareCode}->${latestShareCode},重新初始化关卡会话`,
|
||||
);
|
||||
this._reinitLevelSession(desiredShareMode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 上一次离场时如果停留在「答对后通关流程」(_isTransitioning=true 由 showSuccess 置位、
|
||||
// 而 _applyLevelConfig 才会重置),缓存的 PageLevel 实例会保留完成态:
|
||||
// - 输入格已填入正确答案
|
||||
// - 提交按钮被 _isTransitioning 锁住,无法重新提交
|
||||
// - 倒计时已停、谐音梗已揭示
|
||||
// 此时玩家从首页再次进入会看到一个无法操作的"死局"。必须把会话推进到下一关。
|
||||
// 注意:这只可能在主线模式发生 —— 分享模式下点 iconSetting / PassModal 的 home
|
||||
// 都会调用 ShareManager.clearShareMode + ViewManager.replace,再次进入会被
|
||||
// 上面的 modeChanged / shareCodeChanged 分支拦截走 _reinitLevelSession。
|
||||
if (this._isTransitioning) {
|
||||
console.log('[PageLevel] 上次离场时停留在通关后状态,自动推进到下一关');
|
||||
this._closePassModal();
|
||||
this._closeWrongModal();
|
||||
this._closeTimeoutModal();
|
||||
this._closeCommonModal();
|
||||
void this.goToNextLevel();
|
||||
return;
|
||||
}
|
||||
|
||||
this._refreshModeUI();
|
||||
this.updateStaminaLabel();
|
||||
if (!this._isShareMode) {
|
||||
@@ -408,8 +447,10 @@ export class PageLevel extends BaseView {
|
||||
this._hasRequestedShareUserInfo = false;
|
||||
|
||||
if (this._isShareMode) {
|
||||
console.log('[PageLevel] 切换到分享挑战模式');
|
||||
this._activeShareCode = ShareManager.instance.shareCode;
|
||||
console.log(`[PageLevel] 切换到分享挑战模式 (shareCode=${this._activeShareCode})`);
|
||||
} else {
|
||||
this._activeShareCode = null;
|
||||
// 主线模式:从 AuthManager 拉取最新的 nextLevel
|
||||
this._nextLevelData = null;
|
||||
const nextLevel = AuthManager.instance.nextLevel;
|
||||
@@ -866,6 +907,16 @@ export class PageLevel extends BaseView {
|
||||
console.log('[PageLevel] IconSetting 点击,返回主页');
|
||||
AudioManager.instance.playButtonClick();
|
||||
|
||||
// 离开 PageLevel 时把所有挂在 Canvas 上的关卡级弹窗一起清掉。
|
||||
// PassModal / WrongModal / TimeoutModal / CommonModal 都是 addChild 到 this.node.parent
|
||||
// 也就是 PageLevel 的兄弟节点,PageLevel 被 ViewManager 隐藏后它们并不会自动消失,
|
||||
// 否则会孤儿地盖在 PageHome 上。同时清掉 PassModal 也避免再次进入时缓存实例
|
||||
// 残留 _passModalNode 引用让 _swapToNextLevelImagesIfReady 误判弹窗仍在打开。
|
||||
this._closePassModal();
|
||||
this._closeWrongModal();
|
||||
this._closeTimeoutModal();
|
||||
this._closeCommonModal();
|
||||
|
||||
// 分享模式下栈中没有 PageHome,需要清除分享状态并直接打开首页
|
||||
if (this._isShareMode) {
|
||||
ShareManager.instance.clearShareMode();
|
||||
|
||||
@@ -244,7 +244,7 @@
|
||||
"__id__": 1
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_active": false,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 11
|
||||
@@ -426,7 +426,7 @@
|
||||
"__id__": 25
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_active": false,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 71
|
||||
@@ -2106,8 +2106,8 @@
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -172.179,
|
||||
"y": -613.418,
|
||||
"x": -142.654,
|
||||
"y": 760.825,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -2147,7 +2147,7 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 495,
|
||||
"width": 660,
|
||||
"height": 75.6
|
||||
},
|
||||
"_anchorPoint": {
|
||||
@@ -2186,8 +2186,8 @@
|
||||
"_string": "揭晓以下谐音梗的答案吧",
|
||||
"_horizontalAlign": 1,
|
||||
"_verticalAlign": 1,
|
||||
"_actualFontSize": 45,
|
||||
"_fontSize": 45,
|
||||
"_actualFontSize": 60,
|
||||
"_fontSize": 60,
|
||||
"_fontFamily": "Arial",
|
||||
"_lineHeight": 60,
|
||||
"_overflow": 0,
|
||||
@@ -2241,8 +2241,6 @@
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "90w8HRdbBPLYFqBkhPhWfM",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
@@ -2276,7 +2274,7 @@
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -8.201,
|
||||
"y": -852.319,
|
||||
"y": 492.399,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -2333,7 +2331,7 @@
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"y": -80.522,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
@@ -2345,9 +2343,9 @@
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
"x": 1.363,
|
||||
"y": 1.363,
|
||||
"z": 1.363
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
@@ -2494,7 +2492,7 @@
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -248.28,
|
||||
"x": -202.789,
|
||||
"y": -12.833,
|
||||
"z": 0
|
||||
},
|
||||
@@ -2507,9 +2505,9 @@
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0.537,
|
||||
"y": 0.537,
|
||||
"z": 0.767
|
||||
"x": 0.678,
|
||||
"y": 0.678,
|
||||
"z": 0.968
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
@@ -2789,9 +2787,9 @@
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0.488,
|
||||
"y": 0.488,
|
||||
"z": 0.488
|
||||
"x": 0.422,
|
||||
"y": 0.422,
|
||||
"z": 0.422
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
@@ -3839,8 +3837,6 @@
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "bdqvu61fVFTIU1TQqs/qES",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1668,7 +1668,7 @@
|
||||
"b": 0,
|
||||
"a": 255
|
||||
},
|
||||
"_string": "还差3题获得冷场小白2级",
|
||||
"_string": "还差3题,解锁新成就等级",
|
||||
"_horizontalAlign": 1,
|
||||
"_verticalAlign": 1,
|
||||
"_actualFontSize": 40,
|
||||
|
||||
@@ -93,7 +93,7 @@ export class PassModal extends BaseModal {
|
||||
private _titleInfo: PassModalTitleInfo = {
|
||||
titleText: '冷场小白1级',
|
||||
nextTitleProgress: 0,
|
||||
progressText: '还差3题获得冷场小白2级'
|
||||
progressText: '还差3题,解锁新成就等级'
|
||||
};
|
||||
|
||||
/** 动画起点。为 null 表示不做进度动画,直接展示终态 */
|
||||
@@ -105,7 +105,7 @@ export class PassModal extends BaseModal {
|
||||
/** 下一步按钮文案,为 null 时保留 prefab 默认值 */
|
||||
private _nextButtonText: string | null = null;
|
||||
|
||||
/** 进度游标 0% 时的本地 X 坐标,使用 prefab 当前摆放位置作为起点 */
|
||||
/** 进度游标 0% 时的本地 X 坐标,根据 ProgressBar Bar 子节点的左端推导出来 */
|
||||
private _progressAnchorStartX: number | null = null;
|
||||
|
||||
setParams(params: PassModalParams): void {
|
||||
@@ -400,11 +400,24 @@ export class PassModal extends BaseModal {
|
||||
}
|
||||
|
||||
private _cacheProgressAnchorStartX(): void {
|
||||
if (this._progressAnchorStartX !== null || !this.progressAnchor) {
|
||||
if (this._progressAnchorStartX !== null || !this.titleProgressBar) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._progressAnchorStartX = this.progressAnchor.position.x;
|
||||
const barSprite = this.titleProgressBar.barSprite;
|
||||
if (!barSprite) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bar 节点 anchor 为 (0, 0.5),其本地 position.x 即为进度条可视左端。
|
||||
// ProgressBar 与 ProgressAnchor 共享同一父节点(TitleLevel),
|
||||
// 因此把 Bar 的本地 X 按 ProgressBar 自身的位移与缩放映射到父节点空间,
|
||||
// 才是真正的「0% 起点」。直接拿 progressAnchor.position.x 当起点会导致
|
||||
// 气泡始终被 prefab 摆放偏移量带跑(实测偏右 ~24px)。
|
||||
// -40 为视觉微调,与 PageHome 保持一致。
|
||||
const progressBarNode = this.titleProgressBar.node;
|
||||
const barLocalX = barSprite.node.position.x;
|
||||
this._progressAnchorStartX = progressBarNode.position.x + barLocalX * progressBarNode.scale.x - 30;
|
||||
}
|
||||
|
||||
private _resolveProgressAnchor(): void {
|
||||
|
||||
Reference in New Issue
Block a user