我的自习室—让生活从这里沉淀 - Godot
type: channel
link: http://agoodlife.cn/index.php/tag/Godot/
items: 通过制作2D平台游戏学习Godot 4 — 第10部分：游戏相机
items: 通过制作2D平台游戏来学习Godot 4-第9部分: 加农炮处理程序
items: 通过制作 2D 平台游戏来学习 Godot 4 — 第 8 部分：炸弹生成器
items: 通过制作2D平台学习Godot 4-第7部分：炸弹设置
items: 通过制作 2D 平台游戏学习 Godot 4——第 6 部分：关卡创建 #3
items: 通过制作 2D 平台游戏学习 Godot 4 — 第 5 部分：关卡创建 #2
items: 通过制作 2D 平台游戏学习 Godot 4 — 第 4 部分：关卡创建 #1
items: 通过制作 2D 平台游戏学习 Godot 4 — 第 3 部分：玩家动画
items: 通过制作2D平台游戏学习Godot 4 —— 第二部分：玩家设置与移动输入
items: 通过制作2D平台游戏学习Godot 4——第一部分：项目编辑器与概览

通过制作2D平台游戏学习Godot 4 — 第10部分：游戏相机
type: item
date: 2025-06-22T14:21:16+00:00
description: 到目前为止，和《大金刚》一样，我们的游戏使用默认相机，它可以捕捉整个游戏地图。这意味着我们可以一次性看到所有东西。每款2D平台游戏都有不同类型的相机。有些相机会跟随玩家，有些则会在屏幕上滚动。你最终为游戏选择的相机类型取决于你试图为玩家群体打造的体验。快速移动并捕捉小区域的相机适用于你试图营造紧张感的游戏或关卡，而移动较慢、捕捉较大区域的相机则能营造更轻松的游戏体验。相机的大小、焦点和速度取决于你的最终目标。由于我们的游戏灵感源自《大金刚》，所以无需改变相机设置，但为了让游戏独具特色，我们将通过三种不同方式在Godot中创建相机。在本部分你将学到什么：如何使用Camera2D节点。如何为相机的偏移值设置动画。如何估算和定义相机的限制。固定摄像机使用固定摄像头时，摄像头会捕捉整个屏幕或游戏地图的大部分区域。然后可以看到玩家在这个区域内移动。在玩家到达屏幕边缘或该区域尽头之前，摄像头会线性跟随玩家。在我们的游戏中，我们捕捉的是整个游戏地图（即区域）。一个例子是《大金刚》：这款游戏已经捕捉到了我们主场景的整个窗口，因此我们无需在场景中添加摄像机来作为固定摄像机。玩家固定视角相机使用固定于玩家的相机时，相机会被设置为跟随玩家的中心位置。这意味着相机的相对位置取决于玩家的位置。一个例子是《洛克人》：要为我们的角色添加一个固定视角相机，我们需要在“角色”场景中添加一个Camera2D节点。该节点会强制屏幕（当前层）跟随“角色”场景滚动。与手动更改基于CanvasItem的节点位置相比，这样编写可滚动场景的程序会更轻松（也更快）。如果你现在运行场景，并且你的玩家在地图上四处跑动，相机应该聚焦在他们身上。我们可以通过在检查器面板中更改相机的缩放值，将相机“移近”玩家。如果你现在运行场景，摄像机应该会拉近到玩家身上！如果你在地图上四处跑动，你可能已经注意到相机捕捉到了游戏边界之外的灰色背景。我们不希望相机捕捉这些区域，相反，我们希望相机在到达地图的外部边界时停止。要做到这一点，我们需要更改Camera2D节点的限制。这将以像素为单位限制左右上下的滚动范围。你可以在检查器面板中“限制”下方更改限制。要获取这些限制的值，你可以在主场景中从左右标尺上拖动，以获取游戏边界边缘的坐标值。左极限右极限上限下限这就是我最终得到的结果：现在，如果你运行场景，相机应该跟随玩家，并在到达游戏边界的外缘时停止！偏移固定相机有时我们希望相机仅在超出特定范围后才跟随玩家，而不是始终锁定玩家。这样在相机重新聚焦滚动之前，能给玩家一些空间，使我们能够看到前方的事物。我们可以通过更改相机的偏移量值来实现这一点。这是相机的相对偏移量，能让我们环顾四周。一个例子是《超级马里奥兄弟》：如果你已经有了一个Camera2D节点，在检查器面板中取消选择“启用”属性来禁用它。添加一个新的Camera2D节点。我们还希望根据玩家的方向，让相机缓慢地向左或向右移动，所以还要添加一个AnimationPlayer节点。在“动画”面板中创建两个新动画，分别命名为“move_left”和“move_right”。对于这两者，添加一个新的属性轨迹动画。将其连接到你的Camera2D（即你的新相机，而非已禁用的相机）。选择偏移属性，因为我们希望相机所处位置不以玩家为中心。将动画时长调整为你希望相机移动（转场）的速度。我这里采用 0.5 的测试值。然后在动画的起始和结束位置插入关键帧。现在，在向左移动关键帧的第一个值（0）处，我们需要更改偏移值。我希望相机向右偏移100像素，向上偏移 -50像素。然后在向左移动关键帧的第二个值（0.5）处，我们需要将偏移值更改为向右移动动画的起始值。我希望相机向左偏移100像素，向上偏移50像素。在你的向右移动关键帧的第一个值（0）处，我们需要更改偏移值。我希望相机向右偏移100像素，向上偏移50像素。然后在向右移动关键帧的第二个值（0.5）处，我们需要将偏移值更改为向左移动动画的起始值。我希望相机向左偏移100像素，向上偏移 -50像素。我还希望相机稍微拉近一些，所以将“缩放”值更改为更大的值，比如 “2”（这是可选的）。由于相机的限制取决于相机的偏移量，所以我们必须在代码中更改相机的限制范围，因为相机在各个方向上的位置会有所不同。我们还希望相机能够平滑过渡，因此请启用相机的“位置平滑”属性，该属性将以 position_smoothing_speed 的速度将相机平滑地移动到目标位置。你可以根据希望相机过渡或跟随玩家的速度来更改此速度。我们还希望动画中的过渡捕捉更加平滑。我们可以通过更改动画中的插值模式来实现这一点。插值告诉Godot如何计算关键帧之间的帧值。支持以下插值模式：最近值：设置最接近的关键帧值。线性：根据两个关键帧之间的线性函数计算来设置值三次方：根据两个…

