Files
kidgo/.workbuddy/memory/MEMORY.md
T

4.5 KiB
Raw Blame History

iwanna(IWBT C 同人网页游戏)项目长期笔记

物理与判定(像素级跳刺的核心)

  • 物理常量写在 js/player.js 的 PHY,全部对齐 IWBT 官方:GRAV 0.4 / MAXFALL 9 / JUMP 8.5 / DJUMP 7.6 / HSPD 3,松手即停、无惯性、可变跳跃高度。
  • 玩家判定盒 11×21(Player 构造函数里 this.w = 11; this.h = 21)。改这里会同时影响 level.js 的 spawn 偏移和全部可达性工具。
  • 刺判定盒在 js/level.js 的 spikeBox(),已按刺尖收紧(上刺 y+8 起、左右刺 x+5 起等),留出像素级擦弹窗口。T.KILLER 必须有兜底 return,否则 deadlyRect 会在坑向关崩溃。

冰面滑行惯性(易反复踩坑)

  • 冰面物理只在 js/player.js 的水平输入段,sliding 是唯一惯性开关:冰上 |vx|>SLIDE_MIN 置位,离冰后仍按 sliding 走惯性分支,撞墙/归零/交还控制时才清位。
  • 空中与地面必须分开摩擦:SLIDE_AIR 0.02(几乎无损,能滑出冰块边缘飞出去)vs SLIDE_FRIC 0.12(地面约 34 帧/70px 收住)。曾经两者都用 0.25,导致「滑出冰块掉下去 7 帧就没速度」——玩家最直观的「没惯性」就来自这里。
  • 按住同向键只能让超速收敛回 HSPD(SLIDE_EASE),不能继续加速;低于走速立刻 vx=target 交还控制。反向键 SLIDE_BRAKE 刹车后马上反向。
  • 回归测试:tools/ice-test.mjs(冰→普通地面/悬空/起跳 4 场景 + 断言),改冰面物理必跑。

关卡设计硬规则(都踩过坑)

  • tools/solve.mjs 是唯一权威:改完任何地图必须跑到「✅ 所有关卡终点与存档点均可达」。
  • 之字竖井用 needle.js 的 well(xL, xR, topRow, botRow, floorSide):每级升 2 格、台阶宽 5 且两级重叠 2 格、顶台与上层地板同高相接、靠地板侧井壁从 topRow+1 到 botRow-4(底部留 3 格入口)。
    • 台阶不能铺满井宽(会变成 1 格高封闭走廊,跳不起来)。
    • 顶台不能压在地板洞口正上方(会把井封死)——曾因此 j2 整关不可达。
  • 完整四向钻石(上下左右刺齐全)在矩形判定盒下横向无解,只能当装饰;要「跳穿门」必须用 vgap(上下夹缝)或 hgap(左右夹缝)。
  • 垂刺(压顶)与落脚点的关系:单跳最高 ~86px、二段跳 158px。压顶刺放在落脚点上方 5 行 = 单跳安全/二段必死;放太近(34 行)会让单跳也撞死。冰面上不要加压顶垂刺(滑行无法控制跳跃高度,实测 j8 直接不可达)。
  • 刺毯缺口最远只能 3 连刺(跳 4 格 ≈128px,已是单跳极限);需要更远必须用二段跳,但压顶垂刺会禁止二段跳。

工具链

  • tools/lib-reach.mjs 是 solve / reach-diag 的共享 BFS 核心,改建模只改这一处。
    • 关键修正:跳跃水平方向被墙挡住时不能把 vx 永久清零(真实 player.js 里按住方向键下一帧会恢复)。清零会丢失「贴墙上升→越过台面→横移」这条经典路线,曾导致整个 j2 竖井判为不可达。
    • reach() 默认 DJSET/RELSET 必须与 solve.mjs 的 DJ/REL 环境变量一致,否则诊断和求解结果对不上。
  • 其余:check.mjs 格式校验、save-test.mjs 存档点、key-test.mjs 按键语义(R=回存档点 / Backspace=整关重来)、smoke.mjs、dom-smoke.mjs。
  • 本地预览:python3 -m http.server 8123(ES module 必须走 HTTP,file:// 打不开)。

关卡现状(23 关)

跳刺 j1j10(68×52 ~ 150×44,刺密度 3.8%11.6%)、耐久 e1e4、boss b1b3(可达性求解跳过)、坑向 r1~r4。

移动端虚拟手柄(2026-10-22 新增)

  • 触屏自动检测:matchMedia('(pointer: coarse)') / ontouchstart / maxTouchPoints>0;?touch=1 强制开、?touch=0 关(桌面预览用)。
  • js/input.js 的 touch 状态层 + setTouch/clearTouch 与键盘共用 action 模型(now/prev),不破坏可达性工具。
  • js/touch.js:左下 ◀▶ 移动、右下大「跳」+ 🔫射击(按住连发,受 hasGun/冷却限制)+ ▼下蹲 + 暂停/重生小键;pointer 事件支持多指,hide() 会 clearTouch() 防卡键。
  • 仅在 playing 态显示(startLevel/resume 显示,菜单/暂停/结算隐藏);HUD 每帧 Touch.setGun(P.hasGun) 控制射击键置灰。
  • 若改键位含义,记得同步 js/input.js 的 BIND 与 touch.js 的 HELD/api 映射。