项目设置
Sep 2
为什么"设置"先于"代码"?因为分辨率、格子数、按键名全都会变成代码里的常量和字符串。先在设置里定下来,代码只要抄一次;反过来先写代码再改设置,每个用到的地方都要改。
目录先建,场景后建
新建项目(渲染器选兼容,Web 导出的硬要求),第一件事不是新建场景,是建文件夹:
assets/
├── fonts/
├── audio/sfx/
└── ui/
autoload/ ← 4 个全局单例的 .gd 和 .tscn 全放这
scenes/
scripts/
theme/
build/ ← 导出产物,不进仓库
没有 scenes/ 就先建场景,它会落在根目录,以后挪要改一堆引用。 先有抽屉,再往里放东西。
autoload/ 单独一层,不拆成 scenes/autoload/ + scripts/autoload/:全局单例是一个"类别",总共 4~5 个文件,拆到两处只是让你多点两次。按"是什么"分,不按"文件类型"分。
分辨率:先定格子,再算画面
项目 → 项目设置 → 显示 → 窗口:
| 项 | 值 |
|---|---|
| 视口宽 / 高 | 1920 × 1080 |
| 拉伸 → 模式 | canvas_items |
| 拉伸 → 比例 | keep |
| 尺寸 → 窗口宽度 / 高度覆盖 | 1280 × 720 |
每格 20 像素 → 96 × 54 格。为什么是 20?一格的像素数必须同时整除 1920 和 1080,蛇才不会卡在半格上。能整除的只有 8 · 10 · 12 · 15 · 20 · 24 · 30 · 40 · 60 · 120——想换档位只能从这里挑,挑 16 会得到 67.5 格。格子类游戏先定每格像素,再算格数,永远这个顺序。
"窗口覆盖 1280×720"是什么:视口是"画有多大",窗口是"看画的框有多大"。画是 1080p 的,框在显示器上开到 1080p 会连标题栏一起超出屏幕。框缩到 720p,画照样是 1080p,拉伸模式会把它等比缩进去。发布后玩家的窗口多大都一样,这两项只影响自己测试。

输入映射:键盘和手柄一起绑
项目 → 项目设置 → 输入映射。每个动作既绑键盘也绑手柄——手柄不是一个功能,是一种假设,从第一天就得成立:
| 动作名 | 键盘 | 手柄 |
|---|---|---|
move_up | ↑ 和 W | 十字键 ↑ 和 左摇杆往上 |
move_down | ↓ 和 S | 十字键 ↓ 和 左摇杆往下 |
move_left | ← 和 A | 十字键 ← 和 左摇杆往左 |
move_right | → 和 D | 十字键 → 和 左摇杆往右 |
pause | Esc 和 P | Start |
ui_accept(内置) | 已有 Enter / 空格 | 补一个 A |
ui_cancel(内置) | 已有 Esc | 补一个 B |
最后两行要勾「显示内置动作」才看得到。Godot 4 默认 ui_accept 只有 Enter 和空格,没有手柄键(方向类的 ui_up 等有),不补的话手柄能移焦点但按不下按钮——这个坑我在第 9 章栽了一次才知道。
为什么要给按键起名字,代码里直接判断"按了 W"不行吗?行,但你看上面那张表:一个名字挂了 4 个键。代码只认 move_up,至于是 W、↑、十字键还是摇杆,代码根本不知道也不用知道。配置和代码分离。

Autoload 骨架:先把名字占住
阶段 2 的代码会写 EventBus.snake_died.emit() 这种句子——EventBus 这个名字必须先存在,代码才不报错。所以现在就建 4 个"空"文件,每个脚本只写一行 extends Node:
| 顺序 | 名称 | 路径 |
|---|---|---|
| 1 | EventBus | res://autoload/event_bus.gd |
| 2 | SaveManager | res://autoload/save_manager.gd |
| 3 | GameManager | res://autoload/game_manager.gd |
| 4 | AudioManager | res://autoload/audio_manager.tscn |
顺序不能乱:列表从上往下依次加载,GameManager._ready() 里会写 EventBus.xxx.connect(...),如果 EventBus 排在它后面,那一刻这个名字还不存在,游戏直接崩。规矩:谁被别人连,谁排前面。EventBus 永远第一。

git
项目 → 版本控制 → 生成版本控制元数据,.gitignore 里加 build/、*.zip、.DS_Store,根目录建一个空的 CREDITS.md,然后 git init -b main、第一条提交。
为什么现在就 git,代码都还没写?因为下一章会大改。有了第一条提交,改坏了随时能回到"干净的骨架"。git 是后悔药,后悔药要在犯错之前买。 CREDITS.md 现在就建,是因为小鸟那次三个音效的来源完全想不起来了——以后每引入一份素材当场写一行。
下一章写代码,先让蛇在控制台里"动"起来。