通过制作2D平台游戏来学习Godot 4-第9部分: 加农炮处理程序
type: item
date: 2025-04-25T12:26:00+00:00
description: 在前面的部分中，我们创建了大炮 (炸弹产生者) 和炸弹。现在是时候创建我们的大炮处理程序了，这是一只傲慢的绿猪，他会向我们大喊随机的语音气泡并 “点燃” 大炮。这个大炮处理程序在我们的游戏中没有特殊的目的，除了给我们的玩家一个不喜欢的人 (比如来自donkey Kong的驴)。我们的游戏可以在没有这个处理器的情况下完美地工作，但是如果大炮自己发射了，那会有什么乐趣呢？你将在这部分学到什么:如何使用RandomNumberGenerator方法。如何更改计时器wait_time。让我们创建一个Node2D节点作为其根节点的新场景。将此节点重命名为 “CannonHandler”，并将场景保存在Scenes文件夹下。现在在这个场景中，我们希望CannonHandler有两个AnimatedSprite2D节点。第一个AnimatedSprite2D将作为车身对于我们的猪，第二个AnimatedSprite2D将作为语音气泡为了我们的猪。将它们重命名为 “Body” 和 “SpeechBubble”。我们还需要在我们的场景中添加一个计时器节点，这将在计时器超时后随机化我们返回的语音气泡动画。我们将通过随机化计时器的wait_time,这是从x倒计时到0所需的时间 (以秒为单位)。简单地说，每x秒我们的计时器将超时 ()，并返回一个新的语音气泡!我们希望这个计时器在游戏开始后立即开始随机化我们的语音气泡，因此请在检查器面板中启用Autostart属性。选择你的身体节点，并添加两个新的动画: “空闲” 和 “匹配”。为你的慢车动画，导航到 “res:// 资产/国王和猪/精灵/07-猪与匹配/匹配 (26x18 ).png”，并裁剪出所有三个动画帧。将循环值保留为启用，并将其FPS值更改为3。为你的匹配动画，导航到 “res:// Assets/Kings and Pigs/Sprites/07-Pig与匹配/照明匹配 (26x18 ).png”，并裁剪出所有三个动画帧。关闭循环值并将其FPS值更改为3。在您的检查面板中，还可以在偏移选项下方启用 “翻转H” 属性-因为我们希望我们的猪也向左转向我们的大炮。选择您的SpeechBubble节点并向其中添加三个新动画: “boom”，“loser” 和 “sawaring”。为你的动臂动画，导航到 “res:// Assets/Kings and Pigs/Sprites/13-对话框/Boom In (24x8 ).png” 并裁剪所有三个动画帧。关闭循环值并将其FPS值更改为3。为你的失败者动画，导航到 “res:// 资产/国王和猪/精灵/13-对话框/失败者在 (24x8 ).png” 和裁剪出所有三个动画帧。关闭循环值并将其FPS值更改为3。为你的宣誓动画，导航到 “res:// Assets/Kings and Pigs/Sprites/13-对话框/WTF In (24x8 ).png” 并裁剪出所有三个动画帧。关闭循环值并将其FPS值更改为3。现在，将新脚本附加到CannonHandler场景根目录，并将其保存在脚本文件夹下。此外，连接您的计时器节点的超时 ()信号到你的脚本。由于我们的大炮会在游戏一开始就发射炸弹，我们需要我们的大炮处理程序的第一个动画是我们的匹配动画-因为一旦游戏开始产生炸弹，猪就会点燃大炮。我们将在我们的设置这个动画就绪 ()功能。### CannonHandler.gd extends Node2D #when it's loaded into the scene func _ready(): #play cannon lighting animation on start $Body.play("matching")接下来，我们希望我们的慢车动画播放，如果我们的炸弹是移动的-我们也希望我们的猪向我们喊随机的东西。我们可以通过运行一个条件来实现这一点，看看我们的全局is_bomb_moving变量设置为true，如果它返回为true，我们将使我们的SpeechBubble节点可见 (以显示我们的语音气泡)。我们将在内置的正在处理 ()功能，它将检查我们的炸弹在每一帧的运动状态。这将允许我们运行每帧更新一个节点的代码，从而尽可能频繁地更新我们的大炮处理程序的操作。### CannonHandler.gd #older code func _process(delta): #idle animation if Global.is_bomb_moving == true: $Body.play("idle") #show speech bubble $SpeechBubble.visible = true我们希望我们的匹配动画播放，如果我们的炸弹不动，因为…

