godot
Godot游戏引擎是Juan Linietsky 1 和Ariel Manzur 1 发起的,是一款制作游戏的软件,可以制作2D和3D游戏。通过基于节点的架构来设计游戏,3D渲染器设计可以增强3D游戏的画面。具有内置工具的2D游戏功能以像素坐标工作,可以掌控2D游戏效果。面向团队的设计从架构和工具到VCS集成,Godot专为团队中的每个人设计。编辑器可在Windows、Mac OS和Linux系统中运行,支持导出游戏到Windows、Mac OS、Linux、Android、iOS、UWP和HTML5等平台。
最新发布的 Godot 3.5 Beta 3 开发版已支持在 Android 上运行。
1.详细内容
1.1 Godot 关键概念概述
- 场景 - scene
在 Godot 中,你把你的游戏分解成可重复使用的场景。场景可以是一个角色、一件武器、用户界面中的一个菜单、一座房子、整个关卡,或者任何你能想到的东西。Godot 的场景很灵活,既能够充当预制件(Prefab),又能够用作其他游戏引擎中的场景。
你还可以嵌套场景。例如,你可以把你的角色放在关卡中,然后拖放一个场景作为它的子级。
- 节点 - node
场景由若干节点组成。节点是你的游戏最小的构件,你将其排列成树状。下面是一个人物节点的例子。
- 场景树 - scene tree
所有游戏场景都聚集在场景树中,实际上是一棵场景树。由于场景是节点树,场景树也是节点树。但从场景的角度来思考你的游戏会更容易,因为它们可以代表角色、武器、门或你的用户界面。
- 信号 - signals
当某些事件发生时,节点会发出信号。此功能允许您使节点进行通信,而无需在代码中对它们进行硬连接。它为您构建场景提供了很大的灵活性。
1.2 界面
godot 内置类说明
在编辑器中的任意位置按F1
在脚本编辑器中按住Ctrl类名、函数名或内置变量的同时单击
1.3 step by step
1.3.1 节点
节点是游戏的基本构建块。它们就像食谱中的成分。有几十种可以显示图像、播放声音、代表相机等等的类型。
所有节点都具有以下特征:
- 一个名字。
- 可编辑的属性。
- 他们收到更新每一帧的回调。
- 您可以使用新的属性和功能来扩展它们。
- 您可以将它们作为子节点添加到另一个节点。
最后一个特征很重要。节点一起形成一棵树,这是组织项目的强大功能。由于不同的节点具有不同的功能,将它们组合起来会产生更复杂的行为。正如我们之前看到的,您可以使用名为“Character”的CharacterBody2D 节点、Sprite2D节点、Camera2D节点和CollisionShape2D节点来构建相机跟随的可玩角色。
1.3.2 场景
场景:当您组织树中的节点时,就像我们的角色一样,我们将其称为构建场景。保存后,场景就像编辑器中的新节点类型一样工作,您可以将它们添加为现有节点的子节点。在这种情况下,场景的实例显示为单个节点,其内部结构被隐藏。
场景允许您根据需要构建游戏代码。您可以 组合节点来创建自定义和复杂的节点类型,例如可以奔跑和跳跃的游戏角色、生命条、可以与之交互的箱子等等。
Godot 编辑器本质上是一个场景编辑器。它拥有大量用于编辑 2D 和 3D 场景以及用户界面的工具。Godot 项目可以包含您需要的任意多个场景。该引擎只需要一个作为您应用程序的主场景。这是当您或玩家运行游戏时 Godot 将首先加载的场景。
除了充当节点之外,场景还具有以下特征:
- 它们总是有一个根节点,就像我们示例中的“字符”一样。
- 您可以将它们保存到本地驱动器并稍后加载。
- 您可以根据需要创建任意数量的场景实例。您的游戏中可以有五个或十个角色,这些角色是根据角色场景创建的。
1.3.2.1 创建你的第一个场景
在空场景中,左侧的场景停靠栏显示多个用于快速添加根节点的选项。
- “2D Scene”添加Node2D节点,
- “3D Scene”添加Node3D节点,
- “User Interface”添加Control节点。
- “其他节点”允许您选择任何节点作为根节点。
这些预设是为了方便起见;它们不是强制性的。在空场景中,“其他节点”相当于按场景停靠栏左上角的“添加子节点”按钮,通常会添加一个新节点作为当前所选节点的子节点。
“场景另存为”对话框与编辑器中的其他文件对话框一样,仅允许您将文件保存在项目内。res://窗口顶部的路径代表项目的根目录,代表“资源路径” 。
编辑器将主场景的路径保存在项目目录中的project.godot 文件中。虽然您可以直接编辑此文本文件来更改项目设置,但您也可以使用“项目 -> 项目设置”窗口来执行此操作。
您可以根据需要创建任意数量的场景,并将它们保存为扩展 .tscn名为“文本场景”的文件。我们将这些文件称为“打包场景”"Packed Scenes",因为它们打包了有关场景内容的信息。
# 这是一个球的例子。它由一个名为 Ball 的根节点(允许球下落并在墙壁上弹跳)的RigidBody2D节点、一个Sprite2D节点和一个 CollisionShape2D组成。
Godot 中的实例和场景提供了出色的设计语言,使该引擎与其他引擎区分开来。我们从头开始就围绕这个概念设计了 Godot。
我们建议在使用 Godot 制作游戏时放弃架构代码模式,例如模型-视图-控制器 (MVC) 或实体关系图。相反,您可以首先想象玩家将在游戏中看到的元素,并围绕它们构建代码。

