在 Godot 中的第一个游戏2025年3月17日 | 阅读 8 分钟 本教程将指导我们制作我们的第一个 Godot 项目。我们将学习 Godot 编辑器的工作方式,如何构建项目以及构建一个 2D 游戏。 本项目是对 Godot 引擎的介绍。它假定我们已经有一些编程经验。如果我们完全是编程新手,我们应该从这里开始。 游戏名为"躲避怪物!"我们的角色必须移动并尽可能长时间地避开敌人。这是最终结果的预览 
 为什么选择 2D?3D 游戏比 2D 游戏复杂得多。在我们对游戏开发过程有很好的理解之前,我们应该坚持使用 2D。 项目设置启动 Godot 并创建一个新项目。然后,下载 dodge_assets.zip,即我们将用于制作游戏的图像和声音。将这些文件解压缩到我们的项目文件夹中。 这个游戏将使用纵向模式,所以我们需要调整游戏窗口的大小。单击项目 -> 项目设置 -> 显示 -> 窗口,并将“宽度”设置为 480,将“高度”设置为 720。 组织项目在这个项目中,我们将制作三个独立的场景:Player、Mob 和 HUD,我们将它们组合到游戏的主 main 场景中。在一个更大的项目中,制作文件夹来保存各种视图及其脚本可能很有用,但对于这个相对较小的游戏,我们可以将场景和脚本保存在根文件夹中,该文件夹称为 res://。我们可以在左上角的 FileSystem Dock 中看到项目文件夹  玩家场景我们将制作的第一个场景定义了 Player 对象。创建单独的 Player 场景的好处之一是,我们可以单独测试它,即使在我们创建游戏的其他部分之前。 节点结构首先,单击添加/创建新节点”按钮,并将 Area2D 节点添加到场景中  使用 Area2D,我们可以检测到与玩家重叠或碰撞的对象。通过单击节点的名称将它的名称更改为 Player。这是场景的根节点。我们可以向玩家添加额外的节点以添加功能。 在我们向 Player 节点添加任何子节点之前,我们要确保我们不会通过单击它们来意外地移动或调整它们的大小。选择该节点,然后单击锁右侧的图标;其工具提示显示“确保对象的子对象不可选择”。  保存场景。单击“场景”->“保存”,或在 Windows/Linux 上按 Ctrl+S,或在 Mac 上按 Command+S。 注意 对于此项目,我们将遵循 Godot 命名约定。类(节点)使用 ParcalCase,变量和函数使用 snake_case,常量使用 ALL_CAPs。精灵动画单击 Player 节点,并将 AnimatedSprite 节点添加为子节点。 AnimatedSprite 将处理我们玩家的外观和动画。请注意,节点旁边有一个警告符号。 AnimatedSprite 需要一个 SpriteFrames 资源,这是一个可以显示的动画列表。要创建一个,请在检查器中找到 Frames 属性,然后单击“<null>” -> “NewSpriteFrames”。接下来,在相同的位置,单击“<null>” -> “NewSpriteFrames”。接下来,在相同的位置,单击 <SpriteFrames> 以打开 “SpriteFrames” 面板  左侧是动画列表。单击 “default”,然后将其重命名为“right”。然后单击“添加”按钮以创建第二个名为“up”的动画。将每个动画的两个图像(名为 playerGrey_up[1/2] 和 playerGrey_walk[1/2])拖到面板的“动画帧”一侧  玩家图像对于游戏窗口来说有点太大了,所以我们需要缩小它们。单击 AnimatedSprite 节点,并将 Scale 属性设置为 (0.5,0.5)。我们可以在检查器中的 Node2D 标题下找到它。  最后,添加一个 CollisionShape2D 作为 Player 的子节点。它将决定玩家的“hitbox”,即其碰撞区域的边界。对于这个角色, capsuleShape2D 节点提供了最佳的拟合,所以在检查器中 “Shape” 旁边,单击 “<null>””->” New CapsuleShape2D”。调整形状的大小以覆盖精灵  不要缩放形状的轮廓!仅使用尺寸手柄(红色圈出)来调整形状! 完成后,我们的 Player 场景应该看起来像这样  移动玩家现在我们需要添加一些我们无法从内置节点获得的功能,所以我们将添加一个脚本。单击 Player 节点,然后单击“添加脚本”按钮;  在脚本设置窗口中,我们可以保留默认设置。只需单击“创建” 注意:如果我们正在创建 C# 脚本或其他语言,请在点击创建之前从语言下拉菜单中选择语言。 如果这是您第一次接触 GDScript,请在继续之前阅读 scripting。 首先声明此对象需要的成员变量 在第一个变量 speed 上使用 export 关键字允许我们在检查器中设置其值。对于我们希望能够调整的值,这非常方便,就像节点的内置属性一样。单击 Player 节点,并将 speed 属性设置为 400。 警告 如果我们使用 C#,我们需要暂时重新启动 Godot 编辑器才能在编辑器中看到导出的变量,直到它被修复。  当节点进入场景树时,会调用 _ready() 函数,这是查找游戏窗口大小的好时机 GDScript 现在我们可以使用 _process() 函数来定义玩家将要做什么。 _process() 每帧调用一次,因此我们将使用它来更新游戏的元素,我们预计这些元素会经常更改。在这里我们这样做 首先,我们必须检查输入——玩家是否正在按键?对于游戏,我们有四个输入方向要检查。输入操作在项目设置的“输入映射”下定义。我们可以描述自定义事件并为它们分配不同的键、鼠标事件或其他输入。对于此演示,我们将使用附加到键盘上箭头键的默认事件。 我们可以使用 Input.is_action_pressed() 检测是否按下了一个键,如果按下则返回 true,如果没有按下则返回 false。 GDScript 我们检查每个输入并加/减速度以获得总方向。例如,如果我们同时按住向右和向下键,则产生的速度向量将为 (1,1)。在这种情况下,由于我们添加了水平和垂直移动,玩家的移动速度将比仅水平移动更快。 如果我们对速度进行归一化,我们可以防止这种情况发生,这意味着我们将它的长度设置为 1,然后乘以所需的速度。这意味着没有更快的对角线运动。 小费 如果我们以前从未使用过向量数学,或者需要复习一下,我们可以在 vector math 中看到 Godot 中向量用法的解释。 了解它是很好的,但对于本教程的其余部分来说不是必需的。 我们还检查玩家是否正在移动,以便我们可以启动或停止 AnimatedSprite 动画。 $ 返回此节点相对路径上的节点,如果未找到该节点,则返回 null。由于 AnimatedSprite 是当前节点的子节点,我们可以使用 $AnimatedSprite。 $ 是 get_node() 的简写形式。因此,在上面的代码中, $AnimatedSprite.play() 与 get_node("AnimatedSprite").play() 相同。 现在我们有了移动方向,我们可以更新 Player 的 位置,并使用 clamp() 来防止它离开屏幕,方法是将以下内容添加到 _process 函数的底部 GDScript 小费 钳制一个值意味着将其限制在给定的范围内。 单击“PlayScene”(F6) 并确认我们可以将玩家在屏幕上向各个方向移动。 警告 如果我们在“调试器”面板中收到一个引用“null 实例”的错误,这可能意味着我们错误地拼写了节点名称。节点名称区分大小写,并且 $NodeName 或 get_node("NodeName") 必须与我们在场景树中看到的名称匹配。 选择动画我们需要根据方向更改 AnimatedSprite 正在播放的动画。我们有一个“right”动画,应该使用 flip_h 属性水平翻转以进行向左移动,还有一个“up”动画,应该使用 flip_v 垂直翻转以进行向下移动。让我们将此代码放在 _process() 函数的末尾 GDScript 再次播放场景,并检查每个方向上的动画是否正确。当我们确定移动工作正常时,将此行添加到 _ready() 中,以便在游戏开始时隐藏玩家 GDScript 准备碰撞我们希望 Player 检测到何时被敌人击中,但我们还没有制造任何敌人!没关系,因为我们将使用 Godot 的信号功能来实现它。 在脚本顶部,在 extends Area2D: 之后添加以下内容: GDScript 这定义了一个名为 "hit" 的自定义信号,当我们的玩家与敌人发生碰撞时,我们将发出(发送)该信号。我们将使用 Area2D 来检测碰撞。选择 Player 节点,然后单击检查器选项卡旁边的 “节点” 选项卡,以查看玩家可以发出的信号列表。  注意,我们的自定义信号 "hit" 也在那里!由于我们的敌人将是 RigidBody2D 节点,我们需要 body_entered(Object body) 信号;当一个 body 接触到玩家时,将发出此信号。单击 “连接”,然后在 “连接信号” 窗口中再次单击 “连接”。我们不需要更改任何这些设置 - Godot 将自动在我们的玩家脚本中创建一个名为 _on_Player_body_entered 的函数。 在连接信号时,我们也可以指定要将信号链接到的现有函数的名称,而不是让 Godot 为我们创建一个函数。 将此代码添加到函数中 GDScript 注意 禁用 Area 的碰撞形状意味着它不会检测到碰撞。 通过将其关闭,我们确保不会多次触发 hit 信号。我们玩家的最后一部分是添加一个函数,我们可以在开始新游戏时调用它来重置玩家。 GDScript 敌人场景 现在是时候创建我们的玩家必须躲避的敌人了。 它们的行为不会很复杂:怪物会随机地在屏幕边缘生成,并沿直线以随机方向移动,然后在 离开屏幕 时 消失 。 我们将把它构建到一个 Mob 场景中,然后实例化它以在游戏中创建任意数量的独立怪物。
|