Godot - 游戏引擎快速上手教程(安装配置、2D躲避小游戏开发案例)
作者:hangge | 2026-09-28 09:39
大家有时可能想自己做一款游戏,却不知道从哪里下手。目前主流的 Unity、UE5 功能虽强,但体量庞大、上手门槛不低。而本文介绍的 Godot 是一款完全免费开源的轻量级游戏引擎,只有几十 MB、解压即用,并且其 2D 开发体验尤其出色,近年在独立游戏圈迅速走红。本文我将介绍 Godot 的基本情况和相关核心概念,并演示下载安装与项目创建的完整流程,最后从零开发一个简单的 2D 躲避小游戏,带大家跑通“建场景 → 写脚本 → 连信号 → 运行调试”的完整开发闭环。


























一、基本介绍
1,Godot 是什么
(1)Godot 是一款自由开源、由社区驱动的跨平台 2D/3D 游戏引擎,采用 MIT 许可证发布。它最初诞生于 2002 年,由一家阿根廷游戏工作室供内部使用,2014 年正式以开源形式发布,名字取自爱尔兰剧作家贝克特的荒诞剧《等待戈多》。目前 Godot 由全球志愿者社区持续开发,版本迭代非常活跃。
提示:MIT 许可证意味着你用 Godot 做的游戏 100% 归你自己所有,商用不需要支付任何授权费或分成。加上引擎体积小、无订阅费用,这也是它成为独立开发者和小团队首选的最大原因。
(2)Godot 编辑器本身支持 Windows、macOS、Linux 三大桌面平台;而用 Godot 制作的游戏可以导出到 Windows、macOS、Linux、Android、iOS、HTML5(网页)等众多平台,一套代码多处运行。
- 官网地址:https://godotengine.org
- 官方文档(简体中文):https://docs.godotengine.org/zh-cn/4.x/
- GitHub 仓库:https://github.com/godotengine/godot
2,核心特点
(1)Godot 的核心特点可以概括为以下几点:
- 完全免费开源:MIT 许可证,无订阅、无分成、无功能阉割
- 轻量便携:编辑器本体只有几十 MB,解压即用,无需安装
- 节点 + 场景架构:万物皆节点,节点组合成场景,场景可保存、复用、嵌套
- GDScript 脚本语言:语法类似 Python,简单易读,学习曲线平缓
- 一体化编辑器:场景编辑、代码编辑、动画、瓦片地图、调试器全部内置,开箱即用
- 2D/3D 双管线:2D 拥有专用渲染管线,像素级精确,做 2D 游戏体验极佳
(2)Godot 提供标准版和 .NET 版两个发行版本,区别如下,新手直接选标准版即可:
| 版本 | 脚本语言 | 适用人群 |
|---|---|---|
| 标准版 | GDScript | 绝大多数新手,体积最小、上手最快 |
| .NET 版 | GDScript、C# | 有 C# 基础或需要 .NET 生态的开发者(需另装 .NET SDK) |
3,核心概念
(1)节点(Node)是 Godot 中最小的构建单元,每个节点只负责一件小事:显示图片(Sprite2D)、播放声音(AudioStreamPlayer)、计时(Timer)、检测碰撞(Area2D)等等。节点以树状结构组织,父子节点各司其职,组合起来就能形成复杂的游戏对象。
(2)场景(Scene)就是一棵保存下来的节点树,以 .tscn 文件的形式存放在项目里。场景可以像节点一样被实例化和复用:一个“玩家”场景可以生成十个玩家。每个项目必须指定一个主场景,作为游戏启动时最先加载的画面。
(3)信号(Signal)是 Godot 的“观察者”消息机制:节点在特定事件发生时会发出信号(如计时器到点的 timeout、碰撞发生的 body_entered),其他代码可以连接(connect)这些信号并作出响应。信号让节点之间松耦合通信,是编写游戏逻辑最重要的手段。
提示:理解“节点组成场景、场景可嵌套复用、信号负责节点间通信”这三句话,就抓住了 Godot 的设计哲学,后面的小游戏会反复用到这三个概念。
二、安装配置
1,环境要求
Godot 对电脑配置的要求非常低,近十年的普通电脑都能流畅运行:
- 操作系统:Windows 10 及以上 64 位系统(也支持 macOS、Linux)
- 显卡:推荐支持 Vulkan 1.0,最低支持 OpenGL 3.3 / OpenGL ES 3.0
- 磁盘空间:只需几百 MB,无任何运行时依赖
- .NET 版额外要求:安装 .NET SDK(标准版无需任何环境)
2,下载并运行 Godot
提示:新手直接下载标准版即可;只有想用 C# 开发的读者才需要下载 .NET 版。

(2)解压后双击 Godot_v4.x-stable_win64.exe,首先看到的是项目管理器(Project Manager),所有 Godot 项目都从这里集中创建和管理:
提示:Godot 是绿色软件,下载得到的 zip 包解压后直接双击其中的 exe 文件即可运行,不需要安装程序、不写注册表,删除文件夹即完成“卸载”。