您几乎可以为任何类型的游戏绘制这样的图表。每个矩形代表一个从玩家角度在游戏中可见的实体。箭头告诉您哪个场景拥有哪个场景。
获得图表后,我们建议为其中列出的每个元素创建一个场景来开发您的游戏。您将通过代码或直接在编辑器中使用实例来构建场景树。
程序员往往花费大量时间设计抽象架构并尝试将组件放入其中。基于场景的设计使开发变得更快、更简单,让您可以专注于游戏逻辑本身。由于大多数游戏组件直接映射到场景,因此使用基于场景实例化的设计意味着您几乎不需要其他架构代码。
以下是包含大量资源和嵌套元素的开放世界游戏的场景图示例:

想象一下我们从创建房间开始。我们可以制作几个不同的房间场景,并在其中布置独特的家具。之后,我们可以制作一个内部使用多个房间实例的房屋场景。我们将用许多实例房屋和一个大地形来创建一个城堡,我们将在上面放置城堡。其中每一个都是一个实例化一个或多个子场景的场景。
之后,我们可以创建代表守卫的场景并将他们添加到城堡中。它们将间接添加到整个游戏世界中。
使用 Godot,您可以轻松地像这样迭代您的游戏,因为您所需要做的就是创建和实例化更多场景。我们设计的编辑器可供程序员、设计师和艺术家等使用。典型的团队开发流程可能涉及 2D 或 3D 美术师、关卡设计师、游戏设计师和动画师,所有人员都使用 Godot 编辑器进行工作。
1.3.3 脚本语言
脚本附加到节点并扩展其行为。这意味着脚本继承它们所附加的节点的所有功能和属性。
例如,以一个 Camera2D 节点跟随一艘船的游戏为例。默认情况下,Camera2D 节点跟随其父节点。想象一下,当玩家受到伤害时,您希望相机抖动。由于 Godot 中未内置此功能,因此您可以将脚本附加到 Camera2D 节点并对抖动进行编码。
1.3.3.1 可用的脚本语言
Godot 提供四种游戏编程语言:GDScript、C#,以及通过其 GDExtension 技术提供的 C 和 C++。还有更多社区支持的语言,但这些是官方语言。
1.3.3.2 GDScript
GDScript是一种 面向 对象的命令式 编程语言。它由游戏开发者制作,旨在节省您编写游戏的时间。其特点包括:
- 简单的语法可以生成短文件。
- 编译和加载时间极快。
- 紧密的编辑器集成,具有节点、信号及其所附加场景的更多信息的代码完成功能。
- 内置向量和变换类型,使其能够高效地大量使用游戏必需的线性代数。
- 像静态类型语言一样高效地支持多线程。
- 没有垃圾收集,因为此功能最终会妨碍创建游戏。默认情况下,引擎会计算引用数并为您管理内存,但如果需要,您也可以控制内存。
逐渐打字。默认情况下,变量具有动态类型,但您也可以使用类型提示进行强类型检查。
当您使用缩进构建代码块时,GDScript 看起来像 Python,但在实践中它的工作方式并不相同。它的灵感来自多种语言,包括 Squirrel、Lua 和 Python。
extends Sprite2D
var speed = 400
var angular_speed = PI
func _init():
print("Hello Whh")
func _process(delta):
rotation += angular_speed*delta
var velocity = Vector2.UP.rotated(rotation)*speed
position += velocity*delta
在 Godot 中,您有两个主要工具来处理玩家的输入:
- 内置的输入回调,主要是_unhandled_input(). 就像 一样 _process(),它是一个内置的虚拟函数,每次玩家按下一个键时 Godot 都会调用它。您可以使用它来对并非每帧都发生的事件做出反应,例如按下Space跳跃键。要了解有关输入回调的更多信息,请参阅使用 InputEvent。
- 单实例Input。单例是全局可访问的对象。Godot 提供了对多个脚本的访问。它是检查每帧输入的正确工具。
我们将Input在这里使用单例,因为我们需要知道玩家是否想要在每一帧转动或移动
extends Sprite2D
var speed = 400
var angular_speed = PI
func _init():
print("Hello Whh")
func _process(delta):
var direction = 0
if Input.is_action_pressed("ui_left"):
direction = -1
if Input.is_action_pressed("ui_right"):
direction = 1
rotation += angular_speed*direction*delta
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_up"):
velocity = Vector2.UP.rotated(rotation)*speed
if Input.is_action_pressed("ui_down"):
velocity = Vector2.DOWN.rotated(rotation)*speed
position += delta*velocity
1.3.4 信号
信号是节点在发生特定事件(例如按下按钮)时发出的消息。其他节点可以连接到该信号并在事件发生时调用函数。
信号是 Godot 中内置的一种委托机制,允许一个游戏对象对另一个游戏对象的更改做出反应,而无需它们相互引用。使用信号可以限制耦合并保持代码的灵活性。
extends Sprite2D
var speed = 400
var angular_speed = PI
func _init():
print("Hello Whh")
func _process(delta):
var direction = 0
if Input.is_action_pressed("ui_left"):
direction = -1
if Input.is_action_pressed("ui_right"):
direction = 1
rotation += angular_speed*direction*delta
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_up"):
velocity = Vector2.UP.rotated(rotation)*speed
if Input.is_action_pressed("ui_down"):
velocity = Vector2.DOWN.rotated(rotation)*speed
position += delta*velocity
func _on_button_pressed():
set_process(not is_processing())# Replace with function body.
可以通过代码连接信号,而不是使用编辑器。当您在脚本内创建节点或实例化场景时,这是必要的
extends Sprite2D
var speed = 400
var angular_speed = PI
func _init():
print("Hello Whh")
func _process(delta):
var direction = 0
if Input.is_action_pressed("ui_left"):
direction = -1
if Input.is_action_pressed("ui_right"):
direction = 1
rotation += angular_speed*direction*delta
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_up"):
velocity = Vector2.UP.rotated(rotation)*speed
if Input.is_action_pressed("ui_down"):
velocity = Vector2.DOWN.rotated(rotation)*speed
position += delta*velocity
func _ready():
var timer = get_node("Timer")
timer.timeout.connect(_on_timer_timeout)
func _on_timer_timeout():
visible =not visible
func _on_button_pressed():
set_process(not is_processing())# Replace with function body.
可以在脚本中定义自定义信号。例如,假设您希望在玩家的生命值为零时显示游戏结束屏幕。为此,您可以在健康状况达到 0 时定义一个名为“died”或“health_depleted”的信号。
extends Node2D
signal health_depleted
var health = 10
您的信号的工作方式与内置信号相同:它们显示在“节点”选项卡中,您可以像其他信号一样连接到它们。
要在脚本中发出信号,请调用emit()该信号。
func take_damage(amount):
health -= amount
if health <= 0:
health_depleted.emit()
信号可以选择声明一个或多个参数。指定括号之间的参数名称:
extends Node
signal health_changed(old_value, new_value)
var health = 10
要随信号一起发出值,请将它们作为额外参数添加到函数中 emit():
func take_damage(amount):
var old_health = health
health -= amount
health_changed.emit(old_health, health)
Godot 中的任何节点在特定情况发生时都会发出信号,例如按下按钮。其他节点可以连接到单独的信号并对选定的事件做出反应。
信号有很多用途。使用它们,您可以对进入或退出游戏世界的节点、碰撞、角色进入或离开某个区域、界面元素改变大小等等做出反应。
例如,每当玩家的物理体进入其碰撞形状时,表示硬币 的Area2Dbody_entered就会发出信号,让您知道玩家何时收集了它。
说明
- label 节点 - 在一行中显示纯文本,或在一个矩形内包裹。对于格式化的文本,使用 RichTextLabel。
- CollisionObject2D - 2D 碰撞对象的基础节点。CollisionObject2D 是 2D 物理对象的基类,可以容纳任意数量的 2D 碰撞形状 Shape2D。每个形状必须分配给一个形状所有者。CollisionObject2D 可以拥有任意数量的形状所有者。其节点属性用有shape,可以点击进行创建