feat(polaris): 《夜市一条街》表现层二轮——弹层期抑制世界飘字+灶台案板让出街景

创始人真机眼验批②⑦。② Hud 新增 _floatMuted 闸(飘字 depth=100 高于研发/图鉴/日结弹层部件≤94,照绘会压菜谱列表);MainScene.update 按弹层 open 态每帧驱动,仅抑制被动世界飘字/飘心,dock 主动「不行」反馈在 drainFx 循环外触发不误伤。⑦ STALL 操作台 330×120→300×72 矮案板让出中上部街景消失点;STOVES 灶台坐标未动、service-loop 用 index 非坐标,招牌 y 与案板高度解耦。logic-smoke(M0+M1+M2)+build 双门 EXIT=0。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lili 2026-07-08 04:35:44 -07:00
parent a9c0367f6d
commit 4a2f782a9d
3 changed files with 32 additions and 7 deletions

View File

@ -27,8 +27,12 @@ export const STOVES = Object.freeze([
{ x: 65, y: 300 }, { x: 325, y: 300 }, { x: 195, y: 245 },
]);
/** 摊位主体(渲染参考:操作台矩形)。 */
export const STALL = Object.freeze({ x: 195, y: 320, w: 330, h: 120 });
/**
* 摊位主体(渲染参考:操作台矩形;纯渲染常量,service-loop 不消费灶台调度用 index 非坐标)
* 收缩为矮案板:只承托灶台下缘,把中上部街景消失点让出(缺点⑦: 330×120 实心大板压街景主体)
* 中心下移 + 降高,顶缘约齐灶台圆(y300 半径 26 274),街景从案板上方大片露出
*/
export const STALL = Object.freeze({ x: 195, y: 312, w: 300, h: 72 });
/**
* M2 扩张地块的座位/灶台坐标组(逻辑坐标单源;地块容量数 = 坐标组长度,plots 表零双写)

View File

@ -70,9 +70,11 @@ export class MainScene extends Phaser.Scene {
this.add.rectangle(VIEW_W / 2, VIEW_H * 0.28, VIEW_W, VIEW_H * 0.56, 0x0e1430); // 夜幕
this.add.rectangle(VIEW_W / 2, VIEW_H * 0.78, VIEW_W, VIEW_H * 0.44, 0x1c2138); // 街面
}
// 摊位操作台
this.add.rectangle(STALL.x, STALL.y, STALL.w, STALL.h, 0x3a2c1e).setStrokeStyle(3, 0xffd166, 0.6);
this.add.text(STALL.x, STALL.y - STALL.h / 2 - 18, '夜市一条街 · 一号摊', {
// 摊位操作台(半透矮案板:只承托灶台下缘、让出上方街景消失点——原 330×120 实心大板把最好看的
// 夜市街景主体糊死,缺点⑦。收缩为 300×72 + fillAlpha 0.42 半透:街景从案板透出、中上部大片露出;
// STALL 是纯渲染常量,service-loop 用灶台 index 非坐标,收缩零逻辑影响)
this.add.rectangle(STALL.x, STALL.y, STALL.w, STALL.h, 0x3a2c1e, 0.42).setStrokeStyle(3, 0xffd166, 0.5);
this.add.text(STALL.x, 240, '夜市一条街 · 一号摊', { // 招牌 y 固定(与案板高度解耦,不随收缩位移;稳定落灶台上方)
fontFamily: 'sans-serif', fontSize: '16px', color: '#ffd166',
}).setOrigin(0.5);
// 灯串(占位氛围:一排暖点)
@ -222,13 +224,18 @@ export class MainScene extends Phaser.Scene {
this.rainTint.setVisible(raining);
// ── juice 事件(飘字;音效归 U12;座位坐标从池取 = 扩张位也有反馈)──
// 弹层(dock 研发/图鉴页 · 日结面板)打开期间抑制世界飘字与飘心:飘字 depth=100 高于弹层部件(≤94),
// 照绘会让「…走了…」等浮在菜谱列表上遮挡弹层(缺点②)。音效/day_end/day_start 等副作用仍照常
// 消费事件(事件不积压),仅飘字/飘心让位;dock 主动「不行」反馈在本循环外触发,不受影响。
const overlayOpen = this._dockOpen || !!this._panel;
this.hud.setFloatMuted(overlayOpen);
const seatAt = (i) => st.seatSites[i] || { x: VIEW_W / 2, y: VIEW_H / 2 };
for (const ev of c.drainFx()) {
playSfx(FX_SFX[ev.type]); // M4 事件音反馈(未映射/未解锁静默)
if (ev.type === 'serve') {
const seat = seatAt(ev.seat);
this.hud.floatText(seat.x, seat.y - 30, `+${ev.amount}${ev.combo >= 2 ? ` ×${ev.combo}` : ''}`, '#ffe08a');
floatHeart(this, seat.x + 18, seat.y - 44); // 顾客满意飘心(反馈三件套强化)
if (!overlayOpen) floatHeart(this, seat.x + 18, seat.y - 44); // 顾客满意飘心(反馈三件套强化;弹层打开时同飘字一并让位——缺点②)
} else if (ev.type === 'miss') {
const seat = seatAt(ev.seat);
this.hud.floatText(seat.x, seat.y - 30, `${ev.typeName}走了…`, '#ff8a8a');
@ -246,7 +253,7 @@ export class MainScene extends Phaser.Scene {
this.hud.floatText(VIEW_W / 2, VIEW_H * 0.34, '评论家入座!优先招呼', '#ffe14d');
} else if (ev.type === 'critic_praise') {
this.hud.floatText(VIEW_W / 2, VIEW_H * 0.32, `评论家好评!声望 +${ev.prestige}`, '#ffe14d');
floatHeart(this, VIEW_W / 2 + 40, VIEW_H * 0.32); floatHeart(this, VIEW_W / 2 - 40, VIEW_H * 0.34);
if (!overlayOpen) { floatHeart(this, VIEW_W / 2 + 40, VIEW_H * 0.32); floatHeart(this, VIEW_W / 2 - 40, VIEW_H * 0.34); }
} else if (ev.type === 'critic_angry') {
this.hud.floatText(VIEW_W / 2, VIEW_H * 0.32, '评论家拂袖而去…口碑重挫', '#ff8a8a');
} else if (ev.type === 'staff_serve') {
@ -280,6 +287,7 @@ export class MainScene extends Phaser.Scene {
this._dayEndShown = false;
}
}
this.hud.setFloatMuted(false); // 复位:dock 主动「不行」反馈(pointerup 回调,在本循环外)仍可飘
this.hud.update(st);
this.dock.update(st);

View File

@ -21,6 +21,9 @@ export class Hud {
constructor(scene, viewW, hooks) {
this.scene = scene;
this.hooks = hooks || {};
// 弹层遮挡态:true 时 floatText 不绘制世界飘字(飘字 depth=100 高于研发/图鉴/日结弹层,
// 照绘会压在菜谱列表上遮挡弹层——缺点②)。由 MainScene.update 每帧按 overlay 状态驱动。
this._floatMuted = false;
const W = viewW;
const BAR_H = 92;
@ -120,10 +123,20 @@ export class Hud {
/** 飘字(反馈三件套之一;+金额/翻台提示,缓动上浮渐隐)。 */
floatText(x, y, text, color) {
// 弹层打开期间不绘制世界飘字:飘字 depth=100 高于 dock 弹层(部件 ≤94)与日结面板(≤82),
// 照绘会让「…走了…」等浮在菜谱列表/面板上遮挡内容(缺点②)。抑制标志由场景每帧驱动。
if (this._floatMuted) return null;
const t = this.scene.add.text(x, y, text, txt(20, color, { stroke: '#000000', strokeW: 4, bold: true }))
.setOrigin(0.5).setDepth(100);
t.setScale(0.6);
this.scene.tweens.add({ targets: t, scale: 1, duration: 160, ease: 'Back.easeOut' });
this.scene.tweens.add({ targets: t, y: y - 58, alpha: 0, duration: 780, delay: 60, ease: 'Cubic.easeOut', onComplete: () => t.destroy() });
}
/**
* 设弹层遮挡态:true 时后续 floatText 不绘制世界飘字,让反馈层给弹层让位(缺点②修复)
* dock 的主动反馈(不行:) pointerup 回调触发发生在 update drainFx 循环之外,
* 那时标志已复位为 false,故仍能正常飘只抑制被动的世界 juice 飘字,不误伤交互即时反馈
*/
setFloatMuted(m) { this._floatMuted = !!m; }
}