像素猫的第一款游戏:从 0 到可玩 Demo 的 7 天路线
用 7 天把「一只猫在小屋里收拾东西」做成能玩的原型:怎么砍范围、核心循环长什么样、每天必须交付什么,以及第 3 天必须做对的那件小事。
一个人做游戏,第一周最容易死在设定里。我的做法是先把想法压缩成一句话,再用三个问题过一遍:
- 玩家每分钟重复做的动作是什么?
- 这个动作到第 10 分钟会不会腻?如果会,用什么第二个动作救它?
- 我能不能在这周结束前让这个动作真的跑起来?
「像素猫在小屋里收拾东西」听起来很散,过滤之后剩下的是:玩家不断把物品归类放回原位。重复动作是「拿起—判断—放下」,第二动作是「猫会累,累了还硬放就会打翻东西」。这样第一周的目标就具体了:一个房间、十二件物品、一套对错反馈。
核心循环长这样
| 阶段 | 玩家在做什么 | 系统给什么反馈 |
|---|---|---|
| 观察 | 在房间里找散落的物品 | 物品有轻微呼吸动画与轮廓高光 |
| 判断 | 决定它属于哪个架子 | 靠近架子时架子亮起,显示类别图标 |
| 放置 | 按下交互键 | 正确:清脆音效 + 猫耳朵竖一下;错误:物品滑落 |
| 结算 | 完成一轮整理 | 灯变亮一档,猫坐下舔爪,给出用时与失误数 |
这个循环一次 40 到 90 秒,正好是一局。所有系统都为它服务,不为它服务的功能第一周不做。
7 天日程
| 天 | 交付物 | 判据 |
|---|---|---|
| D1 | 一个能走的猫(方块也行) | WASD 移动不卡、不穿墙 |
| D2 | 房间碰撞与相机 | 相机跟随不抖,边界不露黑 |
| D3 | 拾取与放置 | 能拿起 1 个物品并放到 1 个架子上 |
| D4 | 类别判定与反馈 | 对错各 1 种音效与动画 |
| D5 | 12 件物品与计分 | 一局能完整开始与结束 |
| D6 | 替换美术与动画 | 猫有走、待机、放置三个动作 |
| D7 | 打磨与录制 | 能连续通关 3 次并录出 30 秒片段 |
D7 的判据很关键:能连续通关三次才算做完。只通关一次通常意味着你在靠运气掩盖 bug。
第 3 天必须做对的事
第一周唯一容易做错的是拾取判定。新手常见写法是在 _process 里算距离,结果是手感和帧率绑在一起,掉帧时物品会「粘」在手上。正确做法是用 Area2D 的进出信号维护一个候选列表,交互时取最近的那个。
extends Area2D
@export var item_id: StringName
var held := false
func _on_body_entered(body: Node2D) -> void:
if held or not body.has_method("register_nearby"):
return
body.register_nearby(self)
func _on_body_exited(body: Node2D) -> void:
if body.has_method("unregister_nearby"):
body.unregister_nearby(self)
func pick_up() -> void:
held = true
set_deferred("monitoring", false)猫那边只保留一个按距离排序的数组,交互键按下时取第一个还在范围内的物品。这样即使同屏有 30 件物品,一帧也只有一次 O(n) 排序,而不是每件物品各自做射线检测。
不要做的四件事
- 不要做存档。第一周没有值得存的东西,做了只是浪费时间。
- 不要做设置菜单。音量用系统音量,键位固定,等你真的收到抱怨再改。
- 不要做多语言。中文字体先只留一套,字体文件能省下好几 MB。
- 不要提前做美术。D1 到 D4 全部用色块,D6 才替换。先画美术的人通常在第 5 天已经不想做了。
收尾:把 demo 变成可判断的东西
做完之后不要立刻加内容。先找三个没看过这个项目的人玩,只问一个问题:你刚才想做什么,为什么没做成? 答案会直接告诉你第二周该修什么。我的第一轮答案里出现了三次「我不知道这个东西该放哪」,于是我加了架子高亮,而不是加更多物品。
第二周再谈关卡与音效。第一周的目标只有一个:证明这个循环值得被做成游戏。