《迷途之梦》v0.1 · 全面解析
基于逐行读完全部源码 + 完整通关一轮(三轮复跑)之后写的解析,不是根据宣传文案猜的。 所有数值、台词、界面坐标都来自代码;所有「这游戏实际长什么样」都来自playtest-通关实录/里的实机截图。 工程侧的改动指南另见续作开发基础-v0.2.md,这篇只谈它是什么、为什么这么设计、哪里好哪里不对。
一、定位:它到底是个什么游戏
| 维度 | 结论 |
|---|---|
| 类型 | 2D 横版动作(近战连段 + 翻滚闪避)为主,夹一段现实层点击式探索 |
| 手感参照 | 明显是「死亡细胞」那一挂:翻滚无敌帧、三段连击可取消、命中顿帧 + 震屏、空中攻击砸地 |
| 叙事结构 | 三层世界(现实 / 梦境 / 黑屏)+ 道具驱动(药、剑、医书、纸条) |
| 体量 | 完整流程 9 个屏幕、3 段战斗、2 个 Boss、1 段探索,正常玩 10–18 分钟 |
| 血统 | 《有兽焉》同人,主角是被清了记忆的狐狸「慕容雪川(美美)」 |
| 完成度 | 战斗系统 ≈ 完成;叙事 ≈ 骨架;内容量 ≈ 第一章 + 半章 |
一句话概括:它是一个用动作游戏训练场包装记忆悬疑的垂直切片——玩家在梦里被当成死士练,梦里有人给他送剑,现实里有人在骗他,而他自己在一点点发现「我少了一段记忆」。
它最特别的地方不是战斗,而是把「训练」写进了叙事:那些一波一波的敌人不是关卡障碍,而是「有人在训练你」这件事本身。这让"刷怪"有了叙事借口,是很聪明的做法。
二、叙事解构
2.1 三层世界,三种信息权限
现实层(卧室 / 家) 主角视角,可操作,文本量最大
↑ 吃药入睡
梦境层(鹿人店 / 丛林) 主角视角,可操作,战斗都在这
↑ 梦醒 / 黑屏
黑屏层(只有声音) 主角不在场,玩家独占的信息
这是整个叙事最有效的设计:玩家知道的比主角多。 第一章结束时那段黑屏对话(chapter_end.gd:19–29)告诉玩家「有人在执行一个计划、核桃只是传话的、这事对他(主角)不好」,而主角在梦里还在问「你谁啊」。戏剧反讽由此成立——玩家看着主角被操纵,却没法告诉他。
值得注意的是:黑屏层只出现了一次(第一章完)。第二章、第三章再没回去过。这是当前版本叙事上最可惜的地方。
2.2 时间线与事件表
| 时间 | 层 | 事件 | 出处 |
|---|---|---|---|
| 十月 22 日 · 夜 | 现实 | 失眠、药片散落、药瓶写着「安眠」、第十二个翻身 | prologue.gd:8–11 |
| 十月 22 日 | 现实 | 按下 E 吃下药片 | prologue.gd:12 |
| (倒流)七月 1–4 日 | 现实 | 连续几晚做同一个梦:一只鹿喊他「美美」;开始怀疑自己失忆 | prologue.gd:17–31 |
| 七月 4 日 · 夜 | 现实 | 「我……失眠了?」 | prologue.gd:32–34 |
| (快进)十月 22 日 | 现实 | 药效上来了,祝我好梦 | prologue.gd:35–38 |
| 入梦 | 梦 | 空镜头对话:美美自言自语 + 一个「???」塞给他一把剑就跑 | chapters.gd:15–29 |
| 第一章 | 梦 | 鹿人店庭院,5 波"训练";想到「重击」;击败「假面」 | chapters.gd:30–59 |
| 十月 23 日 · 晨 | 现实 | 梦醒,「病情又恶化了」 | chapter_end.gd:9–15 |
| 十月 23 日 · 黑屏 | 黑屏 | 凶的「???」与「核桃」的对话:计划、反攻、人越多越好 | chapter_end.gd:19–29 |
| 十月 23 日 · 白天 | 现实 | 在家里找医书 → 读书 → 夹层纸条(花蕊大夫)→ 入夜 → 吃药(最后一片,四瓶已空) | house.gd:59–132 |
| 当夜 | 梦 | 美美逼问核桃:「我到底在干什么」「那个鹿呢」「我记忆去哪了」 | chapters.gd:73–95 |
| 梦 · 丛林 | 梦 | 野猪 + 藤蔓,击败「丛林石像」 | chapters.gd:124–158 |
| 结束 | — | 「梦到这里就断了。」 | end_card.gd:8–15 |
结构上的巧思:序章用「倒流 → 快进」把十天压缩成三十秒,让玩家先看到"失眠的现在",再看到"失眠是怎么开始的"。这是电影式的时间折叠,放在这种体量的切片里相当奢侈,也很有效——它一上来就把"记忆/时间不可靠"这个主题拍在玩家脸上。
2.3 角色分析
慕容雪川(美美)—— 主角
- 身份:一只狐狸,长期失眠,靠安眠药入睡,正在失去某段记忆。
- 双名结构:现实里叫「慕容雪川」,梦里那只鹿喊他「美美」。名字的分裂就是身份分裂的暗示——梦里的名字比现实的名字更亲昵,说明"梦里那段被清掉的记忆"才是他真正的人生。
- 性格写法:不苦情。台词是「哎啊啊啊,什么时候是个头啊」「欸不是,你说清楚」「你,你你你……那个俩尾巴的猫,你回来!」——暴躁、嘴碎、爱吐槽,靠语气词(哎/欸/额/啊)撑起性格。
- 认知弧(这是全篇最完整的一条线):
「昨晚做了个好奇怪的梦」→「怎么又是这个梦」→「我难道真的失忆了」→「这是?哦,又是这个地方」→「这里到底是哪里啊」→「我到底在干什么」→「我记忆去哪了」。 每章只推进一格,节奏是对的;但第一章到第二章之间几乎没推进(第一章的梦里他只是在打怪)。
- 行动力:他不是被动受害者。第二章是他自己决定去翻医书、自己决定再吃一片药;梦里他主动逼问核桃。这点比很多同类同人主角强。
- 道具依赖:药(睡不着 → 吃药 → 入梦)、剑(梦里别人给的 → 用来打怪)。两个道具都是外来的,暗示他的人生现在由别人供给。
核桃 —— 双尾猫,「???」→ 核桃
- 出场:第一章梦里以「???」出现,说话结巴、紧张(「我是……不不不,你别管我是谁」「啊啊,不不是的,这把剑,拿好」),塞剑就跑。
- 身份揭示:第一章完的黑屏对话里,凶的「???」叫他核桃,所以他=核桃。玩家比主角先知道这个名字。
- 立场:他说「我……我会救你出去」,但黑屏里他同时说「这么久我还是信不过你,毕竟当初的记忆,我也丢了」——他也是失忆者,也是被指使者。他既像朋友,又像看守。
- 叙事功能:他是主角与幕后之间的唯一通道,也是最大的悬念载体(他到底在帮谁?)。
- 文本细节:第二章梦里主角连珠炮逼问,他的回答是「你你先打着,我明天再回答」「(小声嘟囔)如果有明天的话」——他怕的不是主角,是"明天"。这句话是全篇最好的一句台词。
凶的「???」—— 幕后
- 只在黑屏出现一次,说话人颜色定为深红(
#a32222),和白色名字形成敌我区分。 - 话术:「我怎么说你怎么传达就好,我没有理由害你」「什么话这是,咱们不这样做,他一辈子都会活在迷茫中」——典型的以"为你好"包装的操纵。
- 目标:「反攻这种事情,人越多越好」。「反攻」的对象在游戏里从未说明。
- 身份:README 说主角"被梼杌当作死士训练",暗示这位就是梼杌。但——
⚠️ 「梼杌」在游戏代码与全部文本里出现 0 次(我 grep 过)。玩家在游戏内完全不知道有"梼杌"这个存在,这个信息只存在于 README 和操作说明的散文里。也就是说,当前版本的"反派"对玩家而言是空白的。
花蕊大夫 —— 只存在于纸上的知情者
- 出场:第二章书房的书里夹着一张纸条(
house.gd:82–100),署名「花蕊大夫 8月10日」。 - 他提供了三条关键信息:
1. 「你的症状……不,咱们的症状很特殊」→ 他和主角同病; 2. 「我确信的,咱们的记忆被做了手脚」→ 失忆是人为的(第一次把"悬疑"升级成"阴谋"); 3. 「这段记忆,咱们或许保持遗忘,才是最好的」「请你注意安全」→ 他选择了放弃,并警告主角别查。
- 叙事功能:他是"前一个受害者",也是唯一一个给出外部证据的人。有他,故事才从"主角自述"变成"有据可查"。
- 设计遗憾:他只在纸条里活着。第二章结尾有一句主角的独白「花蕊大夫,他的话到底是什么意思」,但主角从来没有去找他——而游戏里主角明明说"明天找花大夫再买一点,顺便问清楚吧"(
house.gd:128)。这是一个现成的钩子,没用。
鹿 —— 全篇最大的悬念
- 出场:只在序章的转述里:「梦里好像有个鹿,喊我名字美美,喊得好亲近」(
prologue.gd:19)。 - 地点:梦里的地方叫「鹿人店」(鹿人的店)。
- 缺席:第一章梦里主角问「你是那个鹿……不对,是个猫?」,第二章梦里又问「那个鹿呢?」——鹿始终没出现。
- 功能:他是"被清掉的那段记忆"的人格化。玩家的疑问和主角一样:那只鹿是谁,为什么喊他美美。
- 评价:这是全篇埋得最好的钩子——它甚至不需要露面,靠称谓和地点的名字就成立了。
假面 / 丛林石像 —— 两个「不是角色」的 Boss
- 假面:黑袍 + 白色面具 + 大刀,名字就叫「假 面」,二阶段红眼。他没有一句台词。
叙事上他不是敌人,是"训练用的假想敌"——被打死之后没有任何反应,直接切梦醒。"假面"这个名字本身就是暗示(面具/伪装),但游戏没有用它。
- 丛林石像:石头人,落石 + 石拳。同样没有台词,唯一相关文本是主角的一句吐槽:「不是,有猪我认了,我问你这是啥?」(
chapters.gd:155–157)。
这句吐槽其实交代了它的叙事地位:它不是反派,是"梦开始失控"的证据——训练场里突然出现了不该有的东西。
2.4 已埋未收的钩子(清单)
| # | 钩子 | 埋在哪 | 现状 |
|---|---|---|---|
| 1 | 谁动了记忆 | 花蕊纸条、核桃对话 | 未收(只说"被做了手脚") |
| 2 | 「反攻」是什么、反谁 | 黑屏对话 | 未收 |
| 3 | 鹿是谁、在哪 | 序章 + 两章台词 | 未收,且是全篇最强钩子 |
| 4 | 假面是谁/是什么 | Boss 名 | 未收(无台词) |
| 5 | 核桃到底帮谁 | 全程 | 部分揭示(他"也丢了记忆") |
| 6 | 「美美」这名字的来历 | 序章 | 未收 |
| 7 | 药:四瓶吃完、最后一片 | 序章 + 第二章 | 未收,但是很好的"倒计时"装置 |
| 8 | 花蕊大夫本人 | 纸条 | 未收(主角说明天去找他) |
| 9 | 白天的现实层和梦里的时间是否同步 | 10/22 → 10/23 | 未说明 |
九个钩子,零个回收——这对一个"垂直切片"来说是合理的(本来就是留白等人填),但如果继续做,必须优先收 1、3、5。
2.5 叙事结构的总评
做得好的: 1. 三层视角 + 信息不对称,一次黑屏对话就把"悬疑"升级成"阴谋"。 2. 道具驱动:药(现实→梦)、剑(梦里被塞的)、医书+纸条(现实里的证据)。四个道具各自承担一个叙事功能,没有堆砌。 3. 时间折叠(倒流/快进)符合"记忆不可靠"的主题,不是花活。 4. 文本克制:单句最长不超过 46 字(对话系统硬上限),没有大段说明文,读起来像轻小说而不是设定集。 5. 主角有性格:暴躁、嘴碎、会吐槽,不是沉默工具人。
做得不够的: 1. 第一章叙事空心:除了开头 13 句和 Boss 名字,整章没有任何剧情推进。它是纯战斗关。 2. 丛林章文本塌陷:3 波怪 + 1 句吐槽 + 1 个 Boss,叙事密度接近 0。 3. 反派不存在:梼杌 0 次出现,凶的「???」只有一段黑屏。玩家打完通关也不知道自己在跟谁对抗。 4. 两个 Boss 都没台词:作为"叙事节点"它们不合格,只能算"玩法节点"。 5. 黑屏层只用了 1 次:这个最强的手法被浪费了。
三、主角能力系统
3.1 能力全景
| 能力 | 解锁条件 | 数值 | 手感要点 |
|---|---|---|---|
| 移动 | 开局 | 430 px/s,加速 3600 | 空中加速度 2000,空中不粘滞 |
| 跳跃 | 开局 | 初速 −930,重 2500 → 跳高 173,滞空 0.74s | 长按更高、短按矮跳(松手截断到 0.42 倍) |
| 二段跳 | 开局 | −837(0.9 倍) | 空中一次;起跳/二段跳都会刷新"空中翻滚"次数 |
| 地面翻滚 | 开局 | 0.34s,速度 660,无敌 0.05–0.26s,CD 0.10 | 转一圈(rig.rotation 一圈)+ 残影,是最核心的生存手段 |
| 空中冲刺 | 开局 | 1150 速 × 0.15s,无敌 0.18s,CD 0.31 | 一次跳跃周期一次;无敌比动作还长 |
| 三段轻击 | 必须先按 E 拔剑 | 1/1/2 伤,判定框 118/124/140 宽 | 后摇 32% 处可取消接下一段或翻滚 → 实测 ≈6.1 伤/秒 |
| 重击 | 记忆碎片 | 3 伤,245×165,眩晕 1.0s(Boss 0.35s) | 前摇 0.30s 很长,命中把人钉住 1 秒;后摇 50% 可接重击 |
| 破梦 | 完美闪避后 2.5s 内按 J | 5 伤,360×260,无敌 1.15s,CD 10s | 动作 1.04s < 无敌 1.15s → 全程无敌还多 0.11s 安全余量 |
| 斩惑 | 完美闪避后 2.5s 内按 K(需碎片) | 6 伤,绕身 400×96,CD 10s | 0.5s 无敌,最后 0.26s 后摇完全暴露且不能取消 |
| 空中砸地 | 开局 | 落地半径 130、2 伤、击退 420 | 不需要拔剑也能用,是前期最强清群手段 |
| 完美闪避 | 开局 | 慢动作 0.32×、0.42s,窗口 2.5s | 判定 _roll_t ∈ [0.02, 0.26],比无敌帧还早 0.03s |
3.2 状态机
IDLE ⇄ RUN
↓ 跳 ↓ 翻滚 ↓ 攻击
JUMP/FALL ROLL(0.34s) ATTACK(前摇→判定→后摇)
↑ ↓ 结束 ↓ 受击
└──────────── IDLE HURT(0.26s)
↓ 血归零
DEAD
三个设计细节值得记: 1. 攻击中不能跳(跳跃只在 _do_move 里处理)→ 攻击只能"滚取消"或"接下一段",没有跳取消。 2. 翻滚在地面是"转一圈"(rig.rotation = _roll_dir * TAU * ease_out(k)),在空中是"冲刺"——两者共用一个状态,靠 _dash_air 区分。 3. 受击不打断翻滚:hurt() 先判完美闪避、再判无敌帧,所以"在翻滚窗口里被判定命中"永远不吃亏。
3.3 手感参数(这是它最像"成熟动作游戏"的地方)
| 机制 | 实现 | 评价 |
|---|---|---|
| 命中顿帧 | Engine.time_scale = 0.02,用真实时间计时,可叠加取最晚 | 3–5 帧级别的短停,打击感来源 |
| 慢动作 | 完美闪避 0.32×、破梦 0.22×、Boss 死 0.25× | 与顿帧争夺同一个 time_scale,没有引用计数(见问题) |
| 屏幕震动 | trauma 制,trauma² × 26px,每秒衰减 1.6 | 平方衰减让震动"开头狠、尾巴软",比线性好 |
| 输入缓冲 | 攻击 0.16 / 跳 0.12 / 重击 0.16 / 翻滚 0.14 | 偏短,是"按了没反应"的主要来源 |
| 土狼时间 | 0.10s | 惯例值 |
| 受击无敌 | 0.75s | 防连死 |
| 击退 | 玩家被击退 240–420,敌人 250–780 | 敌人被击退出屏幕会被 _keep_in_view 拉回 |
3.4 解锁曲线(设计意图很明确)
开局:只能走跳滚 + 空手(拔剑后才能打) ← 教学关教"基本功"
教学四:完美闪避 ← 教"迎着打"
教学五:破梦 ← 给奖励
第一章前三波:平A + 砸地 ← 建立输出节奏
记忆碎片:解锁重击(控制)+ 斩惑(爆发) ← 中期给"对策"
Boss:检验
问题:这个曲线把最强的控制(重击眩晕 1 秒)和最强的爆发(斩惑 6 伤)都放在了第一章中途,而最难的杂兵波(第三/四/五波)在它们之后。结果实际难度是"先难后易",Boss 反而偏软。
3.5 能力系统的三个真问题
① 翻滚通吃 0.34s 里 0.21s 无敌、CD 只有 0.1s、不消耗任何资源 → 数学上 48% 的时间可以无敌。 所有敌人(含 Boss)的攻击都能被"滚过去"解决,而"滚过去"还额外给完美闪避奖励(慢动作 + 2.5s 窗口 + 破梦)。 这导致最优解永远是同一个:看到前摇就朝攻击滚。 游戏没有给出"不该滚"的理由。
② 完美闪避奖励的是"挨打" 判定窗口 [0.02, 0.26] 比无敌帧 [0.05, 0.26] 还早 0.03s,意思是"刚滚出去就挨打"也算成功。 设计意图是"奖励迎击",实际效果是鼓励玩家把翻滚当成攻击键:往敌人身上滚,赌判定。
③ 攻击缓冲 0.16s 与翻滚 0.34s 不匹配 完美闪避发生时玩家还在翻滚中段,本能地立刻按 J,缓冲会在翻滚结束前过期 → "按了没反应",要再按一次才出破梦。这是实机里最容易劝退新手的细节(player.gd:156)。
四、敌人图鉴
4.1 数值总表
| 敌人 | HP | 体型 | 速度 | 攻击 | 伤害 | 判定 |
|---|---|---|---|---|---|---|
| 影卒 | 3 | 1.45× | 132 | 走近 96px → 举刀 0.42s → 突刺 470 | 1 | 水平 48 / 纵向 62 |
| 浮瞳 | 2 | 1.4× | 190 | 保持 330px,蓄力 0.5s → 弹幕 460 | 1 | 弹丸 32px |
| 奔角 | 4 | 1.5× | 70 / 冲锋 900 | 520px 内蓄力 0.7s → 冲锋 → 撞墙硬直 1s | 1 | 水平 58 / 纵向 56 |
| 野猪 | 7 | 1.7× | 同奔角 | 同奔角 | 1 | 同奔角 |
| 藤蔓 | 3 | 1.2× | 0(不动) | 220px 内 0.55s 预警 → 抽打 → 减速 6s | 1 + 减速 | 不可接触 |
| 木桩 | 9999 | 1.15× | 0 | 0.9s 举刀 → 0.26s 挥 | 0 | 69px |
| 假面 | 26 | 1.55× | 96 / 冲 980 | 横扫 / 跃击地震 / 2–3 连突进 / 二阶段扇形 5 连 | 1–2 | 见下 |
| 丛林石像 | 33 | 1.9× | 0 | 落石 ×3 / 石拳 | 2 | 落石 74px / 石拳 270px |
4.2 设计语言:四个小怪 = 四种"考试题"
| 敌人 | 考什么 | 预警方式 | 颜色语言 |
|---|---|---|---|
| 影卒 | 近战时机 | 举刀 + 地面红色箭头(0.42s) | 深紫黑 + 紫 |
| 浮瞳 | 弹幕走位 | 眼睛发光 + 红色瞄准线(0.5s) | 深紫 + 亮紫 |
| 奔角 | 冲锋闪避 | 下蹲 + 6 段红色虚线 | 深褐 + 橙 |
| 野猪 | 同奔角但更耐打 | 同奔角 | 棕 + 米黄 |
| 藤蔓 | 距离管理(不要贴脸) | 藤蔓摆动 + 红色挥砍弧 | 绿 + 暗红 |
共同设计语言:
- 所有攻击都有 0.4–0.9s 的前摇,并且用红色画预警(箭头 / 虚线 / 弧线 / 圈)。
- 所有小怪都是"接近 → 长前摇 → 单次判定",没有多段、没有持续判定。
- 全部程序化绘制,没有一张贴图:身体是
draw_line/draw_circle/draw_colored_polygon拼的,靠body_color()+accent_color()两个函数区分身份。
这套语言的优点:读得懂。玩家看颜色就知道"这个要来了"。 缺点:全是"单次判定",所以翻滚无敌帧通吃;没有"反翻滚"的设计(持续判定 > 0.28s、抓取、无视无敌帧的招)。
4.3 Boss 设计
假面(26 血,二阶段)
| 招式 | 时间轴 | 判定 | 安全解 | 危险度 |
|---|---|---|---|---|
| 横扫 | 举刀 0.55s → 只在 t=0.55 单帧判定 → 收 0.6s | 圆心身前 143、半径 236 | 站 >380px / 滚过去 / 站背后 | 中 |
| 跃击地震 | 0.35 蓄 → 起跳 → 落地放左右两道地面冲击波(520 速) | 只有冲击波有伤 | 跳过 / 翻滚 / 站远 | 低 |
| 突进 | 蓄 0.32s → 980 速冲 0.42s,2 连(二阶段 3 连) | 水平 120 / 纵向 120 | 必须翻滚(跳跃只有最高点免疫) | 高 |
| 扇形弹幕 | 0.55 蓄 → 5 发 ±0.4rad、430 速 | 每发 32px | 翻滚 / 横向跑 | 中 |
| 二阶段 | 半血强制 _end_attack(0.9) | — | 0.9 秒白给窗口 | — |
决策逻辑(mask_boss.gd:127–159):
- 横扫永远在选项里;
- 距离 >220 → 突进权重 ×2(站远会勾引冲刺,这是很好的"反龟缩"设计);
- 距离 <520 → 加入跃击;
- 二阶段额外加"弹幕 + 一次横扫"。
最漂亮的一处:横扫是单帧判定。这意味着"看起来最吓人的大刀横扫"其实最好躲——站远、滚过去、甚至等 0.55s 之后走进去都行。这是一个反直觉但可学习的设计。
最不漂亮的一处:它没有一句台词。作为第一章的收尾,它只是一个"会动的血条"。
丛林石像(33 血)
- 招式只有两招:落石 ×3(0.9s 预警圈,命中 74px、2 伤)和石拳(0.5s 后 270px 内 2 伤)。
- 它没有二阶段:虽然继承自
MaskBoss,但_think被完全覆写,MaskBoss里那段「半血进二阶段」的检查根本不会执行。 - 血量比假面还厚 7 点,招式却更少 → 体验是"磨"而不是"难"。
- 叙事上它连反派都不是,只是"梦里出现了不该有的东西",主角还吐槽了一句。
4.4 敌人设计总评
优点:
- 用颜色 + 前摇建立了统一的"可读性"语言,五个人形怪一眼能分清。
- 每个怪都有明确的考试点(时机/走位/闪避/距离),不是纯数值堆叠。
- 波次编排有意图:教学(木桩)→ 单兵种(影卒)→ 混合(+浮瞳)→ 冲锋(奔角)→ 混战(全上)。
问题: 1. 没有反制手段:不反翻滚(持续判定)、不反跳跃(对空)、不反重击锁(眩晕抗性)。 2. 远程只有一种(浮瞳的直线弹),没有追踪/范围/延迟爆炸。 3. 没有精英怪:从影卒到 Boss 之间缺一档"血厚 + 有特殊机制"的敌人(野猪只是血厚)。 4. 藤蔓的减速是唯一"状态异常",但惩罚过重(见下)。
五、地图与场景
5.1 世界尺寸与镜头
| 项 | 值 | 说明 |
|---|---|---|
| 设计分辨率 | 1920×1080 | 窗口 1280×720,canvased 拉伸 |
| 战斗场地 | x 0–1920,地面 y=780,左右墙 x=−30 / 1950 | 2400 宽的地面碰撞体 |
| 玩家活动范围 | x 90–1830 | 为了不被镜头裁掉而收窄 |
| 相机 | zoom 1.25,可见宽 1536,中心只能落 768–1152 | 所以场地两端各 384px 是"镜头死区" |
| 敌人夹取 | _keep_in_view() 把怪夹在镜头内 ±44px | 防止怪被击退出画面 |
| 坠落死亡 | y > 1500 | 实际上没有落坑地形 |
这是一个纯一维的战场:没有平台、没有高低差、没有可破坏地形。所有战斗都在一条水平线上解决。 这是"垂直切片"的合理取舍(验证手感优先),但也意味着地图本身不参与战斗设计——玩家没有"上高台躲冲锋"之类的空间解法。
5.2 现实层「家」的空间设计(第二章)
这是全游戏唯一有"空间"的地方:
┌──── 客厅(3 扇门)────┐
房间 ←────────┤ 厨房 书房 ├────────→ 房间
(床/窗/床头柜) └──────────────────────┘ (书架/书桌/台灯)
| 房间 | 交互物 | 平台(可跳上去) | 叙事功能 |
|---|---|---|---|
| 房间 | 床(走到床边自动睡)、门 | 床面 780,730 / 床头柜 | 起点 + 终点 |
| 客厅 | 3 扇门 | 沙发、茶几 | 枢纽 |
| 厨房 | 门 | 整排橱柜台面 | 纯装饰(没有事件) |
| 书房 | 书架上的蓝色医书(E 查看) | 书桌 | 本章唯一目标 |
- 单向平台:家具顶面是
one_way_collision平台,可以跳上去、按 S 掉下来(house.gd:266–282)。 - 空间复用:四个房间共用同一套墙面/地板绘制(
_room_shell),只是家具和门不同。这是"低成本内容"的正确做法。 - 门的连接:
_go_through()会找目标房间里"回源房间"的那扇门,出生在它旁边(house.gd:325–332)——保证了空间连续性,走进客厅再从客厅回房间,位置是对的。
评价:这套空间设计是有效的,厨房"有房间但没内容"是唯一明显的浪费(可以放一个日记/道具/彩蛋)。
5.3 背景图的对齐方式(很实用的一招)
ih = 1920 * tex_h / tex_w # 按 1920 宽等比缩放后的图高
top = 780 - 0.86 * ih # 图内 86% 处压到地面线 y=780
鹿人店(474×296)和丛林(2560×1600)两张图,算出来都是 ih≈1200、top≈−252,图底都被 y=780 以下的程序化沙地盖住。 所以换背景只要保证"图里的地面在 86% 高度",就能直接替换;不在 86% 就要改 PHOTO_GROUND。 这是一个聪明的约定(美术只需要记住一个比例),但代码里没写成可配置字段,是留给下一章的坑。
5.4 场景切换的节奏
标题(黑)→ 序章(卧室,暗)→ 入梦白幕(白,3.2s 极慢揭开)
→ 教学(鹿人店,暖)→ 第一章(同背景)→ 梦醒(白 → 白天房间)
→ 黑屏对话 → 章节卡 → 第二章(家,暖褐,压暗)→ 读书(音乐切 reading)
→ 入夜(全屏蓝调 0.45)→ 吃药(白)→ 梦境(鹿人店夜)→ 灰黑过场 → 丛林(亮绿)
→ 结束卡(黑)
节奏设计得很清楚:现实层用暗色 + 慢节奏;梦境用亮色 + 快节奏;过场用白/黑硬切。 "入梦白幕"用了 3.2 秒极慢揭开(配合 Sfx drone 音高从 0.7 升到 1.0),是全游戏最好的一段过渡。
六、视听表现
6.1 美术:几乎全程序化
| 资源 | 类型 | 说明 |
|---|---|---|
sprites/meimei.png | 位图 | 主角,缩到 150px 高,靠 scale/rotate/skew 演动作 |
sprites/sword.png | 位图 | 剑,独立一层,拔剑/持剑/挥砍角度由代码算 |
bg/lurenshop.webp、bg/jungle.jpg | 位图 | 两张背景 |
art/huarui_ghost.png | 位图 | 花蕊大夫虚影(读纸条时从右往左擦出) |
fx/*.png | 小贴图 | ring / star / streak / dust / berry / orb / boss |
| 所有角色(敌人/Boss) | 代码绘制 | 没有一个贴图,全靠 draw_* |
| 所有 UI | 代码绘制 | HUD、菜单、对话框、结束卡全是 draw_string / draw_rect |
| 卧室/客厅/厨房/书房 | 代码绘制 | house.gd 的 _draw() 有 800 行 |
这是典型的"一个人做完整游戏"的资源策略:用程序化换美术量。好处是零素材依赖、可无限调整;坏处是风格上限低(敌人全是色块拼的)。
主角的"纸片人"做法值得单独说:sprite_rig.gd 用一张狐狸立绘 + 5 个变换量(bob / push / rot / sx / sy)演出跑、跳、落、滚、攻、受击。翻滚是"整体旋转 360°",跑步是"压扁 + 上下浮动 + 前倾"。这是很便宜的动画方案,效果在实机里不违和(因为玩家注意力在怪和刀光上)。
6.2 后处理:一个 shader 管所有气氛
fx/post.gdshader 有 15 个 uniform,覆盖了:暗角、颗粒、色差、扫描线、去饱和、梦境扭曲、亮度、色调、闪白、聚光(spot)。
实际被代码用到的只有 9 个:
wave(梦境扭曲)→ 入梦、死亡重入、读书恍惚desaturate(去色)→ 同上vignette_strength(暗角)→ 同上flash/flash_color(闪白)→ 捡碎片spot_on/spot_white/spot_center/spot_radius(聚光)→ 破梦/斩惑的"世界变白只剩角色"
聚光是这套后处理里最亮眼的设计:破梦触发时,整个画面被压成白色,只有主角那一块保持彩色,配上红色「破!梦!」大字——这是全游戏最"贵"的一个瞬间,而且是用 10 行 shader 实现的。
6.3 音效:全合成 + 3 个采样
| 来源 | 内容 |
|---|---|
| 数学合成(15 个) | hit / hit_heavy / whoosh / jump / land / roll / hurt / shatter / death / pickup / shot / ui / roar / slam / heartbeat |
| 外部 mp3(4 个文件,8 条切段) | swing(轻/重/斩惑)、draw(拔剑)、hit_enemy(受击/死亡/Boss 死)、break_hit(破梦) |
| BGM(3 首 wav) | calm(43.7s)/ battle(31.1s)/ reading(58.2s),强制循环 |
| 环境 drone | 8 秒合成低频(55/82.5/110Hz + 噪声 + 低通),开机即响,贯穿全程 |
合成音效的做法:_wav() 生成 16bit 单声道 PCM,用正弦扫频 + 噪声 + 包络拼。例如:
hit:噪声 0.09s(5200Hz 低通)+ 190→90Hz 正弦pickup:C5-E5-G5 三音上行(523.25 / 659.25 / 783.99)roar:0.85s 的 78→46Hz 扫频 + 700Hz 噪声
问题:4 条挥剑切段的 from 全是 0.0,也就是轻击/重击/斩惑听起来是同一段开头的变调。这是"先取开头,等听出好位置再改"的临时状态,但一直没改。
6.4 表现力清单(这游戏的"爽点"都在这)
| 效果 | 实现 | 触发 |
|---|---|---|
| 刀光月牙 | SlashArc:22 段弧 + 拖尾 + 前缘高光 | 每次攻击 |
| 命中火花 | HitSpark:粒子,暖色下坠/冷色漂浮 | 命中 |
| 翻滚残影 | AfterImage:紫色剪影拖影 | 翻滚 |
| 屏幕震动 | Feel.shake trauma² | 命中/受击/Boss |
| 顿帧 | time_scale 0.02 | 命中 |
| 慢动作 | time_scale 0.32 | 完美闪避/破梦/Boss 死 |
| 闪白 | FlashLight 全屏 0.35s 淡出 | 受击/复活/捡碎片 |
| 死亡插曲 | DeathInterlude:水面浮起 → 床头桌/倒药瓶/散药片一闪 → 沉回 | 死亡 |
| 破梦聚光 | 后处理 spot + 红色艺术字 | 破梦 |
| Boss 收尾 | 慢动作 → 白圈收缩 → 全屏白 → 灰 → 黑 | 击败 Boss |
最值得学的是「死亡插曲」:死亡不是重开,而是"浮出水面 → 看到现实床头桌 → 沉回梦里"。 它把"读档重来"变成了叙事事件,而且右下角还记「第 N 次」——用 UI 把死亡次数变成了氛围。这是整个游戏最有设计感的一处。
七、UI 分析
7.1 层级与设计语言
所有 UI 都是手绘 + 绝对坐标(1920×1080),没有用 Control 的锚点布局。统一的视觉语言:
- 字体:正文微软雅黑(
msyh.ttc),标题黑体(simhei.ttf)。标题字重更粗、更"方正",用于大字卡。 - 颜色:米白
#f5f0e4系为主,金色#ffd889表示"可交互/选中",红色表示危险/Boss,浅橙#f2ae6a表示主角说话。 - 装饰:极简。几乎没有边框、底板、图标。整个 UI 像"电影字幕"而不是"游戏界面"。
- 动效:淡入淡出为主,字有"逐字浮现"(标题)和"随机抖动"(日期卡)。
7.2 战斗 HUD(ui/hud.gd,1–166 行)
实机:playtest-通关实录/19_boss_appear.png、24_假面本体.png

| 元素 | 位置 | 字号 | 颜色 | 信息优先级 |
|---|---|---|---|---|
| 血量(5 个菱形,18×22) | 左上 (52+i×40, 54) | — | 金 #ffd889 / 灰 | 高 |
| 记忆碎片 | 右上 (w−210, 64) | 26 | 淡紫 | 中 |
| 连击数(≥3 才显示) | 右侧 (w−300, 200) | 72 + 24 | 金 | 低(纯氛围) |
| 波次大字 | 中央 y=300 | 62 | 米白 | 高(2 秒后消失) |
| Boss 血条 | 底部 y=980,宽 760 | 16 高 | 一阶段 #d0455c / 二阶段 #ff2f6a | 高 |
| Boss 名字 | 血条左上 | 26 | 米白 | 高 |
| 「二阶段」标签 | 血条右上 | 22 | 红 | 中 |
| 破梦/斩惑提示 | 底部 y=1040 | 30 + 20 | 金 | 中 |
| 冷却条 | 底部 y=1046,240×12 | — | 蓝 | 中 |
| 操作提示 | 底部 y=1020 | 26 | 灰白 | 中 |
| 死亡计数 | 右下 y=1060 | 20 | 淡紫(alpha 0.45) | 极低(氛围) |
优点:
- 血量用菱形而不是心形/条状,和"梦境/碎片"的视觉语言统一。
- 连击数只在 ≥3 时出现,不干扰常规战斗。
- 死亡计数刻意做得很淡(alpha 0.45),是"氛围"而不是"数据"。
- Boss 血条的出现本身就是"进入阶段"的信号,不需要额外提示。
问题: 1. 底部拥挤:y=1020(提示)、1040/1072(破梦提示)、1046(冷却条)、1060(死亡计数)四套东西共享底部 60px,同时出现会叠字。 2. 没有"受伤闪红"的全屏反馈——只有角色闪白 + 震屏,血量变化靠左上角菱形消失,注意力在角色身上时容易没注意到自己快死了。 3. 碎片计数在第二章之后没有意义(没有新碎片可捡,但数字一直挂着)。 4. 所有元素都是绝对像素坐标,换分辨率(非 16:9)会错位(靠 canvas_items 拉伸兜着,但 HUD 是被拉伸而不是重新排版)。
7.3 对话系统(scenes/dialogue.gd)
实机:19_boss_appear.png(主角说话,名字浅橙)

- 没有对话框底板,纯文字居中压在画面下方:名字 y=858(26px)、正文 y=912(34px)、提示 y=988(20px)。
- 自动折行:每行最多 46 字,超出换行(最多显示两行,行高 42px)。
- 打字机:33 字/秒,按 E/Enter/空格 可以"先打完"再"下一句"(两次按键)。
- 自动推进:每句停留
0.95 + 0.075 × 字数秒(约 2–4 秒)。 - 说话人颜色:默认浅橙(主角),可用
"color"覆盖(???=白,凶的???=深红,书本内容/纸条=蓝)。 - 每句都进历史记录(U 键可翻)。
设计评价:
- 优点:极简、不挡画面、有电影感;自动推进让玩家可以"只看不按";颜色区分说话人是低成本的高效手段。
- 问题:
1. 无底板 → 可读性依赖背景。在丛林这种高饱和亮绿背景上,米白 34px 文字对比度偏低(实机 21_boss_appear 那张就能感觉到)。 2. 不能"整句回看"(只能整段历史),也没有"跳过全部"。 3. 46 字折行是按字数而不是像素算的,中英混排会不准。 4. 名字和正文都是居中,长台词居中读起来比左对齐累。
7.4 菜单系统(三套并存,是个隐患)
实机:25_暂停菜单.png、26_存档面板.png


| 菜单 | 入口 | 项数 | 风格 |
|---|---|---|---|
PauseLayer | 战斗关 Esc | 7 | 全屏压暗 0.86,居中列表,选中项金色 + ▶◀ |
SettingsUI | 非战斗场景 Esc | 5 | 同样的居中列表,layer 190 |
SavePanel | 上面两个菜单里进 | 2×2 卡片 | 全屏压暗 0.9,卡片选中金色边框 |
History | 任意处按 U | — | 右侧 RichTextLabel,最近 24 条 |
暂停菜单:极简文字,无图标;↑↓ 选择、Enter 确认、Esc 继续、Q 回标题。 存档面板:2×2 卡片(720×300,间距 40),每格显示章节名 / 进度 / 血量菱形 / 碎片数 / 时间戳 / 游玩时长。 历史对话:U 打开,显示最近 24 条,带说话人颜色。
评价:
- 风格统一:都是"压暗 + 居中文字 + 金色选中",视觉上很干净。
- 信息密度合适:存档卡一屏四格,能扫到全部槽位。
- 但三套菜单的键位逻辑不统一:
PauseLayer用 InputMap 之外的裸 keycode;SavePanel的↑和↓行为完全相同(都跳两格),方向键上下其实是坏的(只能用←→在同排移动)。实机截图底部写着「方向键 / 鼠标 选择」,鼠标可用,键盘半残。 Esc的语义分裂:战斗中Esc开/关菜单;现实层Esc直接回标题(没有确认);标题页Esc什么都不做。- 没有"继续游戏":标题页进去只能从头开始,读档必须先进入关卡再按 Esc。
7.5 标题与结束卡
- 标题:「迷 途 之 梦」四个字逐字浮现(132px,间距 132,带暖色光晕),月亮 + 屋脊剪影 + 狐狸立绘,副标题「一个关于记忆的训练梦境」,底部「按任意键开始」+ 版本号。气质最好的一屏。
- 结束卡:黑底 + 呼吸光 + 6 行文字逐行淡入,「梦到这里就断了。」→「——垂直切片 · 完 ——」→ 两行开发者说明 →「按任意键返回标题」。文字是写死的,多结局要参数化。
7.6 UI 问题总清
| 严重度 | 问题 |
|---|---|
| 中 | 对话框无底板,亮背景下可读性差 |
| 中 | HUD 底部四套信息共享 60px,会叠 |
| 中 | 存档面板 ↑↓ 导航失效(都 +2) |
| 中 | 缺"继续游戏"(标题页无法读档) |
| 低 | 碎片计数在后续章节失去意义 |
| 低 | 受伤时缺少全屏反馈,血量变化容易被忽略 |
| 低 | 三套菜单键位逻辑不统一;Esc 语义分裂 |
| 低 | 全 UI 绝对坐标,非 16:9 靠拉伸 |
八、系统骨架(一句话版)
- 状态:
GameState(血量 5 / 碎片 / 死亡数 / 章节 / 解锁 / flags / 游玩时长 / 对话历史) - 存档:4 格 JSON 写在 exe 同级,字段
version/hp/shards/deaths/heavy/chapter_id/wave/boss/time/stamp/chapter/progress - 章节:
Chapters.DATA一张表驱动波次/背景/对话/Boss 类型 - 流程:
main用代码 new 出 9 个屏幕,靠信号串起来(finished/pressed/chapter_requested) - 手感:
Feel直接改Engine.time_scale(顿帧 0.02 / 慢动作 0.32),trauma 制震屏 - 音效:
Sfx20 路播放池 + 15 个合成音色 + 8 条采样切段 + 3 首 BGM + 1 条 drone - 后处理:一个
post.gdshader15 个 uniform,代码实际只喂 9 个
九、综合评价
做得好的 5 件事
1. 手感是"懂行"的。顿帧用真实时间计时、震屏用 trauma² 衰减、输入缓冲 + 土狼时间、翻滚帧数精确到 0.05–0.26——这不是"能跑就行"的实现,是按动作游戏标准调的。 2. 死亡插曲。把"读档重来"变成"浮出水面看一眼现实 → 沉回梦里",还顺手把死亡次数做成氛围。这是全游戏最聪明的设计。 3. 三层叙事 + 一次黑屏对话。信息不对称用得干净,没有靠大段旁白解释。 4. "训练"作为叙事借口。让刷怪这件事在故事里成立,而不是"关卡就是这样"。 5. 零素材依赖。除了 5 张图 + 4 个音频,全部程序化生成——这让它能在任何机器上跑,也让后续改数值/改颜色零成本。
最该改的 7 件事(按影响排序)
1. 藤蔓的减速是死亡螺旋:6 秒 + 禁翻滚 + 没法解除,而丛林有 3 只冲锋野猪。这是唯一一个让玩家觉得"这游戏不讲理"的地方(实测 15 连死)。 2. 翻滚通吃:无敌 48% 覆盖率 + 无消耗 + 完美闪避奖励,导致没有第二个解法。需要"反翻滚"(持续判定/抓取)或"翻滚成本"(体力/层数)。 3. 章节间不回血:第一章打完剩 1 血,第二章整章带着 1 血打,且没有回血手段。 4. 叙事在战斗章里断档:第一章除了开头 13 句没有任何剧情,丛林章几乎没文本,两个 Boss 都没台词。战斗章也需要"每波一句话"级别的推进。 5. 反派缺席:梼杌 0 次出现,凶的「???」只有一段黑屏。玩家通关后不知道自己在对抗谁。 6. Boss 太"功能化":假面没有台词,石像没有二阶段且血量比假面还厚。Boss 需要"人格"或"机制"至少占一个。 7. 缺"继续游戏"与章节选择:标题页无法读档,体验上像"开发者版本"。
和同类比的定位
- 手感目标明显是《死亡细胞》(翻滚无敌 + 连段取消 + 顿帧),完成度大约到了"能玩得爽"的 70%。
- 叙事野心接近《OMORI》/《去月球》那种"现实层 + 内心世界"的双层结构,但目前只搭了骨架。
- 它现在最像的是:一个做完战斗系统、刚写完第一章剧本、还没开始填内容的独立游戏 demo。
十、如果继续做,最值得先动的 5 件事
| 顺序 | 事 | 为什么 |
|---|---|---|
| 1 | 藤蔓减速改短(6s → 2.5s)且允许翻滚,或改成"挣脱" | 直接消掉唯一的难度断崖,成本 3 行 |
| 2 | 每章开场回满血 + 加一个回血道具(药片) | 让"药"这个道具在玩法上也成立,同时解决跨章 1 血开局 |
| 3 | 给战斗章补"每波一句话"的叙事 | 第一章/丛林章现在叙事是空的,加 5–8 句就能把"被训练"这件事讲实 |
| 4 | 让凶的「???」再出现 1–2 次(黑屏/梦中低语) | 把"反派"从空白变成存在,成本极低(复用黑屏对话) |
| 5 | 石头 Boss 加二阶段(抄假面的扇形弹幕)或降到 26 血 | 让它从"磨"变成"战" |
*附:实机证据在 playtest-通关实录/(含暂停菜单、存档面板、Boss、对话、各场景); 工程侧改动指南在 续作开发基础-v0.2.md。*