通过制作 2D 平台游戏来学习 Godot 4 — 第 8 部分：炸弹生成器
type: item
date: 2025-04-13T02:51:07+00:00
description: 现在我们的游戏中有一个炸弹，但我们仍然需要一个刷怪箱。刷怪箱将在特定路径上生成炸弹 — 每次炸弹与玩家或墙壁/瓦片地图碰撞时，它都会重新生成一个新的炸弹。不是我们自己在地图上放置炸弹，而是刷怪箱会为我们处理它。您将在这部分中学到什么：如何使用 Path2D 节点。如何使用 PathFollow2D 节点。如何使用 AnimationPlayer 节点。我们将使用 Path2D 节点为炸弹创建预定义路径。这个 Path2D 节点允许我们在地图上绘制点，这些点将用作我们的炸弹路径。创建路径点后，我们将使用 PathFollow2D 节点沿此路径移动生成的 Bomb 场景。我们需要使用 AnimationPlayer 节点来为炸弹沿着此路径移动的动画。让我们为 Bomb Spawner 创建一个新场景！我们的根节点应该是 Node2D 节点 — 您可以将其重命名为 “BombSpawner”。将此场景保存在 Scenes 文件夹下。这个 BombSpawner 场景需要一个 Timer 节点，每次炸弹数量低于零时，该节点都会生成一个炸弹（如果没有炸弹，计时器将生成一个新的炸弹）。在 Timer 节点的 Inspector 面板中，我们需要启用 “Autostart” 选项。当 BombSpawner 进入 Main scene 树时，这将自动启动计时器。另一个选项“one-shot”触发计时器一次，计时器将在达到 0 时停止。最后，此场景将需要一个 AnimatedSprite2D 节点。此 AnimatedSprite2D 节点将包含将发射炸弹的大炮的动画。我们将在下一部分添加 cannon handler！让我们为大炮创建两个新的动画，分别名为 “cannon_idle” 和 “cannon_fired”。对于我们的cannon_idle动画，请导航到“res://Assets/Kings and Pigs/Sprites/10-Cannon/Idle.png”，然后将唯一的帧添加到您的动画中。暂时将 looping 和 FPS 值保留为默认值。对于我们的cannon_fired动画，请导航到“res://Assets/Kings and Pigs/Sprites/10-Cannon/Shoot （44x28）.png”，并将所有 4 帧添加到动画中。将第一帧添加两次，以便 cannon 动画以相同的帧开始和结束。关闭循环，并将其 FPS 值更改为 4。我们还希望大炮面向相反的方向（右），因此在 AnimatedSprite2D 节点的 Inspector 面板中，在 Offset 下启用“Flip H”属性。我们稍后会回到 BombSpawner 场景，但现在，让我们回到主场景，并向场景添加新的 Node2D 节点。将其重命名为 “BombPath”。此外，删除您之前从场景中实例化的任何 Bomb 场景。添加 Path2D 节点作为 BombPath 节点的子节点。此节点将允许我们为炸弹的移动绘制路径点。如果选择 Path2D 节点，您将在 Inspector 面板中看到有一个添加 Points 的选项。如果向 Points 属性添加元素，您将看到它在游戏窗口的 （x： 0， y： 0） 处创建了一个菱形。您可以将此点拖动到地图上您希望炸弹生成的任意位置。这是炸弹路径的起点。您可以稍后移动它。如果添加另一个元素，它将创建另一个点。您现在也可以单击线条来添加点，如果您想移动点，您只需选择它们并将它们拖动到您想要放置它们的位置即可。要删除某个点，您可以用鼠标右键单击它或在 Inspector 面板中将其删除。让我们为炸弹创建一条从顶部到底部的路径。炸弹每次生成时都会沿着这条路径移动，如果它到达这条路径的尽头或与我们的玩家发生碰撞，它将从顶部重生并再次下降到终点。确保为玩家留出足够的空间以便能够跳过炸弹，如果炸弹与 Tilemap 碰撞（选项 #1）- 确保有足够的空间让炸弹流动而不会爆炸。为了让我们的炸弹在生成后沿着这条路径移动，我们需要添加一个 PathFollow2D 节点作为 Path2D 节点的子节点。我们还需要添加一个 AnimationPlayer 节点作为 Path2D 节点的子节点。动画播放器用于 Animation 资源的通用播放。它包含 AnimationLibrary 资源的字典和动画过渡之间的自定义混合时间。每当需要对非 sprite 项（如标签或颜色）进行动画处理时，都可以使用此 AnimationPlayer 节点。我们在下面的 Animation 面板中向 AnimationPlayer 节点添加动画。要添加新的 Animation，请单击 Animation 属性并选择 “New” 选项。将此动画称…

通过制作2D平台学习Godot 4-第7部分：炸弹设置
type: item
date: 2025-03-30T03:33:44+00:00
description: 之前我们停在了创建游戏的前两个关卡的地方。在这一部分中，我们将创建炸弹，当炸弹生成器生成炸弹时，炸弹会在场景中移动。我们将在下一部分中创建炸弹生成器。您可以将炸弹想象成《大金刚》中的桶，将炸弹生成器想象成愤怒的大猩猩！您将在本部分中学习到的内容：如何使用 StaticBody2D 节点。如何使用queue_free()从场景中删除节点。让我们创建一个以 Area2D 节点为根的新场景。它应该有以下子节点：AnimatedSprite2D、CollisionShape2D（已为其分配 CircleShape2D）和 Timer 节点。这些节点将允许我们检查碰撞是否与我们的玩家发生碰撞，如果是，它应该播放动画并从我们的场景中移除炸弹。如果炸弹没有与我们的玩家发生碰撞，它应该在几秒钟后“自毁”让我们为场景分配一个新脚本并将其保存在脚本文件夹下。然后，将您的 Timer 节点timeout()信号以及您的 Area2D 节点body_entered()信号连接到您的脚本。在开始编码之前，让我们设置一些动画。在我们的 AnimatedSprite2D 节点中，让我们创建一个新的 SpriteFrames 资源，其中包含两个动画：“移动”和“爆炸”。对于移动动画，请导航至“res://Assets/Kings and Pigs/Sprites/09-Bomb/Bomb On (52x56).png”，并将所有四帧分配给动画。您现在可以将循环和 FPS 保留为默认值。对于爆炸动画，请导航至“res://Assets/Kings and Pigs/Sprites/09-Bomb/Boooooom (52x56).png”，并将所有六帧分配给动画。您现在可以将循环和 FPS 保留为默认值。在您的脚本中，当炸弹进入游戏场景时，让我们将移动动画设为默认动画。### Bomb.gd extends Area2D #default animation on spawn func _ready(): $AnimatedSprite2D.play("moving")在我们的func _on_body_entered(body):中，我们需要检查玩家是否正在进入炸弹场景的碰撞形状，如果是，我们应该播放爆炸动画并启动计时器。计时器将允许我们在从场景中移除炸弹之前延迟 1 秒的动画。### Bomb.gd extends Area2D #default animation on spawn func _ready(): $AnimatedSprite2D.play("moving") func _on_body_entered(body): #if the bomb collides with the player, play the explosion animation and start the timer if body.name == "Player": $AnimatedSprite2D.play("explode") $Timer.start()然后，在timeout()函数中，我们需要从游戏场景树中删除场景。要从场景中删除节点，我们使用对象queue_free()。这是从场景树中删除或“销毁对象”的最标准化方式。还有free()，它们之间的主要区别在于queue_free() 会在下一帧被调用。如果 Bomb 场景有效（即存在），我们才会删除 Bomb 场景。### Bomb.gd extends Area2D #older code #remove the bomb from the scene only if the Bomb exists func _on_timer_timeout(): if is_instance_valid(self): self.queue_free()现在，如果你运行主场景并实例化炸弹，当玩家撞到它时，它就会爆炸并从场景中移除。我们还希望炸弹在到达路径末端时爆炸。我们将在下一部分中设置此路径，但简单地说，此路径将从炸弹生成器的位置延伸到玩家的起始位置。一旦它到达末端且未与玩家发生碰撞，它就会爆炸。我们可以通过一个新场景来实现这一点，这个场景将充当我们的墙壁，或者我们可以引用我们的“关卡”Tilemap 节点作为主体。这意味着如果炸弹与关卡图块地图中的图块发生碰撞，它就会爆炸。这样做的缺点是，你在创建路径时必须非常小心——因为与你的 Tilemap 的任何碰撞都会导致炸弹爆炸。我将向你展示这两种方法。选项 1：使用 Tilemap 引爆炸弹如果炸弹与主场景（和 Main_2）中的“Level”Tilemap 节点发生碰撞，则为了引爆炸弹，我们可以简单地扩展现有的炸弹功能，如下所示：### Bomb.gd #olde…

