游戏设计:原型与开发 17:数字化系统里的思维体操
- 一、每章都有个"我保证你会用到"的开头
- 二、骰子里藏着没写进说明书的规则
- 三、"站起来"实验:人类语言的效率陷阱
- 四、C#、代码库与"高级命令的艺术"
- [五、拆解《拾苹果》:一个 1981 年的经典,被温和化了](#五、拆解《拾苹果》:一个 1981 年的经典,被温和化了)
- 六、小结:本章其实只教了一个动作
一、每章都有个"我保证你会用到"的开头
第Ⅱ部分叫数字原型 。作者开门见山:如果你没写过程序,这一章会带你进入一个新世界------不是教语法,而是先给你换一种思维方式。
毕竟,电脑很笨。它每秒能执行上百万条指令,但它没有意识,不知道"把餐具摆好"是什么意思。你必须把意图翻译成它听得懂的东西。
二、骰子里藏着没写进说明书的规则
作者先从桌上游戏讲起:一对普通六面骰,在多数棋类游戏中有一套"大家都懂"的玩法。
| ✅ 符合预期的行为 | ❌ 不符合预期的行为 |
|---|---|
| 掷出后随机得到 1~6 点 | 不能直接摆出想要的点数 |
| 两个骰子通常一起掷(尤其颜色大小相同时) | 必须有一个面完全朝下才算有效,否则重掷 |
| 一起掷时通常计算总点数(3 + 4 = 7) | 掷出后本回合不许再碰骰子 |
| 掷出一对相同点数时,有时有特殊奖励 | 不能把骰子掷向其他玩家 |
左栏是规则,右栏也是规则------只不过右栏从来没人写进规则书。
这就解释了两件事:为什么一群小孩能自创游戏、还全都凭直觉明白怎么玩;以及为什么 VR/AR 里的"社交默契"那么难做。人类玩家随身携带一整套默认规则:公平、体面、不耍赖。
而计算机没有这套东西。它只有你写下的指令。
三、"站起来"实验:人类语言的效率陷阱
这是计算机科学课堂上的经典练习:让同伴仰卧在地板上,你只能用简单命令让他站起来。禁止说"站起来"。
你大概会发出这样的句子:
- 把你的左胳膊肘弯成 90°;
- 让你的右腿半伸展;
- 将你的左手手心向下放在地上;
- 举起你的右臂指向电视。
作者还很实在地补了一句:这些命令对真正的机器人来说仍然太复杂,而且容易被误解。但作为练习,够了。
结果呢?如果你和同伴都严格遵守规则,用时肯定不会短。更妙的是------如果同伴事先不知道你要让他站起来,花的时间会更长。
一个四岁小孩的降维打击
作者抛出了对比:他四岁时,家长说一句"请把餐具摆好",他就能完成。而"摆餐具"这件事,拆成机器人指令大概要几十上百条。
这不是为了打击你,而是为了让你明白高级命令有多值钱。
从"意图"到"指令"的两层落差
#mermaid-svg-IGTg4KH09T2LgXER{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IGTg4KH09T2LgXER .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IGTg4KH09T2LgXER .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IGTg4KH09T2LgXER .error-icon{fill:#552222;}#mermaid-svg-IGTg4KH09T2LgXER .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IGTg4KH09T2LgXER .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IGTg4KH09T2LgXER .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IGTg4KH09T2LgXER .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IGTg4KH09T2LgXER .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IGTg4KH09T2LgXER .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IGTg4KH09T2LgXER .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IGTg4KH09T2LgXER .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IGTg4KH09T2LgXER .marker.cross{stroke:#333333;}#mermaid-svg-IGTg4KH09T2LgXER svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IGTg4KH09T2LgXER p{margin:0;}#mermaid-svg-IGTg4KH09T2LgXER .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-IGTg4KH09T2LgXER .cluster-label text{fill:#333;}#mermaid-svg-IGTg4KH09T2LgXER .cluster-label span{color:#333;}#mermaid-svg-IGTg4KH09T2LgXER .cluster-label span p{background-color:transparent;}#mermaid-svg-IGTg4KH09T2LgXER .label text,#mermaid-svg-IGTg4KH09T2LgXER span{fill:#333;color:#333;}#mermaid-svg-IGTg4KH09T2LgXER .node rect,#mermaid-svg-IGTg4KH09T2LgXER .node circle,#mermaid-svg-IGTg4KH09T2LgXER .node ellipse,#mermaid-svg-IGTg4KH09T2LgXER .node polygon,#mermaid-svg-IGTg4KH09T2LgXER .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IGTg4KH09T2LgXER .rough-node .label text,#mermaid-svg-IGTg4KH09T2LgXER .node .label text,#mermaid-svg-IGTg4KH09T2LgXER .image-shape .label,#mermaid-svg-IGTg4KH09T2LgXER .icon-shape .label{text-anchor:middle;}#mermaid-svg-IGTg4KH09T2LgXER .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-IGTg4KH09T2LgXER .rough-node .label,#mermaid-svg-IGTg4KH09T2LgXER .node .label,#mermaid-svg-IGTg4KH09T2LgXER .image-shape .label,#mermaid-svg-IGTg4KH09T2LgXER .icon-shape .label{text-align:center;}#mermaid-svg-IGTg4KH09T2LgXER .node.clickable{cursor:pointer;}#mermaid-svg-IGTg4KH09T2LgXER .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-IGTg4KH09T2LgXER .arrowheadPath{fill:#333333;}#mermaid-svg-IGTg4KH09T2LgXER .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IGTg4KH09T2LgXER .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IGTg4KH09T2LgXER .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IGTg4KH09T2LgXER .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IGTg4KH09T2LgXER .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IGTg4KH09T2LgXER .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-IGTg4KH09T2LgXER .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IGTg4KH09T2LgXER .cluster text{fill:#333;}#mermaid-svg-IGTg4KH09T2LgXER .cluster span{color:#333;}#mermaid-svg-IGTg4KH09T2LgXER div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IGTg4KH09T2LgXER .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IGTg4KH09T2LgXER rect.text{fill:none;stroke-width:0;}#mermaid-svg-IGTg4KH09T2LgXER .icon-shape,#mermaid-svg-IGTg4KH09T2LgXER .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IGTg4KH09T2LgXER .icon-shape p,#mermaid-svg-IGTg4KH09T2LgXER .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-IGTg4KH09T2LgXER .icon-shape .label rect,#mermaid-svg-IGTg4KH09T2LgXER .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IGTg4KH09T2LgXER .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-IGTg4KH09T2LgXER .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-IGTg4KH09T2LgXER :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 跳过的层
人类意图:把餐具摆好
人类语言:一句话
隐含前提:你知道餐具在哪
知道谁在吃饭
知道碗筷怎么放
计算机需要:坐标·顺序·条件·循环
几十条原子指令
图说 :图中虚线是"效率的来源"。人类的语言之所以高效,是因为它大胆跳过了中间层------所有常识都由听者自己补齐。而编程的困难恰恰在于:计算机不会补,你必须把虚线拆成一格一格的实线。理解这一点,你就理解了"为什么写代码感觉慢"------你不是慢,你是在补人类语言省略掉的那几十行。
四、C#、代码库与"高级命令的艺术"
既然要给计算机下命令,得选一门语言。作者选了 C#,理由很坦诚:它比 Processing、JavaScript 这类语言更"较真",但正是这份较真,能让你真正理解核心概念、养成好习惯,长期收益更大。
于是"站起来"这个比喻,直接映射成了编程里的两个概念:
| 人类语言 | 编程世界 | 例子 |
|---|---|---|
| "站起来" | 代码库里的高级方法 | transform.position = ... |
| "把餐具摆好" | 封装好的功能模块 | Physics.Raycast() |
| 逐条原子指令 | 你新写的业务逻辑 | if (hit) { ... } |
最常用的代码库,就是 UnityEngine。它替你处理了:
- 光影(烟雾、反射);
- 物理(重力、碰撞,甚至布料模拟);
- 输入(鼠标、键盘、手柄、触屏);
- 还有上千种你暂时想不到的功能。
外面还有几十万个免费/收费库。作者举了个很具体的例子:想让物体在一秒内平滑穿过屏幕?Bob Berkebile 的 iTween 已经写好了,直接拿来用。
这就是"高级命令"的价值:你不必每次从"弯胳膊肘"开始 。本书也会建一个自己的库,叫
ProtoTools,在几个项目里反复长胖。
五、拆解《拾苹果》:一个 1981 年的经典,被温和化了
本章的实战对象是《拾苹果》(Apple Picker),也是第 28 章要做的第一个原型。它的祖先是 Activision 1981 年发行的 Kaboom!,设计师 Larry Kaplan------那个版本里,一个"疯狂炸弹投手"往屏幕下方扔炸弹,玩家左右移动篮筐去接。
本书版本把炸弹换成了苹果 🍎,暴力值下降,可爱度上升。
玩法三句话
- 玩家用鼠标左右移动屏幕下方的三个篮筐;
- 苹果树在屏幕上方左右晃动,每隔一段时间掉一个苹果;
- 接住得分;漏接一个,所有苹果立即消失,损失一个篮筐;三个篮筐丢光,游戏结束。
三个游戏对象,三份极简动作清单
在 Unity 里,屏幕上任何可见的东西都叫游戏对象(GameObject)。这个游戏只有三个:
| 对象 | 动作清单 | 复杂度 |
|---|---|---|
| 🧺 篮筐 | ① 随鼠标左右移动 ② 碰到苹果就接住并得分 | ★☆☆☆☆ |
| 🍎 苹果 | ① 垂直下落 ② 碰到地面就消失,并让其他苹果一起消失 | ★☆☆☆☆ |
| 🌳 苹果树 | ① 随机左右移动 ② 每隔 0.5 秒落下一个苹果 | ★★☆☆☆ |
作者的原话是"仅此而已!"------注意这三个感叹号里的自信。一个能玩的游戏,行为清单可以短到这种程度。
对象与规则的分解视图
#mermaid-svg-gyvkKG4DooNkRkcl{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gyvkKG4DooNkRkcl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gyvkKG4DooNkRkcl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gyvkKG4DooNkRkcl .error-icon{fill:#552222;}#mermaid-svg-gyvkKG4DooNkRkcl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gyvkKG4DooNkRkcl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gyvkKG4DooNkRkcl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gyvkKG4DooNkRkcl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gyvkKG4DooNkRkcl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gyvkKG4DooNkRkcl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gyvkKG4DooNkRkcl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gyvkKG4DooNkRkcl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gyvkKG4DooNkRkcl .marker.cross{stroke:#333333;}#mermaid-svg-gyvkKG4DooNkRkcl svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gyvkKG4DooNkRkcl p{margin:0;}#mermaid-svg-gyvkKG4DooNkRkcl .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gyvkKG4DooNkRkcl .cluster-label text{fill:#333;}#mermaid-svg-gyvkKG4DooNkRkcl .cluster-label span{color:#333;}#mermaid-svg-gyvkKG4DooNkRkcl .cluster-label span p{background-color:transparent;}#mermaid-svg-gyvkKG4DooNkRkcl .label text,#mermaid-svg-gyvkKG4DooNkRkcl span{fill:#333;color:#333;}#mermaid-svg-gyvkKG4DooNkRkcl .node rect,#mermaid-svg-gyvkKG4DooNkRkcl .node circle,#mermaid-svg-gyvkKG4DooNkRkcl .node ellipse,#mermaid-svg-gyvkKG4DooNkRkcl .node polygon,#mermaid-svg-gyvkKG4DooNkRkcl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gyvkKG4DooNkRkcl .rough-node .label text,#mermaid-svg-gyvkKG4DooNkRkcl .node .label text,#mermaid-svg-gyvkKG4DooNkRkcl .image-shape .label,#mermaid-svg-gyvkKG4DooNkRkcl .icon-shape .label{text-anchor:middle;}#mermaid-svg-gyvkKG4DooNkRkcl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gyvkKG4DooNkRkcl .rough-node .label,#mermaid-svg-gyvkKG4DooNkRkcl .node .label,#mermaid-svg-gyvkKG4DooNkRkcl .image-shape .label,#mermaid-svg-gyvkKG4DooNkRkcl .icon-shape .label{text-align:center;}#mermaid-svg-gyvkKG4DooNkRkcl .node.clickable{cursor:pointer;}#mermaid-svg-gyvkKG4DooNkRkcl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gyvkKG4DooNkRkcl .arrowheadPath{fill:#333333;}#mermaid-svg-gyvkKG4DooNkRkcl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gyvkKG4DooNkRkcl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gyvkKG4DooNkRkcl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gyvkKG4DooNkRkcl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gyvkKG4DooNkRkcl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gyvkKG4DooNkRkcl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gyvkKG4DooNkRkcl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gyvkKG4DooNkRkcl .cluster text{fill:#333;}#mermaid-svg-gyvkKG4DooNkRkcl .cluster span{color:#333;}#mermaid-svg-gyvkKG4DooNkRkcl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gyvkKG4DooNkRkcl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gyvkKG4DooNkRkcl rect.text{fill:none;stroke-width:0;}#mermaid-svg-gyvkKG4DooNkRkcl .icon-shape,#mermaid-svg-gyvkKG4DooNkRkcl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gyvkKG4DooNkRkcl .icon-shape p,#mermaid-svg-gyvkKG4DooNkRkcl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gyvkKG4DooNkRkcl .icon-shape .label rect,#mermaid-svg-gyvkKG4DooNkRkcl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gyvkKG4DooNkRkcl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gyvkKG4DooNkRkcl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gyvkKG4DooNkRkcl :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 命中
是
是
到点
拾苹果 · 游戏循环
🧺 篮筐
🍎 苹果
🌳 苹果树
读取鼠标水平位移
每帧检测与苹果的碰撞
苹果消失 + 加分
每帧向下位移
碰到地面?
清空所有苹果 + 篮筐 -1
每帧 10% 概率转向
翻转移动方向
计时器累加到 0.5 秒
生成一个苹果 + 计时归零
图说 :这张图是从"游戏"到"原子动作"的完整分解 。请注意三件事:第一,所有行为都挂在"每帧"这个节拍上,没有人拥有"自由意志";第二,唯一的随机性在苹果树的转向(10% 概率),其余全是确定性判断;第三,所谓"难度",不过是"0.5 秒掉一个"这个数字------调小它,游戏立刻变难。这就是参数化设计的最小样本。
用流程图画"每一帧"
作者强调:表达动作与判断流程,流程图是极好的工具。椭圆是帧,方框是动作,菱形是判断。
篮筐:每一帧都在做同一件事
#mermaid-svg-xdBZU1PZ85HTAkCv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xdBZU1PZ85HTAkCv .error-icon{fill:#552222;}#mermaid-svg-xdBZU1PZ85HTAkCv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xdBZU1PZ85HTAkCv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xdBZU1PZ85HTAkCv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xdBZU1PZ85HTAkCv .marker.cross{stroke:#333333;}#mermaid-svg-xdBZU1PZ85HTAkCv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xdBZU1PZ85HTAkCv p{margin:0;}#mermaid-svg-xdBZU1PZ85HTAkCv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xdBZU1PZ85HTAkCv .cluster-label text{fill:#333;}#mermaid-svg-xdBZU1PZ85HTAkCv .cluster-label span{color:#333;}#mermaid-svg-xdBZU1PZ85HTAkCv .cluster-label span p{background-color:transparent;}#mermaid-svg-xdBZU1PZ85HTAkCv .label text,#mermaid-svg-xdBZU1PZ85HTAkCv span{fill:#333;color:#333;}#mermaid-svg-xdBZU1PZ85HTAkCv .node rect,#mermaid-svg-xdBZU1PZ85HTAkCv .node circle,#mermaid-svg-xdBZU1PZ85HTAkCv .node ellipse,#mermaid-svg-xdBZU1PZ85HTAkCv .node polygon,#mermaid-svg-xdBZU1PZ85HTAkCv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xdBZU1PZ85HTAkCv .rough-node .label text,#mermaid-svg-xdBZU1PZ85HTAkCv .node .label text,#mermaid-svg-xdBZU1PZ85HTAkCv .image-shape .label,#mermaid-svg-xdBZU1PZ85HTAkCv .icon-shape .label{text-anchor:middle;}#mermaid-svg-xdBZU1PZ85HTAkCv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xdBZU1PZ85HTAkCv .rough-node .label,#mermaid-svg-xdBZU1PZ85HTAkCv .node .label,#mermaid-svg-xdBZU1PZ85HTAkCv .image-shape .label,#mermaid-svg-xdBZU1PZ85HTAkCv .icon-shape .label{text-align:center;}#mermaid-svg-xdBZU1PZ85HTAkCv .node.clickable{cursor:pointer;}#mermaid-svg-xdBZU1PZ85HTAkCv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xdBZU1PZ85HTAkCv .arrowheadPath{fill:#333333;}#mermaid-svg-xdBZU1PZ85HTAkCv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xdBZU1PZ85HTAkCv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xdBZU1PZ85HTAkCv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xdBZU1PZ85HTAkCv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xdBZU1PZ85HTAkCv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xdBZU1PZ85HTAkCv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xdBZU1PZ85HTAkCv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xdBZU1PZ85HTAkCv .cluster text{fill:#333;}#mermaid-svg-xdBZU1PZ85HTAkCv .cluster span{color:#333;}#mermaid-svg-xdBZU1PZ85HTAkCv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xdBZU1PZ85HTAkCv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xdBZU1PZ85HTAkCv rect.text{fill:none;stroke-width:0;}#mermaid-svg-xdBZU1PZ85HTAkCv .icon-shape,#mermaid-svg-xdBZU1PZ85HTAkCv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xdBZU1PZ85HTAkCv .icon-shape p,#mermaid-svg-xdBZU1PZ85HTAkCv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xdBZU1PZ85HTAkCv .icon-shape .label rect,#mermaid-svg-xdBZU1PZ85HTAkCv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xdBZU1PZ85HTAkCv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xdBZU1PZ85HTAkCv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xdBZU1PZ85HTAkCv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
每一帧开始
随鼠标左右移动
是否碰到苹果?
本帧结束
接住苹果并得分
图说 :这张图短得有点可爱,但它精确描述了"玩家控制"的本质:输入 → 位移 → 碰撞 → 反馈。注意碰撞检测被放在移动之后,而不是之前------顺序不同,手感就不同。如果你先检测后移动,苹果会在"视觉上还差一点"的时候就被接住。
苹果:下落,然后消失
#mermaid-svg-Q2y1HjZMECyOUb2X{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Q2y1HjZMECyOUb2X .error-icon{fill:#552222;}#mermaid-svg-Q2y1HjZMECyOUb2X .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Q2y1HjZMECyOUb2X .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Q2y1HjZMECyOUb2X .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Q2y1HjZMECyOUb2X .marker.cross{stroke:#333333;}#mermaid-svg-Q2y1HjZMECyOUb2X svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Q2y1HjZMECyOUb2X p{margin:0;}#mermaid-svg-Q2y1HjZMECyOUb2X .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Q2y1HjZMECyOUb2X .cluster-label text{fill:#333;}#mermaid-svg-Q2y1HjZMECyOUb2X .cluster-label span{color:#333;}#mermaid-svg-Q2y1HjZMECyOUb2X .cluster-label span p{background-color:transparent;}#mermaid-svg-Q2y1HjZMECyOUb2X .label text,#mermaid-svg-Q2y1HjZMECyOUb2X span{fill:#333;color:#333;}#mermaid-svg-Q2y1HjZMECyOUb2X .node rect,#mermaid-svg-Q2y1HjZMECyOUb2X .node circle,#mermaid-svg-Q2y1HjZMECyOUb2X .node ellipse,#mermaid-svg-Q2y1HjZMECyOUb2X .node polygon,#mermaid-svg-Q2y1HjZMECyOUb2X .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Q2y1HjZMECyOUb2X .rough-node .label text,#mermaid-svg-Q2y1HjZMECyOUb2X .node .label text,#mermaid-svg-Q2y1HjZMECyOUb2X .image-shape .label,#mermaid-svg-Q2y1HjZMECyOUb2X .icon-shape .label{text-anchor:middle;}#mermaid-svg-Q2y1HjZMECyOUb2X .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Q2y1HjZMECyOUb2X .rough-node .label,#mermaid-svg-Q2y1HjZMECyOUb2X .node .label,#mermaid-svg-Q2y1HjZMECyOUb2X .image-shape .label,#mermaid-svg-Q2y1HjZMECyOUb2X .icon-shape .label{text-align:center;}#mermaid-svg-Q2y1HjZMECyOUb2X .node.clickable{cursor:pointer;}#mermaid-svg-Q2y1HjZMECyOUb2X .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Q2y1HjZMECyOUb2X .arrowheadPath{fill:#333333;}#mermaid-svg-Q2y1HjZMECyOUb2X .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Q2y1HjZMECyOUb2X .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Q2y1HjZMECyOUb2X .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q2y1HjZMECyOUb2X .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Q2y1HjZMECyOUb2X .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q2y1HjZMECyOUb2X .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Q2y1HjZMECyOUb2X .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Q2y1HjZMECyOUb2X .cluster text{fill:#333;}#mermaid-svg-Q2y1HjZMECyOUb2X .cluster span{color:#333;}#mermaid-svg-Q2y1HjZMECyOUb2X div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Q2y1HjZMECyOUb2X .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Q2y1HjZMECyOUb2X rect.text{fill:none;stroke-width:0;}#mermaid-svg-Q2y1HjZMECyOUb2X .icon-shape,#mermaid-svg-Q2y1HjZMECyOUb2X .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q2y1HjZMECyOUb2X .icon-shape p,#mermaid-svg-Q2y1HjZMECyOUb2X .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Q2y1HjZMECyOUb2X .icon-shape .label rect,#mermaid-svg-Q2y1HjZMECyOUb2X .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q2y1HjZMECyOUb2X .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Q2y1HjZMECyOUb2X .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Q2y1HjZMECyOUb2X :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
每一帧开始
向下坠落
是否碰到地面?
本帧结束
消失,并结束本回合
图说 :苹果的流程图比篮筐还短,但它藏着一个设计决策:"漏接"的惩罚不是扣分,而是清场 + 减篮筐。惩罚被放大成了"局面重置",所以玩家的紧张感不是来自分数,而是来自"我还能错几次"。
苹果树:每帧要做两个决定
#mermaid-svg-53csdknZXOgOP3TF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-53csdknZXOgOP3TF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-53csdknZXOgOP3TF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-53csdknZXOgOP3TF .error-icon{fill:#552222;}#mermaid-svg-53csdknZXOgOP3TF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-53csdknZXOgOP3TF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-53csdknZXOgOP3TF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-53csdknZXOgOP3TF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-53csdknZXOgOP3TF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-53csdknZXOgOP3TF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-53csdknZXOgOP3TF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-53csdknZXOgOP3TF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-53csdknZXOgOP3TF .marker.cross{stroke:#333333;}#mermaid-svg-53csdknZXOgOP3TF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-53csdknZXOgOP3TF p{margin:0;}#mermaid-svg-53csdknZXOgOP3TF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-53csdknZXOgOP3TF .cluster-label text{fill:#333;}#mermaid-svg-53csdknZXOgOP3TF .cluster-label span{color:#333;}#mermaid-svg-53csdknZXOgOP3TF .cluster-label span p{background-color:transparent;}#mermaid-svg-53csdknZXOgOP3TF .label text,#mermaid-svg-53csdknZXOgOP3TF span{fill:#333;color:#333;}#mermaid-svg-53csdknZXOgOP3TF .node rect,#mermaid-svg-53csdknZXOgOP3TF .node circle,#mermaid-svg-53csdknZXOgOP3TF .node ellipse,#mermaid-svg-53csdknZXOgOP3TF .node polygon,#mermaid-svg-53csdknZXOgOP3TF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-53csdknZXOgOP3TF .rough-node .label text,#mermaid-svg-53csdknZXOgOP3TF .node .label text,#mermaid-svg-53csdknZXOgOP3TF .image-shape .label,#mermaid-svg-53csdknZXOgOP3TF .icon-shape .label{text-anchor:middle;}#mermaid-svg-53csdknZXOgOP3TF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-53csdknZXOgOP3TF .rough-node .label,#mermaid-svg-53csdknZXOgOP3TF .node .label,#mermaid-svg-53csdknZXOgOP3TF .image-shape .label,#mermaid-svg-53csdknZXOgOP3TF .icon-shape .label{text-align:center;}#mermaid-svg-53csdknZXOgOP3TF .node.clickable{cursor:pointer;}#mermaid-svg-53csdknZXOgOP3TF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-53csdknZXOgOP3TF .arrowheadPath{fill:#333333;}#mermaid-svg-53csdknZXOgOP3TF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-53csdknZXOgOP3TF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-53csdknZXOgOP3TF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-53csdknZXOgOP3TF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-53csdknZXOgOP3TF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-53csdknZXOgOP3TF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-53csdknZXOgOP3TF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-53csdknZXOgOP3TF .cluster text{fill:#333;}#mermaid-svg-53csdknZXOgOP3TF .cluster span{color:#333;}#mermaid-svg-53csdknZXOgOP3TF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-53csdknZXOgOP3TF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-53csdknZXOgOP3TF rect.text{fill:none;stroke-width:0;}#mermaid-svg-53csdknZXOgOP3TF .icon-shape,#mermaid-svg-53csdknZXOgOP3TF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-53csdknZXOgOP3TF .icon-shape p,#mermaid-svg-53csdknZXOgOP3TF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-53csdknZXOgOP3TF .icon-shape .label rect,#mermaid-svg-53csdknZXOgOP3TF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-53csdknZXOgOP3TF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-53csdknZXOgOP3TF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-53csdknZXOgOP3TF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
否
是
每一帧开始
按当前方向移动
是否改变方向?
10% 概率
翻转方向
是否到了掉落时间?
本帧结束
掉落一个苹果
图说 :这是本章唯一带"双重判断"的图,也是全篇最值得琢磨的地方:移动与掉落是两个独立时钟 。方向每帧都可能翻(10%),掉落则严格按 0.5 秒节拍。作者特意说明:判断放在移动之前还是之后都可以------这句话背后是"实现自由度",但玩家感受到的差异几乎为零。能用两种写法都对的设计,说明它足够松耦合。
顺手把它翻译成代码
流程图最大的好处是:它几乎能一行一行地变成 Update()。下面是苹果树的骨架(C# / Unity 风格):
csharp
using UnityEngine;
public class AppleTree : MonoBehaviour
{
public GameObject applePrefab;
public float speed = 1f;
public float leftAndRightEdge = 10f;
public float changeDirChance = 0.1f; // 每帧 10% 概率转向
public float appleDropDelay = 0.5f; // 每 0.5 秒掉一个
private float dropTimer = 0f;
void Update()
{
// 1) 按当前方向移动
Vector3 pos = transform.position;
pos.x += speed * Time.deltaTime;
transform.position = pos;
// 2) 是否改变方向(随机 + 边界强制掉头)
if (pos.x >= leftAndRightEdge) { speed = -Mathf.Abs(speed); }
else if (pos.x <= -leftAndRightEdge) { speed = Mathf.Abs(speed); }
else if (Random.value < changeDirChance) { speed = -speed; }
// 3) 计时器累加,到点掉苹果并归零
dropTimer += Time.deltaTime;
if (dropTimer >= appleDropDelay)
{
dropTimer = 0f;
Instantiate(applePrefab, transform.position, Quaternion.identity);
}
}
}
这段代码在解释什么 :
Time.deltaTime是"上一帧花了多少秒",把它乘进速度里,帧率高低就不会影响移动快慢 ------60fps 和 30fps 下,苹果树一秒走的距离一样。而dropTimer之所以要"累加再归零"而不是"每帧减一",也是同一个道理:用时间做单位,而不是用帧做单位。很多新手原型的"手感随电脑性能漂移",根源就在这里。
顺带说一句"帧":电影时代是 16/24 帧每秒,电视约 30 帧,Unity 里 60 帧每秒意味着每秒 60 幅画面 + 大量"把物体从这一帧搬到下一帧"的数学运算。图 15-3 描述的就是这套运算。
六、小结:本章其实只教了一个动作
作者在结尾说得很平静:数字化游戏可以分解为一系列非常简单的选择和命令;这项工作隐含在本书创建模型的每一步里。
回头看,这一章给你的其实是一个可复用的动作:
#mermaid-svg-AoI25LD0Su12MUQL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AoI25LD0Su12MUQL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AoI25LD0Su12MUQL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AoI25LD0Su12MUQL .error-icon{fill:#552222;}#mermaid-svg-AoI25LD0Su12MUQL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AoI25LD0Su12MUQL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AoI25LD0Su12MUQL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AoI25LD0Su12MUQL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AoI25LD0Su12MUQL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AoI25LD0Su12MUQL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AoI25LD0Su12MUQL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AoI25LD0Su12MUQL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AoI25LD0Su12MUQL .marker.cross{stroke:#333333;}#mermaid-svg-AoI25LD0Su12MUQL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AoI25LD0Su12MUQL p{margin:0;}#mermaid-svg-AoI25LD0Su12MUQL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-AoI25LD0Su12MUQL .cluster-label text{fill:#333;}#mermaid-svg-AoI25LD0Su12MUQL .cluster-label span{color:#333;}#mermaid-svg-AoI25LD0Su12MUQL .cluster-label span p{background-color:transparent;}#mermaid-svg-AoI25LD0Su12MUQL .label text,#mermaid-svg-AoI25LD0Su12MUQL span{fill:#333;color:#333;}#mermaid-svg-AoI25LD0Su12MUQL .node rect,#mermaid-svg-AoI25LD0Su12MUQL .node circle,#mermaid-svg-AoI25LD0Su12MUQL .node ellipse,#mermaid-svg-AoI25LD0Su12MUQL .node polygon,#mermaid-svg-AoI25LD0Su12MUQL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AoI25LD0Su12MUQL .rough-node .label text,#mermaid-svg-AoI25LD0Su12MUQL .node .label text,#mermaid-svg-AoI25LD0Su12MUQL .image-shape .label,#mermaid-svg-AoI25LD0Su12MUQL .icon-shape .label{text-anchor:middle;}#mermaid-svg-AoI25LD0Su12MUQL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AoI25LD0Su12MUQL .rough-node .label,#mermaid-svg-AoI25LD0Su12MUQL .node .label,#mermaid-svg-AoI25LD0Su12MUQL .image-shape .label,#mermaid-svg-AoI25LD0Su12MUQL .icon-shape .label{text-align:center;}#mermaid-svg-AoI25LD0Su12MUQL .node.clickable{cursor:pointer;}#mermaid-svg-AoI25LD0Su12MUQL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AoI25LD0Su12MUQL .arrowheadPath{fill:#333333;}#mermaid-svg-AoI25LD0Su12MUQL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AoI25LD0Su12MUQL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AoI25LD0Su12MUQL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AoI25LD0Su12MUQL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AoI25LD0Su12MUQL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AoI25LD0Su12MUQL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AoI25LD0Su12MUQL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AoI25LD0Su12MUQL .cluster text{fill:#333;}#mermaid-svg-AoI25LD0Su12MUQL .cluster span{color:#333;}#mermaid-svg-AoI25LD0Su12MUQL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AoI25LD0Su12MUQL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AoI25LD0Su12MUQL rect.text{fill:none;stroke-width:0;}#mermaid-svg-AoI25LD0Su12MUQL .icon-shape,#mermaid-svg-AoI25LD0Su12MUQL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AoI25LD0Su12MUQL .icon-shape p,#mermaid-svg-AoI25LD0Su12MUQL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AoI25LD0Su12MUQL .icon-shape .label rect,#mermaid-svg-AoI25LD0Su12MUQL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AoI25LD0Su12MUQL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AoI25LD0Su12MUQL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AoI25LD0Su12MUQL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 不好玩
好玩
一个模糊的点子
列出游戏对象
为每个对象写动作清单
画每帧流程图
翻译成代码
好玩吗?
加内容 · 调参数
图说 :这是把第 15 章的方法论压缩成的一张"工作回路"。它最重要的部分是那条回流箭头:分解不是一次性的仪式,而是每次改玩法都要重跑一遍的循环。第 28 章会带你把这套回路真正跑一遍------届时你会看到篮筐追鼠标、苹果往下掉、苹果树像疯狂炸弹投手一样一刻不停地扔。

而在那之前,请先记住这个反差:人类用一句话让四岁小孩摆好餐具,计算机需要你写下几十条命令------但它永远不会偷懒、不会抱怨、不会在第 70 个小时的加班里摔键盘。 ⌨️