今日速览

  • 游戏本质是循环:每一帧先更新世界状态,再绘制到屏幕,这就是「游戏循环」(Game Loop)。
  • Godot 提供两个回调:_process(delta)(空闲处理,每帧调用,频率随帧率浮动)和 _physics_process(delta)(物理处理,固定每秒 60 次,与帧率无关)。
  • delta 是距离上一次调用的秒数,任何移动计算都要乘上它,否则低帧率电脑上角色会「瞬移」。
  • 物理相关必须用 _physics_process:移动会碰撞的实体、检测碰撞,都放这里,保证物理稳定。
  • 节点是积木、场景是成品:节点组合成树状结构并保存,就是场景;场景可反复实例化(如 5 个敌人 = 同一个敌人场景的 5 个实例),主场景是游戏启动的入口。

核心学习内容

1. 游戏循环:每一帧都在做什么

所有游戏都在跑一个无限循环:输入 → 更新逻辑 → 渲染 → 等待下一帧。Godot 帮你封装好了这个循环,你只需要在脚本里定义两个虚函数,引擎就会自动调用:

func _process(delta):          # 每帧调用,频率≈帧率
    pass

func _physics_process(delta):  # 固定 60 次/秒(可在 Project Settings → Physics → Common → Physics Fps 修改)
    pass

关键区别:_process 用于 UI 动画、计时器、任何「跟着画面走」的逻辑;_physics_process 用于物理引擎相关的一切。在单线程游戏中,_process 会在物理迭代后执行。写代码时记住一句话:会撞墙的移动放物理回调,纯视觉的更新放空闲回调。

2. delta 的魔法:让游戏在不同电脑上跑得一样快

帧率会变(60 帧、144 帧、卡顿时 20 帧),但游戏速度不能变。所以位移公式永远是 位移 = 速度 × 时间:

func _physics_process(delta):
    velocity = Vector2(Input.get_axis("ui_left", "ui_right") * SPEED, 0)
    position += velocity * delta  # 乘 delta,帧率无关

不乘 delta 的后果:高刷屏上角色跑得飞快,低配电脑上角色慢如蜗牛——这就是最常见的「帧率相关 bug」。

3. 节点与场景:Godot 的乐高体系

  • 节点(Node):最小的功能单元,如 Sprite2D(显示图片)、Label(显示文字)、Camera2D(摄像机)、CollisionShape2D(碰撞形状)。所有节点都有名称、可编辑属性、可挂脚本扩展、可以挂在其他节点下。
  • 场景(Scene):一组组织好的节点树,保存为 .tscn 文件。场景可以像节点一样被实例化:做 10 个敌人,只需把「敌人场景」实例化 10 次,改一改属性即可。
  • 典型角色结构:CharacterBody2D(身体)+ Sprite2D(外观)+ CollisionShape2D(碰撞盒)+ Camera2D(跟随镜头)。
  • 项目中至少有一个主场景(Main Scene,F5 运行入口),路径保存在 project.godot 里;资源路径用 res:// 开头。

对我们做 Steam 游戏的意义:场景系统天然支持「模块化开发」——先搭出玩家场景,再复制出敌人、道具、关卡,每个场景都可以让 DeepSeek 单独写脚本,互不干扰。

🎯 DeepSeek 提示词

提示词 1:生成 2D 角色移动脚本(适用:新建玩家控制)

你是一名资深 Godot 4 游戏开发者。请用 GDScript 写一个 2D 平台跳跃角色的完整脚本,挂在 CharacterBody2D 节点上。
要求:
1. 支持左右移动(Input.get_axis("ui_left", "ui_right"))、跳跃(空格,仅在地面时可跳)、重力与落地检测;
2. 所有物理逻辑放在 _physics_process 中,移动必须乘 delta;
3. 用 @export 暴露移动速度、跳跃力度、重力等参数,方便在检查器里调;
4. 每段代码加简短中文注释,说明为什么这样写(尤其说明为什么用 _physics_process 而不用 _process);
5. 直接输出完整可粘贴的脚本,不要省略号。

提示词 2:代码体检——查帧率相关 bug(适用:脚本跑起来表现不对时)

你是 Godot 性能审查专家。下面是我的 GDScript 脚本,请逐行审查并指出所有「帧率相关」问题:
1. 是否有本应在 _physics_process 中执行的物理逻辑被放进了 _process;
2. 移动/速度计算是否漏乘 delta;
3. 是否直接修改了受物理引擎管理的属性(如 CharacterBody2D 的 position 代替 velocity);
4. 输出格式:先列出问题清单(位置+原因+后果),再给出修正后的完整代码,最后用 3 句话总结教训。
脚本如下:
```gdscript
(粘贴你的脚本)
```

提示词 3:设计场景结构(适用:开始搭新玩法/新关卡前)

你是 Godot 场景架构师。我要做一款【2D 横版闯关游戏,主角能跑跳,有关卡、金币、敌人和 UI 血条】。请帮我设计:
1. 完整的场景清单(每个场景的根节点类型、子节点树结构、负责的职责);
2. 场景之间的实例化关系(谁加载谁、何时加载);
3. 哪些逻辑放 _process、哪些放 _physics_process 的分工建议;
4. 输出为层级缩进的树状结构图 + 表格说明,中文回答。

使用说明:提示词 1 是「从零生成」,每天练手必用;提示词 2 是「诊断修复」,报错或手感不对时先跑一遍;提示词 3 是「设计先行」,动手写代码前让 DeepSeek 当架构师,避免返工。

学习心得

第 1 天选了引擎,第 2 天学了语言,今天终于摸到 Godot 的「心跳」和「积木」。游戏循环解释了为什么同样一段代码在不同电脑上表现不同,节点/场景体系则给了我们一条可复制的开发流水线:场景拆分 → 每个场景单独生成脚本 → 用提示词 2 做体检。这正好和「用 DeepSeek 做游戏」的思路咬合——AI 写代码不可怕,可怕的是不懂机制、看不出 bug 在哪一层。理解了循环和场景树,就等于拿到了和 DeepSeek 对话的地图:你能准确告诉它「问题出在物理回调里」,而不是笼统地说「角色乱动」。

明日关注

  • 动手搭一个带 CharacterBody2D + Sprite2D + CollisionShape2D 的最小玩家场景,跑通 F5
  • 用提示词 1 生成移动脚本,故意删掉 delta 观察「帧率 bug」的实际手感差异
  • 学习 Godot 信号(signal)与 await:节点之间如何通信(为多场景协作打基础)

本文由自动化学习流水线每日生成,坚持即学即记。