通过制作 2D 平台游戏学习 Godot 4——第 6 部分：关卡创建 #3
type: item
date: 2025-03-24T13:42:47+00:00
description: 在上一部分中，我们为游戏创建了第一个关卡。在这一部分中，我们将通过创建第二个关卡来完成本教程的关卡创建部分，并在现有关卡中添加最后的润色。您将在本部分学习：如何使用定时器节点。如何创建移动平台。如何使用Tilemap层。第1关：最后润色目前，当我们运行关卡时，地图后方仍有默认的灰色背景。我们将借助Tilemap图层把这个背景改为平铺背景。图层能帮助我们区分前景图块和背景图块，让项目结构更清晰。默认情况下，TileMap节点会自带一个预制图层。在主场景中，选中 “Level” 这个Tilemap节点，然后在检查器面板中找到 “Layers”（图层）属性。你会看到已有一个图层，但它没有名字。目前，我们绘制在Tilemap上的所有图块都在这个图层上。我们要把这个图层重命名为 “Foreground”（前景）图层。这时你会发现，Tilemap面板中的 “Layers” 属性已经显示了这一更改。我们希望背景显示在前景图层的后方，所以在 “Layers” 属性中添加一个新元素，并将其命名为 “Background”（背景）。现在你就可以在不同图层间切换了。因为我们希望背景图层在前景图层之后，所以需要通过将 “Background” 图层拖到 “Foreground” 图层上方来重新排列图层顺序。你可以按住图层元素旁边的堆叠线图标进行拖动。现在，在Tilemap面板的 “Layers” 选项中，确保选中了 “Background” 图层。当你选中一个图层时，其他图层上的所有图块都应该会变暗。绘制你的背景。我用的是纯黑色图块，但你可以用任何你喜欢的图块。只是要确保所选图块没有添加任何碰撞体——因为这会阻挡玩家移动！另外，注意不要在梯子上绘制背景。我们会添加另一个Tilemap节点来填充梯子后面的空间。还有一种解决方法，就是在主场景树中将 “Ladders”（梯子）节点拖到 “Tilemap” 节点上方——但我不喜欢梯子突出在地图上方的效果！让我们来填补这个空白。在主场景中复制Tilemap节点，然后把它拖到 “Ladders” 节点后面。我们可以把这个复制的节点重命名为 “Background”。删除这个Tilemap的 “Foreground” 图层，然后简单地绘制剩余的背景部分，去除那些难看的灰色空白区域！（或者直接从 “Level” 节点中删除现有的背景，然后在这里重新绘制）。最终效果应该如下：现在，我们给场景添加一些窗户作为装饰！在 “Level” Tilemap节点中，添加一个名为 “Decorations”（装饰）的新图层。在下方的 “TileSet” 面板中，我们需要为 “Decorations” 创建一个新的图块集。找到 “res://Assets/Kings and Pigs/Sprites/14-TileSets/Decorations (32x32).png”，将这个图片拖到 “Tiles” 属性中。在Tilemap面板中，在 “Decorations” 图层上绘制窗户。你也可以添加其他装饰，比如架子或蜡烛。你可以在 “res://Assets/Kings and Pigs/Sprites/7-Objects/” 目录下的资源中找到更多装饰物品。我最终的效果如下：[此处可能有图片，但文档未提供，可根据描述想象或参考原文]第2关 + 移动平台现在我们已经设置好了第一关，接下来可以创建第二关了。如果你愿意且有时间，也可以创建第3关和第4关。目前，我们只创建第2关。为此，我们可以直接复制主场景，将其命名为 “Main_2”。在新关卡中，玩家实例已经存在。当我们切换场景进入下一关时，玩家会在这里生成，所以要确保玩家位于关卡起点。以下是第二关的布局规划：我们会在顶部设置桶生成器。不过，这次生成器生成的不是桶，而是会沿特定路径滚动的炸弹。我们还会在两侧设置较小的障碍物生成器，它们会向玩家投掷箱子，增加游戏难度。这些箱子也会沿特定路径移动。关卡中还会随机分布生命值、攻击力和得分加成道具。会有上下移动的墙壁阻挡玩家前进。最后，会有玩家出生点和终点，到达终点即可通关。以下是这一关可能的样子：在这一关中，我们会在两侧增加更多炸弹生成器，让游戏更具挑战性，同时还会创建一个移动墙壁，每隔3秒左右阻挡玩家通过。在开始创建关卡之前，我们先创建可移动的墙壁或平台。为此，我们需要新建一个场景，以Area2D节点作为根节点。如果你愿意，也可以使用CharacterBody2D节点——我们只需要一个能处理碰撞和移动的根节点。将这个节点重命名为 “Platform”（平台），并将场景保存在 “Scenes” 文件夹下。给这个新场景添加一个CollisionShape2D节点，形状设为RectangleShape2D。之后我们会调整这个形状的宽度和高度。现在，…

