fix(tier2): mapToClient 坐标映射去掉错误的 /dpr——driver tap 落对格

CDP 探针实证:tap 逻辑(85,175) 本该选中棋盘格(0,0),实际选中(2,1)——坐标整体被
放大 dpr(=2) 倍、点击全落错格 → 合成永不成、coins 卡 20、E_live/G_input/F_wiring/
H_progress 连锁红(且 latch=true 是破产路误判,非真赢)。

根因:mapToClient 旧算法假设「Phaser canvas backing-store 含 DPR、逻辑=c.width/dpr」,
但 host 用 Phaser Scale.NONE,canvas backing-store=逻辑 390×844(不含 DPR 乘子),
故 c.width/dpr=195 错、sx=r.width/195=2。修:sx=r.width/c.width(client↔canvas
内部坐标标准换算,与 DPR 无关;游戏逻辑像素=backing-store 像素)。

real 浏览器实证(probe5):tap(85,175)→selected{0,0}正确;driver 驱动 step16 达
win/coins116;__engineCalls=17 含 resource.addCoins/consumeIngredient(F门/三联动门真接线)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
zizi 2026-06-23 20:55:56 +00:00
parent 8ea6133e63
commit e05a1a8b76

View File

@ -198,14 +198,16 @@ async function sampleHash(cdp, selector) {
return fnv1a32(img.data);
}
/** 逻辑坐标 → 页面 client 坐标(钩子④坐标映射;用 Phaser canvas 自身逻辑尺寸算缩放,不硬编码 390/844。 */
/** 逻辑坐标 → 页面 client 坐标(钩子④坐标映射;用 Phaser canvas 自身 backing-store 尺寸算缩放,不硬编码 390/844。 */
async function mapToClient(cdp, xLogical, yLogical) {
const m = await cdp.evaluate(
'(function(){ var c = document.querySelector("' + PHASER_PROBE.canvasSelector.replace(/"/g, '\\"') + '");' +
' if (!c) return null; var r = c.getBoundingClientRect(); var dpr = window.devicePixelRatio || 1;' +
// Phaser canvas 的 width/height 是设备像素(含 DPR逻辑尺寸 = width/dpr缩放 = 显示 rect / 逻辑尺寸。
' var lw = c.width / dpr, lh = c.height / dpr;' +
' return { l: r.left, t: r.top, sx: r.width / (lw || 1), sy: r.height / (lh || 1) }; })()'
' if (!c) return null; var r = c.getBoundingClientRect();' +
// 缩放 = CSS 显示尺寸(rect) / canvas backing-store 尺寸(c.width/height)——这是 client↔canvas 内部坐标的标准换算,
// 与 DPR 无关:游戏逻辑像素 = canvas backing-store 像素(Phaser Scale.NONE,backing=逻辑 390×844、不含 DPR 乘子),
// 故 sx=r.width/c.width。早先误按「c.width 含 DPR、逻辑=c.width/dpr」算,在 Scale.NONE 下把坐标整体放大 dpr 倍、
// 点击全落到错格(实测 tap 逻辑(85,175)→错点格(2,1)、合成永不成、coins 卡 20)。
' return { l: r.left, t: r.top, sx: r.width / (c.width || 1), sy: r.height / (c.height || 1) }; })()'
);
if (!m) throw new Error('mapToClient找不到 Phaser canvas' + PHASER_PROBE.canvasSelector + '');
return { x: m.l + xLogical * m.sx, y: m.t + yLogical * m.sy };