3,创建第一个项目
(1)在项目管理器中点击“新建项目”按钮,填写项目名称(本文使用 dodge_game),选择一个空文件夹,渲染方式保持默认的 Forward+,然后点击“创建并编辑”:
注意:渲染器选择 Forward+ 是桌面端默认选项,画质最好;如果目标设备较旧或需要发布到网页端,可以选择“兼容(Compatibility)”渲染器。本文的小游戏两种渲染器都可以正常运行。

(2)进入编辑器后可以看到 Godot 的主界面:中间是 2D/3D 视口,左上方是场景树面板,右上方是检查器,左下方是文件系统面板,点击编辑器顶部按钮可切换到脚本编辑器:

(3)接着设置游戏窗口大小。打开菜单“项目 → 项目设置”,搜索关键字 window,把“视口宽度”改为 480、“视口高度”改为 720(竖屏小游戏布局),关闭设置窗口后会自动保存。

三、开发一个简单的 2D 小游戏(躲避小怪)
1,玩法设计
(1)我们将开发一款经典的躲避类小游戏“躲避小怪”:玩家使用方向键上下左右移动,小怪从屏幕顶部不断随机落下;玩家碰到小怪游戏结束,坚持的时间越长得分越高;游戏结束后按回车键可以重新开始。
(2)整个游戏只需要三个场景:玩家场景 player.tscn、敌人场景 mob.tscn 和游戏主场景 main.tscn。美术素材直接使用每个新项目自带的 icon.svg 图标,做到零外部素材,跟着本文就能完整复现。
2,创建玩家场景
(1)打开菜单“场景 → 新建场景”。

(2)点击场景树上方的“其他节点”按钮。

(3)在弹出的窗口中搜索并选择 CharacterBody2D 作为根节点。
提示:CharacterBody2D 是专为可操控角色设计的 2D 物理体,自带 move_and_slide() 移动方法,碰撞、滑动等物理细节都由引擎处理,做角色移动必选它。

(4)然后将将其重命名为 Player。

(5)选中 Player 节点,点击场景树上方的“+”按钮依次添加两个子节点:Sprite2D(负责显示图案)和 CollisionShape2D(负责碰撞体积)。

(6)选中 Sprite2D,在检查器中把 Texture 属性设置为项目自带的 res://icon.svg(直接把文件系统面板中的 icon.svg 拖到 Texture 属性框即可),并把 Scale 属性改为 (0.3,0.3),把图标缩小到 40 像素左右。

(7)选中 CollisionShape2D 节点,在检查器的 Shape 属性下拉框中选择新建 RectangleShape2D,并把形状大小调整为约 40×40(在视口中拖动方形手柄即可)。最后按 Ctrl+S 将场景保存为 player.tscn:

3,编写玩家移动脚本
(1)在场景树中右键点击 Player 节点,选择“附加脚本”。

(2)保持默认参数点击“创建”,编辑器会自动切换到脚本编辑器,把脚本内容替换为如下代码,其中:
- _physics_process() 是每个物理帧自动调用的回调函数;
- Input.get_vector() 一次性读取上下左右四个方向键并自动归一化(斜向移动不会变快),返回的向量乘以速度后赋值给内置属性 velocity。ui_left、ui_right 等是引擎内置的按键映射,无需手动配置。
- 最后调用 move_and_slide() 让角色沿 velocity 移动并自动处理碰撞。
extends CharacterBody2D
@export var speed = 300 # 移动速度(像素/秒)
func _physics_process(delta):
# 同时读取四个方向按键,返回一个已归一化的二维向量
var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
velocity = direction * speed
move_and_slide()
(3)保存脚本,点击编辑器右上角的“运行当前场景”按钮(或按 F6)。

(4)弹出游戏窗口后就可以用方向键控制小图标四处移动了。

4,创建敌人场景
(1)再新建一个场景,这次根节点选择 Area2D,重命名为 Mob。然后用与玩家场景相同的方法,为它添加 Sprite2D 子节点(Texture 同样设为 icon.svg,Scale 改为 0.3)和 CollisionShape2D 子节点(新建 RectangleShape2D,约 40×40),并保存为 mob.tscn。
注意:敌人节点一定要用 Area2D,而不是 CharacterBody2D。Area2D 的 body_entered 信号可以检测到“其他物体进入碰撞区域”,这正是我们判断“玩家被小怪撞到”的依据。

(2)右键点击 Mob 节点选择“附加脚本”,创建后将脚本内容替换为如下代码,其中:
- @export 修饰的变量会显示在编辑器检查器中,方便随时调参而无需改代码;
- _ready() 在节点进入场景时执行一次,这里用 randf_range() 给每只小怪随机一个下落速度;
- _process() 每帧执行,负责向下移动,并在小怪飞出屏幕后调用 queue_free() 销毁回收;
- 碰撞发生时先通过 hit.emit() 发出信号通知主场景,再销毁自己。
extends Area2D
# 撞到玩家时发出的信号
signal hit
@export var min_speed = 150 # 最小下落速度
@export var max_speed = 350 # 最大下落速度
var speed = 0
func _ready():
# 小怪生成时随机决定下落速度
speed = randf_range(min_speed, max_speed)
# 连接碰撞信号:有物体进入碰撞区域时触发
body_entered.connect(_on_body_entered)
func _process(delta):
# 每帧向下移动
position.y += speed * delta
# 飞出屏幕底部后自动销毁,释放资源
if position.y > 800:
queue_free()
func _on_body_entered(body):
# 通知主场景:玩家被撞到了
hit.emit()
# 销毁小怪自身
queue_free()
5,搭建游戏主场景
(1)第三次新建场景,根节点选择 Node2D,重命名为 Main,保存为 main.tscn。

