Godot《躲避小兵》实战之创建游戏主场景

游戏主场景

现在是时候将我们所做的一切整合到一个可玩的游戏场景中了。

创建新场景并添加一个 Node节点,命名为 Main。(我们之所以使用 Node 而不是 Node2D,是因为这个节点会作为处理游戏逻辑的容器使用。本身是不需要 2D 功能的。)

点击实例化 按钮(由链条图标表示)并选择保存的 player.tscn

现在,将下列节点添加为 Main 的子节点,并按如下所示对它们进行命名:

  • Timer(名为 MobTimer)------控制怪物产生的频率
  • Timer(名为 ScoreTimer)------每秒增加分数
  • Timer(名为 StartTimer)------在开始之前给出延迟
  • Marker2D名为 StartPosition)------表示玩家的起始位置

Timer 即计时器节点,是一种倒计时器,也是引擎中最简单的处理基于时间的逻辑的方法。计时器在等待 wait_time结束后就会发出 timeout 信号。

如下设置每个 Timer 节点的 Wait Time 属性(值以秒为单位):

  • MobTimer0.5
  • ScoreTimer1
  • StartTimer2

此外,将 StartTimerOne Shot 属性设置为"启用",启用之后即代表该定时器只执行一次,结束就停止。

并将 StartPosition 节点的 Position 设置为 (240, 450),这里的位置就是我们角色开始的初始位置,到时候将这个值传递给Player的start方法。

生成怪物

Main 节点将产生新的生物, 我们希望它们出现在屏幕边缘的随机位置. 添加一个名为 MobPathPath2D 节点作为 Main 的子级. 当你选择 Path2D 时, 你将在编辑器顶部看到一些新按钮:

选择添加点按钮,并单击以添加拐角点来绘制路径。可使用网格捕捉和用智能捕捉,使点对齐到网格。

在图像上放置点 4 后, 点击 闭合曲线 按钮, 你的曲线将完成.

现在已经定义了路径, 添加一个 PathFollow2D节点作为 MobPath 的子节点, 并将其命名为 MobSpawnLocation. 该节点在移动时, 将自动旋转并沿着该路径, 因此我们可以使用它沿路径来选择随机位置和方向.

PathFollow2D节点是对Path2D节点的一个取样器。

Main主场景脚本

将脚本添加到 Main。在脚本的顶部,我们使用 @export var mob_scene: PackedScene 来允许我们选择要实例化的 Mob 场景。

extends Node

@export var mob_scene: PackedScene
var score

单击 Main 节点,就可以在"检查器"的"Script Variables"(脚本变量)下看到 Mob Scene 属性。

有两种方法来给这个属性赋值:

  • mob.tscn 从"文件系统"面板拖放到 Mob Scene 属性里。
  • 单击"[空]"旁边的下拉箭头按钮,选择"加载"。选择 mob.tscn

然后选中"场景"面板中 Main 节点下的 Player 场景实例,切换到侧边栏的"节点"面板。请确保"节点"面板中的"信号"选项卡处于选中状态。

你可以看到 Player 的信号列表。找到 hit 信号并双击(或右键选择 "Connect...")将会打开信号连接窗口。接下来创建用于在游戏结束时进行一些处理的 game_over 函数。在信号连接窗口底部的 "接收方法" 框中输入 "game_over",并点击 "连接"。 你的目标是从 Player 发出 hit 信号,并在 Main 脚本中进行处理。将以下代码添加到新函数中,以及一个 new_game 函数,该函数将为新游戏设置一切:

func game_over():
	# 定时器停止
	$ScoreTimer.stop()
	# 生成怪物定时器停止
	$MobTimer.stop()
	
	
func new_game():
	score = 0
	# 调用玩家start方法
	$Player.start($StartPostion.position)
	# 倒计时2秒开始
	$StartTimer.start()

现在将每个 Timer 节点(StartTimerScoreTimerMobTimer)的 timeout() 信号连接到 main 脚本。 StartTimer 将启动其他两个计时器。 ScoreTimer 将使得分加1。

func _on_score_timer_timeout():
	# ScoreTimer定时器结束时分数自增
	score += 1

func _on_start_timer_timeout():
	# starttimer定时器结束时开启其余两个定时器
	$MobTimer.start()
	$ScoreTimer.start()

_on_mob_timer_timeout() 中, 我们先创建小怪实例,然后沿着 Path2D 路径随机选取起始位置,最后让小怪移动。PathFollow2D 节点将沿路径移动,并会自动旋转,所以我们将使用它来选择怪物的方位和朝向。生成小怪后,我们会在 150.0250.0 之间选取随机值,表示每只小怪的移动速度(如果它们都以相同的速度移动,那么就太无聊了)。

注意,必须使用 add_child() 将新实例添加到场景中。

func _on_mob_timer_timeout():
	# MobTimer定时器结束时要做什么事情
	# 触发该场景的实例化
	var mob = mob_scene.instantiate()
	
	# 在路径节点上选择一个随机的位置
	var mob_spawn_location = $MobPath/MobSpawnLocation
	mob_spawn_location.progress_ratio = randf()
	
	# 设置生物的方向垂直于路径方向。
	var direction = mob_spawn_location.rotation + PI / 2
	# 将生物的位置设置为随机位置
	mob.position = mob_spawn_location.position
	
	# 让怪物的方向更加的随机,为direction重新赋值
	direction += randf_range(-PI / 4, PI / 4)
	mob.rotation = direction
	
	# 随机一个区间
	var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
	# 设置怪物实体的线速度,单位为像素每秒。
	# velocity.rotated(direction)将这个结果旋转弧度
	mob.linear_velocity = velocity.rotated(direction)
	
	# 添加怪物到主场景
	add_child(mob)

测试场景

让我们测试这个场景,确保一切正常。请将对 new_game 的调用添加至 _ready()

func _ready():
	new_game()

让我们同时指定 Main 作为我们的"主场景"------游戏启动时自动运行的场景。按下"运行"按钮,当弹出提示时选择 main.tscn

你应该可以四处移动游戏角色,观察敌人的生成,以及玩家被敌人击中时会消失。

当你确定一切正常时,在 _ready() 中删除对 new_game() 的调用,使用 pass 替代它。

我们的游戏还缺点啥?缺用户界面。在下一课中,我们将会添加标题界面并且显示玩家的分数。

相关推荐
向宇it1 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
白乐天_n2 小时前
腾讯游戏安全移动赛题Tencent2016A
安全·游戏
这是我582 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
向宇it3 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
tealcwu3 小时前
【游戏设计原理】21 - 解谜游戏的设计
游戏·游戏策划
清梦20203 小时前
经典问题---跳跃游戏II(贪心算法)
算法·游戏·贪心算法
tealcwu4 小时前
【游戏设计原理】22 - 石头剪刀布
游戏·游戏策划
每日出拳老爷子6 小时前
【图形渲染】【Unity Shader】【Nvidia CG】有用的参考资料链接
unity·游戏引擎·图形渲染
l138494274517 小时前
Java每日一题(2)
java·开发语言·游戏
YY-nb14 小时前
Unity Apple Vision Pro 开发教程:物体识别跟踪
unity·游戏引擎·apple vision pro