diff --git a/tier2/harness/play-phaser.cdp.cjs b/tier2/harness/play-phaser.cdp.cjs index 2b5c97d9..e9d2bf9d 100644 --- a/tier2/harness/play-phaser.cdp.cjs +++ b/tier2/harness/play-phaser.cdp.cjs @@ -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 };