通过制作 2D 平台游戏学习 Godot 4 — 第 5 部分：关卡创建 #2
type: item
date: 2025-03-20T13:21:16+00:00
description: 在上一部分中，我们为游戏的边界创建了基本碰撞和地形。我决定将 Tilemaps 部分分成几个部分，以防止信息过载。如果这是您第一次使用 Godot 中的 TileMap 节点，请不要担心，我保证您练习得越多就会变得越容易。这就是为什么我鼓励您在每部分结束时花时间复习您所做的事情。在这一部分中，我们将创建我们的梯子以及其余的平台。您将在本部分中学习到的内容：如何创建 Area2D 场景。如何连接 Area2D 信号。如何创建全局自动加载单例。阶梯创造在绘制玩家可以跳上的其他平台之前，我们首先需要创建梯子。我们将在新场景中执行此操作。让我们创建一个以Area2D节点为根节点的新场景。此节点创建一个 2D 区域，用于检测与其形状重叠、进入或退出的CollisionObject2D节点。我们将使用此 Area2D 节点检测玩家场景是否正在进入其碰撞形状，如果是，我们将信号指示is_climbing变量为真，这反过来又允许玩家攀爬。此节点上出现警告，因为它没有形状，因此为其分配一个以 RectangleShape2D 为形状的 CollisionShape2D 节点。我们将根节点重命名为“Ladder”。将此场景保存在您的“Scenes”文件夹下。让我们通过向 Ladder 场景添加 Sprite2D 节点来可视化我们的 Ladder。将图像“res://Assets/wood_set/ladder/28x128/2.png”分配给其纹理。现在，修复碰撞形状以勾勒出梯子的轮廓。将新脚本附加到您的 Ladder 场景并将该脚本保存在您的 Scripts 文件夹中。在这个脚本中，我们将获得对 Player 的 is_climbing 变量的引用。如果我们的 Player 进入梯子的碰撞，我们将触发他们的is_climbing变量为真。如果他们离开梯子的碰撞，我们将触发他们的is_climbing变量为假。我们可以使用 Area2D 节点的body_entered()和 body_exited() 信号触发这些变化。当接收的物体（我们的玩家）进入此区域时，会发出body_entered()信号。当接收的物体离开此区域时，会发出body_exited()信号。让我们将这两个信号连接到我们的 Ladder 脚本。这将创建两个新函数，_on_body_exited()和_on_body_entered()。现在，我们可以通过我们的Loading资源获取对我们的玩家节点的引用来实现这一点，但让我们用更好的方法来实现。我们将创建一个 Global 脚本，该脚本将添加到我们的AutoLoad Singleton中。Singleton模式是解决需要在场景之间存储持久信息的常见用例的有用工具。这将使我们能够从游戏中的任何其他场景或脚本访问 Global 脚本中的变量 - 而无需先将它们作为资源加载！让我们在脚本文件夹中创建一个新脚本，并将其命名为“Global”。现在，让我们将其添加到我们的自动加载资源中，以便我们可以全局访问此脚本的值。要将其添加到您的自动加载资源中，请进入您的项目设置 > 自动加载，然后将 Global.gd 文件添加到列表中。接下来，我们需要对 Player 脚本进行一些重构。我希望将is_climbing和is_attacking变量从 Player 脚本移至 Global 脚本。### Global.gd extends Node #移动状态 var is_attacking = false var is_climbing = false现在，在我们的玩家脚本中，让我们用来自 Global 单例的引用替换我们的变量（例如，用 Global.is_climbing 替换 is_climbing，用Global.is_attacking替换 is_attacking）。### Player.gd extends CharacterBody2D #player movement variables @export var speed = 100 @export var gravity = 200 @export var jump_height = -100 #movement and physics func _physics_process(delta): # vertical movement velocity (down) velocity.y += gravity * delta # horizontal movement processing (left, right) horizontal_movement() #applies movement move_and_slide() #applies animations if …

