这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《Java 编程入门》9.3 sealed 与模式匹配
把 library 的 CLI 从字符串命令和 if/else 改成 sealed Command 接口加记录子类型,再用 switch 模式匹配一次性解构、守卫和分发;讲清 permits 的限制、穷尽性检查、模式顺序与 null 分支,并给出非穷尽 switch 与未授权实现的真实编译错误。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
把 library 的 CLI 从字符串命令和 if/else 改成 sealed Command 接口加记录子类型,再用 switch 模式匹配一次性解构、守卫和分发;讲清 permits 的限制、穷尽性检查、模式顺序与 null 分支,并给出非穷尽 switch 与未授权实现的真实编译错误。
把「BORROWED」「RETURNED」这类字符串常量换成 LoanStatus 枚举:用字段和方法承载展示名与开放状态,用 switch 表达式把状态迁移写穷尽,把续借、归还规则放进 Loan record,并用 ordinal、valueOf 与持久化的真实边界说明枚举该怎么用、不该怎么用。
《小游戏开发实战》卷二《引擎、实现与体验打磨》的复现索引:按 16 章列出 pebble/ 下全部 config / sim / core / web 文件,写清卷二工具链的 e<章号>_ 前缀约定(与卷一的 ch 前缀区分,避免 node --test 通配符交叉匹配)、环境速查与六层可运行性口径(S/P/W/D/X/B)的逐层复现命令,以及一键复现与排错顺序。
对象池解决「少分配」,但弱机的内存与帧耗时本身就不够用。这一节把弱机识别做成整数判据:按可用内存、帧耗时 P95、CPU 核心数把设备分成 high/mid/low 三档,每档给出粒子数、渲染分辨率千分比、动效开关与目标帧率,并支持运行时主动降一档。
把「每帧新建对象」与「对象池零分配」放进同一个分配量级的解析模型:跑 10 分钟,算出分配总量与 GC 触发次数,再用 B 层扫描每帧分配数到 GC 触发间隔。全程显式声明这是模型而非 V8 实测,数字只在同一套假设下可比,用来判断分配密度是否危险。
小游戏里每帧新建对象会把垃圾回收压力堆到帧预算上。这一节用 TypeScript 写一个定容对象池:acquire 借出时清零状态、release 归还进空闲表,容量耗尽按拒绝、覆盖最旧、扩容到上限三种策略处理,并统计命中率与峰值占用,让「复用是否真的发生」变成可断言的事。
前两节把存档存好、迁好了,这一节问一个更尖锐的问题:存档被玩家改了怎么办。给出客户端能做的四类校验——数值上限、时间间隔下界、增量单调性、离线收益封顶,再用 S 层脚本模拟八种作弊模式,看清本地校验能拦住哪些、漏掉哪些,以及为什么权威必须放服务端。
上一节把存档存进了抽象层,这一节解决更难的一半:玩家设备上躺着的旧存档,格式变了怎么办。用 v1→v2→v3 的迁移链演示三类改动——字段新增默认值、字段重命名、类型收紧,配可跑测试断言旧存档能升到最新且不丢数据、迁移幂等、未知版本明确失败,并用 S 层脚本对照迁移前后的体积与耗时。
小游戏要在浏览器与多个小游戏宿主上跑,存储能力各不相同:有的无上限,有的只有几 MB 且会静默丢写。本节给出一层可断言的 KV 抽象——内存、限额、降级到最小存档三种实现,容量按整数字节记账、超限按优先级淘汰,云存档只按整数版本号对账取新者。
把「落地弹得对不对」变成四个整数参数:重力增量、速度阻尼比、落地弹性比、静止阈值。用固定步长的整数物理内核实现下落与弹跳,再用单文件 HTML 原型配 Playwright 无头,先注入固定帧数步进、再走一遍真实 rAF 下落,断言落点、弹跳次数与静止判定并截图。
动手写 t1/t2 两级里最核心的碰撞内核:AABB 与圆相交(整数平方距离比较,无开方)、按网格做的 3x3 邻域 broad phase,并用可播种 LCG 撒点,对照暴力 O(n^2) 与网格的候选对数随实体数增长,产 CSV 与 SVG。
把「小游戏要不要上物理引擎」变成可核算的分级问题:把玩法类型映射到所需物理能力,再折算成代码行数、实现工时与包体占用,用 S 层脚本逐层汇总五个层级,讲清《合成小岛》为什么只需最轻的一级、多上一级要付多少代价,以及分级为何要按能力增量补齐而非整体升级。
把浏览器与小游戏宿主的输入差异摆成一张矩阵:事件 API 名、多点触控投递方式、取消事件、安全区、坐标原点五个维度逐平台对比,用 S 层脚本统计差异条目并估算适配工时,讲清权重模型与复用系数如何把「每家平台都要改一遍」压成一次性抽象层成本。
把「跟不跟手」从主观感受变成可调参数:用整数跟随模型(跟随系数、死区、最小步、速度上限、松手吸附)实现拖拽手感,参数全为像素整数、无浮点,再用单文件 HTML 原型配 Playwright 无头真跑一次鼠标拖拽,断言落点、吸附与手势并截图存档。
把不同平台的触摸事件统一归一化成 {x,y,phase} 样本序列,再用手势状态机识别点击、长按、拖拽与滑动:给出可跑的 TypeScript 输入内核与 14 项单元测试,讲清时间阈值与位移阈值的判定顺序,以及物理像素到逻辑坐标的整数缩放与原点翻转。
暂停容易,恢复难:切后台十分钟再回来,若把十分钟按固定步长如实补回,一帧要跑三万七千步,设备直接卡死。本节用封顶补偿把离线时长折算成有上限的固定步数,并把整条「暂停 → 切后台 → 恢复」路径放进单文件 HTML 原型,用 Playwright 无头断言加截图验收。
一款小游戏不止一个「世界」:菜单、对局、结算、弹窗各自是一个场景。本节用场景栈 + 生命周期状态机管理它们——进入、暂停、恢复、退出四个动作,按动作而非目标态判定合法迁移,非法迁移一律拒绝且不改动任何状态,并配可跑的 TS 内核与断言测试。
固定步长主循环是《合成小岛》可复现的地基:用累加器把可变帧率折算成整数固定步,输入按 tick 采样、随机按步推进,同一 seed 与输入序列在 16ms / 32ms / 不规则帧率下终局逐位一致;配可跑的 TS 内核、断言测试与跨语言对拍。
小游戏改一张图、加一个关卡,用户要重下多少,取决于热更新的版本模型。本节用 TypeScript 写一个差异计算内核:版本号按整数分段比较,清单按路径与哈希分类,再据此在「差异下载」与「整包更新」之间做决策,让每次更新要下多少变成可复算的数字。
音频常常是包体里仅次于图集的一块,却最容易被「随便导出个 MP3」糊弄过去。本节把音频格式折算成可算的字节:码率、容器开销、片段时长一起进公式,再用一段脚本选出每个片段该用的格式,并给出「什么时长用什么格式」的判据,算清短音效与长片段各自该走哪条路。