(2)点击场景树上方的“实例化子场景”按钮(链条图标),在列表中选择 player.tscn,玩家就会被作为一个整体添加到主场景中。

(3)选中实例化出来的 Player 节点,在检查器中把它的 position 属性设置为约 (240,560),让玩家出现在屏幕下方中央。

(4)接着为 Main 添加两个 Timer 子节点,分别命名为 MobTimer 和 ScoreTimer。在检查器中把 MobTimer 的 Wait Time 设为 0.5(每 0.5 秒生成一只小怪),ScoreTimer 的 Wait Time 设为 1(每 1 秒加 1 分)。

(5)继续为一个 Main 添加一个 Label 字节点,命名为 ScoreLabel(用于显示得分,可在视口中拖到左上角,把 Text 属性设为“得分:0”)

(6)最后告诉主场景用哪个场景生成小怪:右键点击 Main 节点选择“附加脚本”(保持默认文件名 main.gd),创建完成后选中 Main 节点,检查器中会出现一个 Mob Scene 属性,把文件系统面板中的 mob.tscn 拖到该属性上(或点击属性右侧的下拉箭头选择“快速加载”):

6,编写主场景游戏逻辑
(1)打开 main.gd 脚本,替换为以下代码:
extends Node2D
@export var mob_scene: PackedScene # 敌人场景(在检查器中指定)
var score = 0 # 当前得分
var game_running = false # 游戏是否进行中
func _ready():
# 连接两个计时器的信号
$MobTimer.timeout.connect(_on_mob_timer_timeout)
$ScoreTimer.timeout.connect(_on_score_timer_timeout)
# 游戏开始
new_game()
func _process(delta):
# 游戏结束后按回车键重新开始
if not game_running and Input.is_action_just_pressed("ui_accept"):
new_game()
func new_game():
score = 0
game_running = true
$ScoreLabel.text = "得分:0"
$MobTimer.start()
$ScoreTimer.start()
func game_over():
game_running = false
$MobTimer.stop()
$ScoreTimer.stop()
$ScoreLabel.text = "游戏结束!得分:" + str(score) + ",按回车键重新开始"
func _on_score_timer_timeout():
# 每秒加 1 分并刷新显示
score += 1
$ScoreLabel.text = "得分:" + str(score)
func _on_mob_timer_timeout():
# 在屏幕顶部随机位置生成一只小怪
var mob = mob_scene.instantiate()
mob.position = Vector2(randf_range(30, 450), -40)
# 连接小怪的 hit 信号:撞到玩家就结束游戏
mob.hit.connect(game_over)
add_child(mob)
(2)上面代码主要逻辑如下:
- $MobTimer 这种写法是 get_node() 的简写,用来按名字获取子节点;
- _ready() 中我们把两个计时器的 timeout 信号分别连接到处理函数(也可以在编辑器的“节点”面板中用鼠标连线,效果相同);
- MobTimer 每次到点就随机生成一只小怪并连接它的 hit 信号;
- ScoreTimer 每秒加 1 分;game_over() 负责停表并显示最终得分;
- _process() 中监听回车键(ui_accept)实现重新开始。
7,运行游戏
(1)按 F5 运行项目,首次运行时 Godot 会提示选择主场景,点击“选择当前”按钮指定 main.tscn 即可:

(2)游戏运行后,小怪会从屏幕顶部的随机位置不断落下,用方向键移动玩家躲避,左上角的分数每秒增加 1;一旦碰到小怪,计时停止、得分定格,按回车键即可重新开始一局。
提示:觉得难度不合适?选中 mob.tscn 场景中的 Mob 节点,在检查器里调整 Min Speed / Max Speed 即可改变小怪下落速度;把 MobTimer 的 Wait Time 调小,小怪就会生成得更密集。

附、进阶学习建议
(1)本文为了快速入门做了不少简化。想系统学习的话,官方中文文档是最好的资料,推荐按下面的顺序阅读:
- 渐进式教程(节点、场景、脚本、信号):夯实基础概念
- 你的第一个 2D 游戏(Dodge the Creeps!):本文小游戏的官方完整版,包含动画、音效、路径生成、结束画面等
- GDScript 基础:系统学习脚本语法
(2)跑通本文的小游戏后,可以尝试对其做个改进:给玩家和小怪换上 AnimatedSprite2D 帧动画、用 AudioStreamPlayer 添加音效、做一个开始菜单界面。甚至将其改造成一个打飞机的小游戏。最后通过菜单“项目 → 导出”把游戏打包成 Windows、Android 或网页版本进行发布。


全部评论(0)