通过制作 2D 平台游戏学习 Godot 4 — 第 4 部分：关卡创建 #1
type: item
date: 2025-03-15T15:15:13+00:00
description: 在本教程系列的开头，我提到过这款游戏的灵感来源于1981年版本的《大金刚》。我再次提起这一点，是因为当我研究原版游戏以分析其机制和玩法时，发现原版《大金刚》只有四个关卡。四个关卡与当今大多数游戏相比似乎微不足道——我的意思是，我们可能都认识某个在《糖果粉碎传奇》中玩到506关的人。图7：经典《大金刚》的四个关卡 在当时，程序化生成关卡并不常见。程序化生成是一种通过算法生成关卡或内容的技术，而不是手动设计，这种技术在许多视频游戏中都有应用，尤其是在类Rogue游戏和开放世界游戏中。然而，原版《大金刚》及其早期续作主要依赖于手工设计的关卡。这意味着开发者自己创建了关卡，这也解释了为什么《大金刚》只有四个关卡。在Godot 4中创建一个程序化生成的《大金刚》风格关卡，意味着要通过算法生成平台、梯子和其他元素，而不是手动放置它们。由于这是一个初学者教程，我们今天不会深入探讨程序化生成的复杂性，而是保持传统，手动创建四个关卡。除了关于高级库存、任务和对话系统的完整教程系列外，我还在制作一个专注于程序化生成世界和地图的独立系列。这些教程将在今年晚些时候免费提供。在本部分中，你将学习：如何创建TileMap资源。如何添加物理和地形层。如何更改TileSet属性。让我们分解一个《大金刚》关卡的基础，以确定我们的关卡需要哪些对象：目前，我们只专注于添加平台和梯子。我们需要在创建每个关卡时考虑起点和终点。我建议你阅读MakeCode的这篇文章，它为你提供了平台游戏关卡设计基础的概述。让我们从基础开始，即在游戏屏幕上绘制游戏边框（城堡的外墙）。我们将使用TileMap节点来实现这一点。TileMap是用于创建游戏布局的网格。要使用TileMap，首先需要创建一个TileSet。TileSet是可以放置在TileMap节点中的图块集合。简单来说，TileMap是我们用来创建地图或环境的完整图块集合。例如：TileSet是将TileMap分解为小立方体的资源，然后我们将这些小立方体视为独立对象。例如：让我们在主场景中添加一个新的TileMap节点，并将其重命名为“Level”。要使用这个TileMap，我们需要为其分配一个TileSet资源。我们可以在选择TileMap节点后，在检查器面板中分配一个新的TileSet资源。我们需要在Tile Set属性旁边的<空>块中分配一个“新建TileSet”。这将在编辑器下方打开两个新的资源块：Tilemap和Tileset。我们将使用Tilemap面板将TileSet绘制到屏幕上，并使用Tileset面板为Tilemap面板分配TileSheet以进行绘制。我们还可以在Tileset面板中更改单个图块的属性。让我们为Tilemap分配一个新的TileSheet，以便绘制城堡边框。为此，点击Tileset面板，然后在文件系统管理器面板中将“res://Assets/Kings and Pigs/Sprites/14-TileSets/Terrain (32x32).png” TileSheet拖到Tiles块中。你可以根据需要拖入任意数量的TileSheet，因为我们将使用许多TileSheet来创建我们的世界。会弹出一个窗口，询问你是否要创建网格。选择“是”，因为这将把我们的TileSheet分解为可管理的小块。现在我们可以回到Tilemap面板，你会看到TileSheet已经可用。你可以使用上面的工具选择、绘制和擦除图块。如果你选择一个图块并将其绘制到屏幕上，它应该会被绘制为一个新对象！以下是Tilemap面板中可用的绘制工具概述：Tilemap碰撞 在开始绘制边框之前，我们首先需要为地板和墙壁图块分配物理层。这将为每个图块提供碰撞形状。为此，选择TileMap节点，点击检查器中的TileSet属性值进行编辑，然后展开物理层并选择添加元素。现在我们可以回到Tileset面板为图块配置碰撞。以下是Tileset面板中可用的工具概述：我们的TileSet只包含立方体形状的物品——因为它只有地板和墙壁。因此，我们可以使用绘制模式面板批量添加碰撞。如果我们有不同形状的图块，比如一棵树，我们将在选择模式面板中为其添加碰撞，因为我们需要手动绘制其形状。我们可以在选择和绘制模式面板中的物理层属性下绘制单个碰撞形状。如果你选择一个图块并导航到其物理层属性，你可以在红色轮廓的块中绘制形状。在这里，你将绘制出物品的形状。正如我之前提到的，我们的形状是简单的正方形，因此我们可以在绘制模式面板中加快这一过程。选择“绘制”面板并导航到物理层属性。你仍然可以像在设置模式面板中一样绘制形状，但在这里我们可以批量添加这个形状到多个图块。让我们不要改变这个形状，因为我们只需要一个立方体。如果你点击一个图块，蓝色框会勾勒出它，这意味着碰撞形状已…

通过制作 2D 平台游戏学习 Godot 4 — 第 3 部分：玩家动画
type: item
date: 2025-03-09T12:26:58+00:00
description: 创建完 Player 场景后，我们现在可以继续为 Player 添加动画，然后将其连接到脚本中的输入。我们希望 Player 在按下ui_left和ui_right时有奔跑动画，站立时有静止动画，按下ui_up时有攀爬动画，按下ui_jump时有跳跃动画，按下 ui_attack 时有攻击动画（我们仍需创建）。我们还希望 Player 受到伤害和死亡时有动画。您将在本部分中学习到的内容：如何创建多个 AnimatedSprite2D 动画。如何将节点信号连接到脚本。首先，让我们添加ui_attack输入操作。我们将为攻击分配 SHIFT 键。我们的玩家在拾取攻击增强拾取物时将需要此攻击动画和输入，这将使其能够在短时间内摧毁箱子和炸弹。现在，让我们创建动画，从奔跑动画开始。我们将使用此奔跑动画进行左跑和右跑，因此我们不需要创建 run_left 和 run_right 动画。让我们创建一个新动画（单击动画面板中的纸张图标）并将其命名为“run”。导航到 Assets 文件夹中的“res://Assets/Kings and Pigs/Sprites/01-King Human/Run (78x58).png”，然后裁剪出动画帧，如下图所示。将其 FPS 更改为 10 并保持循环开启。创建新动画并将其命名为“jump”。导航至 Assets 文件夹中的“res://Assets/Kings and Pigs/Sprites/01-King Human/Jump (78x58).png”，然后裁剪出动画帧，如下图所示。将其 FPS 更改为 5 并保持其循环开启。创建新动画并将其命名为“climb”。导航至 Assets 文件夹中的“res://Assets/Kings and Pigs/Sprites/01-King Human/Door In (78x58).png”，然后裁剪出动画帧，如下图所示。将其 FPS 更改为 10 并保持循环开启。创建新动画并将其命名为“attack”。导航至 Assets 文件夹中的“res://Assets/Kings and Pigs/Sprites/01-King Human/Attack (78x58).png”，然后裁剪出动画帧，如下图所示。将其 FPS 更改为 7 并关闭其循环。创建新动画并将其命名为“damage”。导航至 Assets 文件夹中的“res://Assets/Kings and Pigs/Sprites/01-King Human/Hit (78x58).png”，然后裁剪出动画帧，如下图所示。将其 FPS 更改为 2 并关闭其循环。最后，创建一个新的动画并将其命名为“死亡”。导航到 Assets 文件夹中的“res://Assets/Kings and Pigs/Sprites/01-King Human/Dead (78x58).png”，然后裁剪出动画帧，如下图所示。将其 FPS 更改为 5 并关闭其循环。创建动画后，我们现在可以继续向我们的 Player 脚本添加一个函数，该函数将根据捕获的输入操作更改动画。让我们从奔跑动画开始。如果我们的玩家按下ui_left或ui_right，我们的奔跑动画就会播放。我们将水平翻转精灵，以便我们可以重复使用“奔跑”动画进行左右移动。我们还需要确保我们没有按下ui_jump输入，否则，我们将在跳跃时奔跑！我们将使用我们的 Input 单例来检查这些输入，因为我们想在我们的physics_process函数中调用这个player_animations()函数，以便我们的动画可以在每一秒重新捕获。### Player.gd #旧代码 #动画 func player_animations(): #在左边 (添加 is_action_just_released 以便你在跳跃后继续奔跑) if Input.is_action_pressed( "ui_left" ) || Input.is_action_just_released( "ui_jump" ): $AnimatedSprite2D.flip_h = true $AnimatedSprite2D.play( "run" ) #在右边 (添加 is_action_just_released 以便你在跳跃后继续奔跑) if Input.is_action_pressed( "ui_right" ) || Input.is_action_just_released( "ui_jump" ): $AnimatedSprite2D.flip_h = false $AnimatedSprite2D.play( "run" )现在，如果你注释掉 move_and_slide 以暂时阻止玩家掉…

