单击场景->
新场景, 我们将创建生物。
Mob场景将使用以下节点:
- RigidBody2D(命名为Mob)
- 动画精灵
- CollisionShape2D
- VisibilityNotifier2D(命名为Visibility)
在RigidBody2D属性中, 将” 重力比例” 设置为0, 这样生物就不会下降。此外, 在PhysicsBody2D部分下, 单击Mask属性, 然后取消选中第一个框。这样可以确保小怪不会互相碰撞。

文章图片
像我们为播放器所做的那样设置AnimatedSprite。这次, 我们有三个动画:飞行, 游泳和行走。将检查器中的” 播放” 属性设置为” 开” , 然后调整” 速度(FPS)” 设置, 如下所示。我们将随机选择这些动画之一, 以使小怪有一些变化。
飞:

文章图片
游泳:

文章图片
步行:

文章图片
飞行设置为3 FPS, 游泳和步行设置为4 FPS。
像玩家图像一样, 这些暴民图像需要按比例缩小。设置AnimatedSprite的Scale属性(0.75、0.75)。
与在Player场景中一样, 为碰撞添加CapsuleShape2D。为了使形状与图像对齐, 我们需要在Node2D下将Rotation Degrees属性设置为90。
敌人剧本
将脚本添加到Mob并添加以下成员变量:
GDScript
extends RigidBody2Dexport (int) var min_speed # Minimum speed range.export (int) var max_speed # Maximum speed range.var mob_types = ["walk", "swim", "fly"]
我们必须在min_speed和max_speed之间选择一个随机值, 以了解每个生物的移动速度(如果它们都以相同的速度运行, 那将很无聊)。在检查器中将它们设置为150和250。我们还有一个数组, 其中包含三个动画的名称, 我们将使用它们选择一个随机的动画。
现在让我们看一下脚本的其余部分。在_ready()中, 我们随机选择以下三种动画类型之一:
GDScript
func _ready():$AnimatedSprite.animation = mob_types[randi() % mob_types.size()]
注意如果希望每次运行场景时” 随机” 数字的序列不同, 则必须使用randomize()。我们将在Main场景中使用randomize(), 以便在这里不再需要它。 randi()%n是获取介于0和n-1之间的随机整数的标准方法。 最后一步是让暴民在离开屏幕时将自己删除。连接可见性节点的screen_excited()信号, 添加以下代码:
GDScript
func _on_Visibility_screen_exited():queue_free()
它完成了暴民场景。
主要场景
现在是时候将它们整合在一起了。创建一个新场景并添加一个名为Main的节点。单击” 保险” 按钮, 然后选择我们保存的Player.tscn。

文章图片
注意请参阅实例化以了解有关实例化的更多信息。 现在将以下节点添加为Main的子节点, 并按如下所示对其进行命名(值以秒为单位):
- 计时器(名为MobTimer)-用于控制生物产生的频率。
- 计时器(名为ScoreTimer)-用于每秒增加分数。
- 计时器(名为StartTimer)-在启动之前给予延迟。
- Position2D(名称为StartPosition)-用于指示玩家的起始位置。
- 移动计时器:0.5
- 积分时间:1
- 启动计时器:2
产卵小怪
主要节点将产生新的生物, 我们希望它们出现在屏幕边缘的随机位置。将名为MobPath的Path2D节点添加为Main的子级。选择Path2D时, 我们将在编辑器顶部看到一些新按钮:

文章图片
选择中间的一个(“ 添加点” ), 然后通过单击以在所示的角点处添加点来绘制路径。要使点与网格对齐, 请确保已选中” 与网格对齐” 。该选项可以在” 锁定” 按钮左侧的” 捕捉选项” 按钮下找到,
显示为一系列三个垂直点。确保还启用了” 使用快照” 按钮, 该按钮位于” 快照选项” 的左侧。

文章图片
重要
按顺时针方向绘制路径, 在我们的生物上会朝外而不是向内指向!
将点4放置在图像中后, 单击” 关闭曲线” 按钮, 我们的曲线将完成。
现在已经定义了路径, 添加一个pathFollow2D节点作为MobPath的子节点, 并将其命名为MobSpawnLocation。该节点将自动旋转并跟随其移动的路径, 因此我们可以使用它来选择沿路线的随机位置和方向。
主脚本
【游戏节点设置】将脚本添加到Main。在脚本的顶部, 我们使用export(PackedScene)来选择我们要实例化的Mob场景。
extends Nodeexport (PackedScene) var Mobvar scorefunc _ready():randomize()
从” 文件系统” 面板中将Mob.tscn拖放到Main节点的脚本变量下的Mob属性中。
接下来, 单击播放器并连接点击信号。我们要创建一个名为game_over的新函数, 该函数将处理名为game_over的新函数, 该函数将处理游戏结束时需要发生的情况。
在” 连接信号” 窗口底部的” 方法在节点中” 框中键入” game_over” 。添加以下代码以及new_game函数以设置新游戏的所有内容:
func game_over():$ScoreTimer.stop()$MobTimer.stop()func new_game():score = 0$Player.start($StartPosition.position)$StartTimer.start()
在_on_MobTimer_timeout()中, 我们将创建一个暴民实例, 沿着Path2D选择一个随机的起始位置, 并让暴民运动。 PathFollow2D节点沿路径移动时将自动旋转, 因此我们将使用它来选择生物的方向及其位置。
请注意, 必须使用add_child()将新实例添加到场景中。
GDScript
func _on_MobTimer_timeout():# Choose a random location on Path2D.$MobPath/MobSpawnLocation.set_offset(randi())# Create a Mob instance and add it to the scene.var mob = Mob.instance()add_child(mob)# Set the mob's direction perpendicular to the path direction.var direction = $MobPath/MobSpawnLocation.rotation + PI / 2# Set the mob's position to a random location.mob.position = $MobPath/MobSpawnLocation.position# Add some randomness to the direction.direction += rand_range(-PI / 4, PI / 4)mob.rotation = direction# Choose the velocity.mob.set_linear_velocity(Vector2(rand_range(mob.min_speed, mob.max_speed), 0).rotated(direction))
重要
GDScript使用弧度而不是度。如果我们对使用度数感到更自在, 则需要使用deg2rad()和rad2deg()函数在两者之间进行转换
推荐阅读
- Godot的设计哲学
- Godot的第一个游戏项目示例
- 在Godot中编写场景脚本
- GDscript中的工具模式
- 故事书-故事对象(JSON)
- 引用函数
- 电脑设置锁屏密码怎样设置?本文教您设置办法
- 驱动精灵万能网卡版,本文教您驱动精灵万能网卡版怎样运用
- 笔记本cpu温度高怎样办,本文教您笔记本电脑cpu温度高怎样办