Files
SimpleFarm/.workbuddy/memory/2026-09-25.md
T
snowy-yang 92b1a628b1 网页端新增 Canvas 二维农场地图
为什么:地块和牲畜原本是响应式卡片列表,信息全但没有"农场"的形状感。
改成一张俯视像素风地图作主视觉:农田按 4 列排成方阵(地块多自动改 6 列),
土壤颜色随水分深浅变化、作物随生长进度放大、成熟发金光、缺水画干裂;
牧场围栏里牲畜随机漫步,待收产出挂金色气泡、没喂食标 💢;
已拥有的建筑在底部建筑带列队;五种天气各有天色,雨/暴雨有雨滴动画。
悬停出提示框,点地块即播种/浇水/收获、点牲畜即喂食/收取——全部复用
既有 openCropPick/act() 流程,卡片面板原样保留作精确操作入口。

实现要点:画布用逻辑坐标绘制、按容器宽 × devicePixelRatio 缩放,
高分屏不糊、窄屏等比缩;命中检测在逻辑坐标上自己算。
服务端零改动——state 里的 plots/animals/buildings 现成够用。

修复一个真机才抓得到的初始化 bug:动画循环首帧同步执行,原顺序
"先绑定后布局"让首帧在未初始化的字段上 TypeError,rAF 注册被一起吞掉,
表现为画布全白但点击命中正常(命中不经过画布)。改为先布局再绑定,
并给 mapStep/mapDraw 加空值护栏。

真浏览器端到端验证:登录、canvas 坐标点击浇水(AP/水分/toast 全对)、
悬停提示、动画循环存活(云位移 5.24px/600ms)、截图目检渲染效果,
errors/console 干净。534 项测试全绿,ruff/pyright 无告警。
2026-09-25 22:24:08 +08:00

45 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 2026-09-25 四座自动化设施
- 用户要「添加自动化设施」,AskUserQuestion 给了 4 个候选,用户全选:
喷灌系统 / 自动收割机 / 自动售货机 / 饲料磨坊。
- 设计上沿用既有建筑哲学:**只替代行动点动作,绝不自动花钱**。
`_run_buildings` 扩成六段流水线(顺序即依赖):
水井 → 喷灌 → 收割机 → 磨坊 → 喂食器 → 售货机。
磨坊刻意排在喂食器前——早上磨的饲料当天就能喂上;
收割机遇满仓停摆、作物留地(同喂食器缺料停摆)。
- 数值:喷灌 2800/限1/全量浇水;收割机 900/限3/每天各收 2 块熟地、
**刻意不给经验**(机器收的不算劳动,给手动玩法留价值);
售货机 1200/限1/市价>基准价才卖、每天上限 5 份、越贵越先卖
(_earn 复用 sell 的入账逻辑);磨坊 500/限1/1 份最便宜的作物磨 3 份饲料
(FEED_UNIT_PRICE=6,小麦 14 磨 18 金的料,微赚但吃掉作物)。
- 架构红利:config.BUILDINGS 驱动一切(build 动作、catalog、网页建筑区、
可用动作推荐),新增建筑 engine 之外零改动。
- 测试 +6,途中确认两个既有行为:引擎自带 START_FEED=5(feed 断言要先清零);
advance_day 牲畜阶段末尾会把 fed 复位(「喂到了」的证据是 pending 累计,
鸡 cycle=1 当天喂到就 pending=1)。
- 门禁 534 项 OK(skip 39)、ruff/pyright 全绿;提交 cb4c1e7 已推送。
服务器已重启到新代码,catalog 8 座建筑齐全。
## 2026-09-25 Canvas 二维农场地图
- 用户问「能不能做成二维的」,AskUserQuestion 三选一:CSS 农田视图 /
Canvas 像素农场 / 网页+TUI 都改,用户选 **Canvas 像素农场**。
- 实现:全在 webui.py(服务端零改动,state 里现成的 plots/animals/buildings
够用)。页首插一张全宽 canvas 卡片:逻辑坐标绘制(456×152 起,随地块数变)、
实际像素 = 容器宽 × dpr,命中检测自己算(逻辑坐标 = clientX × MAP.w/rect.width)。
农田 4 列方阵(>12 块改 6 列)土壤颜色随水分插值、作物 emoji 随生长放大、
成熟金光、干裂画裂纹;牧场围栏里牲畜随机漫步回弹、待收产物金泡、没喂 💢;
底部建筑带(owned>0 才画);天气五種各有天色+雨滴/云/烈日。
交互复用 openCropPick/act():空地点击弹选种、熟地收获、缺水浇水、
牲畜收取优先于喂食。下方卡片面板全保留(地图负责沉浸,卡片负责精确)。
- **踩坑:rAF 循环首帧同步执行**。updateMap 原顺序 bind→layout,首帧
`f.ts` 在 MAP.field=null 上 TypeError,把 requestAnimationFrame 注册一起吞掉,
表现是「画布全白但点击命中正常」(命中是纯数学不经过画布)。
修复:layout→sync→bind→fit 顺序 + mapStep/mapDraw 空值护栏。
排查手法:截图空白先别信,`getImageData` 读像素 + 探针 rAF 计数 + 云位移
三连定位「画了没」和「循环活着没」。
- 真机验收:登录、canvas 点击浇水(AP 4→3、水分 2→3、toast)、
悬停 tooltip、截图目检全过;errors/console 干净。534 项测试全绿。