通过制作2D平台游戏学习Godot 4 —— 第二部分：玩家设置与移动输入
type: item
date: 2025-03-06T14:46:52+00:00
description: 您将在本部分中学习到的内容：如何创建、运行和实例化新场景。如何向节点添加输入动作、碰撞和物理。如何通过脚本操纵场景。如何添加计算速度和运动。现在我们已经设置好了项目，现在可以开始创建块，最终将我们的骨架项目变成一个完整的游戏。在这一部分中，我们将创建一个新的场景，其中包含组成玩家的节点。我们的玩家是我们在玩游戏时将控制的实际角色——它的场景将包含所有节点和脚本，这些节点和脚本将使我们能够看到这个角色并控制它们，以便我们可以四处奔跑并与世界互动。在主场景中，我们可以继续删除上一节中添加的 Sprite2D 节点 — 因为我们只添加了该节点来演示纹理过滤更改。我们将为 Player 创建一个全新的场景，然后在主场景中实例化（或实例化）它。实例化允许我们从模板复制对象，以便我们可以单独修改它们。换句话说，我们将 Player 与主场景分开，因此我们可以将其视为单独的对象。这样，我们的 Player 就是它自己的实体 — 一个不依赖于我们的关卡（或主）场景的实体。继续从主场景中删除 Sprite2D 节点，以便我们剩下这些：然后，让我们创建一个新场景。让我们创建一个新场景。您可以通过单击 Main(*) 旁边的加号图标来执行此操作，这将创建一个新的空场景。在场景码头中，添加一个新的根节点。我们需要将此根节点设为 CharacterBody2D 节点，这是一个专门用于角色的 2D 物理身体节点，可通过脚本移动。我们需要此节点为玩家角色提供物理特性，使其可以四处移动。双击新添加的 CharacterBody2D 节点将其重命名为“Player”，然后将场景保存在 Scenes 文件夹下。您将看到 Player 根节点旁边弹出一个黄色三角形。如果将鼠标悬停在它上面，它会告诉您该节点没有形状。它所指的形状是碰撞形状，该形状将围绕我们的角色，以便它可以与关卡中的其他项目发生碰撞和互动。让我们通过向我们的玩家场景添加 CollisionShape2D 节点来清除此警告。这将返回另一个警告，因为即使我们添加了碰撞节点，我们仍然没有为其分配碰撞形状。我们需要设置shape属性来配置形状。我们可以通过单击我们的CollisionShape2D节点并在Inspector面板中的Shape属性中为其分配一个形状来做到这一点。让我们添加一个新的RectangleShape2D形状。我选择 RectangleShape2D 形状是因为这是我的角色的形状 — 我们以后也可以随时更改此形状以满足我们的需求。您为对象选择的形状类型取决于您希望它们完成的任务（它们需要从哪里碰撞）以及它们的身体形状。因此，圆形角色可能具有 CircleShape2D，依此类推。按 F 键将焦点放在您的节点上。您将看到您的形状已添加。接下来，我们需要在 Player 场景中添加一个精灵，以便我们能够直观地看到我们的节点。如果您想要一个不移动或没有动画的项目，您可以添加一个 Sprite2D 节点来充当这个精灵。在我们的例子中，我们希望 Player 四处移动，并使用动画来实现这一点。因此，我们将添加一个 AnimatedSprite2D 节点。AnimatedSprite2D 与 Sprite2D 节点类似，只是它带有多个纹理作为动画帧。确保在添加此节点时选择了根节点（Player），而不是选择了 CollisionShape2D 节点。我们希望 AnimatedSprite2D 节点成为根节点的子节点，而不是碰撞形状！此节点还会返回警告，因为它需要 SpriteFrames 资源。此资源允许您导入图像文件（或包含所述文件的文件夹）以提供精灵的动画帧。我们可以通过 Sprite Frames 属性在 Inspector 面板中添加新的 SpriteFrames 资源。单击 Sprite Frames 属性旁边的 选项，然后选择“New SpriteFrames”。如果您单击此新添加的资源，它将在下面的编辑器中打开动画面板。在这里我们可以配置我们的 SpriteFrames 资源。配置包括添加新动画、删除动画、播放动画或编辑动画的功能。默认动画可以删除或重命名。我们将在下一部分中添加所有玩家的动画，以便我们可以更详细地探索此节点。现在，让我们通过单击“从 Sprite Sheet 添加帧”选项为默认动画分配一个精灵。会弹出一个窗口，让我们选择 Sprite Sheet。此 Spritesheet 将包含组成完整动画的动画帧。我们想添加一个基本的空闲动画，因此请进入“res://Assets/Kings and Pigs/Sprites/01-King Human/”并选择“Idle (78x58).png”表。从这里开始，我们需要裁剪动画。我们需要将水平和垂直值更改为我们可以计算的动画帧数…

