diff --git a/.workbuddy/memory/2026-10-23.md b/.workbuddy/memory/2026-10-23.md new file mode 100644 index 0000000..d7735f3 --- /dev/null +++ b/.workbuddy/memory/2026-10-23.md @@ -0,0 +1,24 @@ +# 2026-10-23 工作日志 + +## 首页移除「清除存档」按钮(用户要求) +- 需求:把首页(scr-title)的「清除存档」按钮删掉。 +- 改动:仅删 `index.html:41` 的 `` 一行。`js/main.js` 里的 `wipe` handler(确认后 `Save.wipe()`)已无按钮触发,成为未接线死代码,保留无害(用户只要求删按钮,未要求删逻辑)。 +- 验证:`grep 清除存档/data-act="wipe"` 零残留;`tools/` 无引用;`death/map/check/solve/smoke/save/key/dom-smoke/ice` 九套回归全绿;预览 8123 返回 200。 + +## 主界面新增「设置」功能(用户要求) +- 需求:主界面加「设置」入口;可自定义用户名;可拖动调整手机操作按钮的位置与大小;点「确定」保存、有「恢复默认」按钮。 +- 新增 `js/settings.js`:`BUTTONS`(7 个手柄键 left/right/jump/shoot/down/pause/suicide,各带默认 `cx,cy,size` 百分比+像素),`meta()/place()/apply()/showUsername()`,`Settings.init/enter/confirm/reset`,`wire()` 给预览按钮绑「拖动移动 + 右下角圆点缩放」。工作副本 `work` 未点确定不落盘,点「返回」即丢弃。 +- 存档:`js/save.js` 的 `settings:{username,touch}` 走 `Save.flush()`(localStorage `iwbtc_fan_v1`)。 +- 接线:`index.html` 标题菜单加「设置」按钮 + `#title-user` + `scr-settings` 屏(用户名 input + `#touch-preview` 拖拽预览 + 确定/恢复默认);`js/main.js` 加 `settings/set-ok/set-reset` action 并 `Settings.init()`;`js/touch.js` `show()` 里 `Settings.apply()` 让自定义布局在游戏内生效。 +- CSS:`.tc-btn` 改为 `position:absolute;transform:translate(-50%,-50%)`(active 变形同步保留 translate);新增 `.tc-rsz` 缩放手柄、`.touch-preview`、`.set-*`、`#title-user` 样式。 +- 验证:新增 `tools/settings-test.mjs`(默认布局/apply 定位/enter+confirm 保存用户名并写 localStorage/reset 回出厂且不自动落盘,15 断言全过);dom-smoke(main 初始化成功)、check/smoke/map/save/key/solve/ice 全绿;预览服务返回 200 且含 `scr-settings`。 + +## 修复:拖动设置里的手柄按钮时直接跳到右下角 +- 根因:`js/settings.js` 原 `wire()` 用「指针(clientX) − 基准偏移(off/cx0)」做**绝对坐标映射**定位;一旦 `wrap.getBoundingClientRect()` 取值与渲染偏差(预览百分比定位 + translate(-50%,-50%) 场景下易偏),按下首帧就把 cx/cy 算到极值 → 弹到右下角。 +- 修复:改为**相对位移累加**——按下只记录 `lastX/lastY` 与预览 `rect`;`pointermove` 把「相对上一帧的像素位移 ÷ rect 宽高 ×100」累加到当前 cx/cy(clamp 3~97%),缩放则按「当前指针到中心距离 ÷ 按下时距离」缩放 `size`(24~160px)。第一帧必然停在正确位置,不再跳角。还顺手加了 `e.stopPropagation` + try/catch 包裹 `setPointerCapture`。 +- 回归:`tools/settings-test.mjs` 新增「模拟拖动/缩放」4 条——派发真实 pointerdown/move/up 事件断言:cx 按位移增量变化、逆向可精确归位、缩放放大尺寸且不改位置。settings-test 共 21 断言全过,dom-smoke 初始化正常。 + +## 修复:设置界面打开后一片空白 +- 根因:`js/ui.js` 的 `SCREENS` 数组没加 `'scr-settings'`,`UI.show('scr-settings')` 会把所有已知屏 hidden、却从不取消设置屏的 hidden——只剩画布标题背景(用户截图即此症状)。 +- 修复:SCREENS 加入 `scr-settings`(一行)。教训:**新增 screen 必须同步 SCREENS 数组**。 +- 回归:`tools/settings-test.mjs` 增加「SCREENS 含 scr-settings / 标题有设置入口」两条源码断言,防复发;settings-test 与 dom-smoke 全绿。 diff --git a/css/style.css b/css/style.css index 04dc4c1..8bafa5f 100644 --- a/css/style.css +++ b/css/style.css @@ -218,6 +218,27 @@ canvas#ed-canvas{ .imp-empty{color:var(--dim);font-size:.8em;padding:10px 2px} .modal-btns{display:flex;justify-content:flex-end;gap:6px} +/* ---------- 设置界面 ---------- */ +.title-user{color:var(--dim);font-size:.85em;letter-spacing:2px;margin-top:1vh} +.set-body{display:flex;flex-direction:column;gap:14px;overflow-y:auto;padding:2px} +.set-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap} +.set-row.col{flex-direction:column;align-items:stretch;gap:6px;justify-content:flex-start} +.set-lab{color:var(--gold);letter-spacing:1px;font-size:.95em;min-width:64px} +.set-in{background:#111119;border:1px solid var(--line);color:var(--fg);font-family:inherit;font-size:1em;padding:6px 8px;min-width:200px} +.set-in:focus{outline:none;border-color:var(--gold)} +.set-hint{color:var(--dim);font-size:.78em} +.set-btns{margin-top:2px} +/* 手机手柄预览区(与舞台同比例),按钮绝对定位可拖拽 */ +.touch-preview{ + position:relative;width:100%;aspect-ratio:800/608; + background:#0d0d16;border:1px solid var(--line);overflow:hidden;max-height:46vh; +} +.tp-tip{ + position:absolute;top:6px;left:50%;transform:translateX(-50%); + color:var(--dim);font-size:.72em;background:rgba(0,0,0,.45); + padding:2px 8px;border-radius:6px;pointer-events:none;z-index:3;white-space:nowrap; +} + ::-webkit-scrollbar{width:8px;height:8px} ::-webkit-scrollbar-track{background:#111} ::-webkit-scrollbar-thumb{background:#333;} @@ -247,6 +268,7 @@ html:not(.touch) #touch{display:none !important} .tc-btn{ pointer-events:auto;-webkit-user-select:none;user-select:none;touch-action:none; + position:absolute;transform:translate(-50%,-50%); background:rgba(18,18,28,.52);border:2px solid rgba(255,255,255,.28); color:#fff;font-family:inherit;display:flex;align-items:center;justify-content:center; flex-direction:column;line-height:1;backdrop-filter:blur(2px); @@ -255,7 +277,14 @@ html:not(.touch) #touch{display:none !important} } .tc-btn span{font-size:1.5em} .tc-btn .lbl{font-size:.6em;letter-spacing:1px;opacity:.85;margin-top:2px} -.tc-btn.on,.tc-btn:active{transform:scale(.93);background:rgba(224,48,80,.6);border-color:#ff5c7a} +.tc-btn.on,.tc-btn:active{transform:translate(-50%,-50%) scale(.93);background:rgba(224,48,80,.6);border-color:#ff5c7a} + +/* 设置界面预览里的缩放手柄(真实手柄不挂此元素) */ +.tc-rsz{ + position:absolute;right:-7px;bottom:-7px;width:16px;height:16px;border-radius:50%; + background:var(--gold);border:2px solid #000;cursor:nwse-resize;opacity:.92;touch-action:none; + box-shadow:0 1px 4px rgba(0,0,0,.5); +} .tc-move{width:62px;height:62px;border-radius:14px} .tc-item{width:54px;height:54px;border-radius:50%} @@ -267,7 +296,7 @@ html:not(.touch) #touch{display:none !important} border:3px solid #ffd0da;box-shadow:0 6px 18px rgba(192,26,58,.5); font-size:1.9em;font-weight:bold;color:#fff; } -.tc-jump.on,.tc-jump:active{transform:scale(.92);filter:brightness(1.12)} +.tc-jump.on,.tc-jump:active{transform:translate(-50%,-50%) scale(.92);filter:brightness(1.12)} /* 未持枪时射击键置灰 */ #tc-gun.off{opacity:.4;filter:grayscale(1);background:rgba(18,18,28,.4)} diff --git a/index.html b/index.html index 1abca4e..758d180 100644 --- a/index.html +++ b/index.html @@ -38,8 +38,9 @@ - + +
非商业同人作品 · 致敬 I Wanna Be The Guy / I Wanna Be The Creator · 素材与代码原创
@@ -134,6 +135,34 @@ + + +