通过制作2D平台游戏学习Godot 4——第一部分：项目编辑器与概览
type: item
date: 2025-03-02T13:19:24+00:00
description: 如果你对复古游戏历史感兴趣，你会知道任天堂在1981年发布《大金刚》后取得的成功简直是一个奇迹。《大金刚》不仅让我们认识了深受喜爱的马里奥（当时被称为Jumpman），还挽救了任天堂免于彻底的经济崩溃。在本系列教程中，我们将追随伟大作品的脚步，尝试制作一款类似《大金刚》的游戏，名为《城堡攀登者》。图1：经典游戏《大金刚》这款游戏与《大金刚》街机游戏类似，玩家将扮演一位国王，需要躲避来自猪敌人的炸弹和箱子，最终爬到城堡顶部以逃脱并进入下一关。与Jumpman不同的是，我们没有公主需要拯救，但这仅仅是因为我们的“国王与猪”资源包中没有包含一个需要救援的公主角色！图2：《城堡攀登者》最终效果本系列教程将涵盖以下内容：玩家动画与移动通过全局脚本管理玩家与障碍物状态攻击激活器、生命值和分数提升的拾取物敌人动画玩家死亡、伤害与攻击带有碰撞与摄像头的游戏地图移动平台与排名系统障碍物的生成关卡进度暂停、保存与加载音乐与音效粒子效果完整的图形用户界面本教程使用的是Godot 4.0.3版本——如果你使用的是更新版本，可能会出现错误，因为引擎在不断变化！请随时向我反馈本系列教程的质量，或如果你遇到任何bug，请通知我，以便我们及时修正。现在让我们开始吧！在本部分你将学习到：如何在Godot编辑器中导航。如何更改项目设置。如何添加场景与节点。编辑器概览在我们开始编写代码之前，首先需要了解Godot编辑器的布局。如果你已经熟悉编辑器，可以跳过本部分的项目设置部分，但如果不熟悉，我建议你快速跟随我一起浏览一下编辑器。如果你还没有安装Godot，请前往他们的网站下载最新版本。下载完成后，解压文件，由于Godot不需要安装，你可以直接将其拖到你希望存储的位置，或者直接从下载文件夹中打开。启动可执行文件后，你将看到项目管理器窗口。在这里你可以创建新项目、加载现有项目，或扫描整个目录以导入多个项目。在顶部，你会看到一个名为“资源库项目”的菜单。在这里你可以下载和找到由社区成员为Godot制作的项目、模板或演示。它类似于其他在线市场，如Itch.io、Unreal Marketplace或Unity Asset Store。唯一的区别是这里的一切都是免费的。要创建我们的项目，点击“新建项目”，然后会出现一个窗口，我们可以选择项目的保存位置并为其命名。我将我的项目命名为“城堡攀登者”，但你可以随意命名。可用的三种渲染模式是：Forward+模式，适用于更高级的游戏项目，对图形和渲染要求较高。移动模式，通常用于移动游戏。兼容模式，使用与Godot 3相同的渲染器，图形和渲染质量较低，更适合较旧或低配设备。我的集成显卡与Godot 4支持的Vulkan版本存在兼容性问题，所以我需要选择兼容模式。但这并不影响使用，因为它仍然运行得很好。你可以在这里阅读更多关于新渲染更新的信息。选择“创建并编辑”，你将神奇地进入项目窗口。在顶部，我们有我们的工作区，这是我们完成任务的空间。3D模式将始终默认激活。如果你点击其他选项，可以在不同的工作区之间切换。图3：工作区导航的鼠标输入现在，让我们逐一了解这些工作区：2D工作区用于编辑和查看2D游戏的2D场景。3D工作区用于编辑和查看3D游戏的3D场景。脚本工作区是代码编辑器，我们在这里编写、编辑和查看脚本。AssetLib工作区是资源库项目，你可以免费在你的项目中使用。窗口左侧的面板是场景停靠栏。这里列出了你当前打开的场景内容，你也可以在这个停靠栏中向场景添加新节点。在Godot中，场景是节点的主要容器，节点是游戏的主要构建块。不同的节点有不同的功能，例如碰撞形状和动画精灵各有其用途，因此能够将它们组合在一个场景中，使我们能够为游戏创建具有更复杂功能的组件。场景还可以实例化其他场景，例如在你的世界场景中包含敌人场景。我建议你去看看Godot关于节点和场景的文档。我画了一个Mural板来给你展示节点和场景的示例，你可以在这里查看。另一个面板称为导入停靠栏，在这里你可以设置或编辑添加到项目文件夹中的资源（如图片、字体和音频文件）的属性，然后你可以重新导入这些资源并保存这些属性。在场景和导入停靠栏下方，你会找到文件系统面板，这是你管理项目文件、文件夹和资源的地方。你可以将新资源拖入此面板以将其导入项目，还可以添加新文件夹、脚本、场景等。窗口右侧的面板称为检查器面板，在这里你可以查看和编辑当前所选节点的属性。旁边的节点面板是你可以连接信号并向节点添加组的地方。组可以用于将场景或节点类型分组，例如我们的NPC，以便玩家知道如何与这些节点交互。信号可以在许多情况下使用，例如通知游戏按钮已被按下或动画已播放完毕。这使我们能够告诉游戏在某些事件发生时该做什么。大多数节点都有内置信号，例如按钮和动画播放器，但我们也可以创建自己的自定义信号。我画了一个Mu…