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

news2025/1/10 20:59:12

游戏主场景

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

创建新场景并添加一个 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 节点将产生新的生物, 我们希望它们出现在屏幕边缘的随机位置. 添加一个名为 MobPath 的 Path2D 节点作为 Main 的子级. 当你选择 Path2D 时, 你将在编辑器顶部看到一些新按钮:

在这里插入图片描述

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

../../_images/draw_path2d.gif

在图像上放置点 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 替代它。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2065237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ZooKeeper 的3种部署模式

ZooKeeper 的3种部署模式 1. 单机模式(Standalone Mode)2. 伪集群模式(Pseudo-Cluster Mode)3. 集群模式(Cluster Mode) 💖The Begin💖点点关注,收藏不迷路💖…

[000-01-011].第2节:持久层方案的对比

我的后端学习大纲 MyBatis学习大纲 1.持久层解决方案: 1.1.面试1:请说一说持久层解决方案有哪些??? 1.jdbc JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。Java程序员使用JDB…

Vodafone 推出了与 Wi-Fi 竞争的基于树莓派私人5G技术

随着全球5G网络的逐步推出,在其过程中遇到了可预见的起起伏伏,并且蜂窝技术也开始进入另一个无线技术 Wi-Fi ,并且已经占据的市场。私有5G网络(即个人或公司建立自己的全设施蜂窝网络)如今正在寻找曾经属于Wi-Fi的唯一…

Unity低延迟播放RTSP视频流

Unity播放RTSP视频流这个功能在好几个项目中用到,虽然有一些现成的插件(VLC for unity、UMP)可以使用,但是延迟高(300毫秒以上)的问题一直没法解决。 最近终于下定决心来解决这个问题,经过几天…

基于 Jenkins、Gitlab、Harbor、Helm 和 Kubernetes 的 CI/CD

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

【微服务部署】Linux部署微服务启动报ORA-01005

问题背景: Linux机器部署springboot微服务,部署完成后发现无法启动,后台报ORA-01005错误。 解决方案: 1.检查当前服务器是否已安装oracle客户端 命令行执行sqlplus username/passwd实例名,如果执行成功,说…

【Canvas与艺术】十边曲线形光阑

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>十边曲线型光阑</title><style type"text/css"&g…

机器学习-识别手写数字

机器学习可以首先构建一个神经网络&#xff0c;用于识别手写数字。通过训练数据&#xff0c;优化神经网络的参数。再利用测试数据来测试训练完成后的神经网络的准确度。本次需要下载的库有tensorflow和matplotlib&#xff0c;keras和mnist数据集一般都被集成在tensorflow中了。…

C/C++语言基础--指针三大专题详解3,完结篇(包括指针做函数参数,函数指针,回调函数,左右法则分析复杂指针等)

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 指针是C/C的灵魂&#xff0c;和内存地址相关联&#xff0c;运行的时候速度快&#xff0c;但是同时也有很多细节和规范要注意的&#xff0c;毕竟内存泄漏是很恐怖的指针打算分三篇文章进行讲解&#xff0c;本…

LabVIEW多显示器环境下主显示器识别与管理

该程序使用 LabVIEW 图形化编程语言&#xff0c;涉及多显示器环境中主显示器的识别与信息提取。图像显示了两个不同的方法来获取主显示器的信息。 第一部分&#xff1a;方法一——基于显示器位置的主显示器识别 1. 当前监视器识别&#xff1a; 使用“FP.Monitor”属性节点获取…

在AES加密中,设主密钥为“2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C”,试计算迭代第1轮使用的轮密钥。

题解: 1.分析: 第一轮使用的轮密钥是W[4]、W[5]、W[6]、W[7] w[i](4≤i≤43)求法: (1)i不为4的倍数 w[i] = w[i-1] ⊕w[i-4] (2)为4的倍数 w[i]=SubWord(RotWord(w[i-1]))⊕w[i-4]⊕Rcon[i/4] 解释: ①RotWord:将w[i-1]的4个字节循环上移一个字节 ②SubWo…

JVM的类是如何运行的

本文就是讲解 如何将.class文件转换为机器码

U盘中毒文件被隐藏怎么恢复文件?

很多用户都曾经遇到过U盘文件被病毒隐藏的问题&#xff0c;U盘作为拷贝、存储文件最主要的移动存储设备&#xff0c;里面经常存储了重要的文件&#xff0c;如果文件被隐藏了会给用户带来很多麻烦。那么U盘文件被病毒隐藏&#xff0c;应该怎么解决呢&#xff1f;本文列举了有效的…

QT中使用QAxObject类读取xlsx文件内容并显示在ui界面

一、源码 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACEclass MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();pr…

Andrid异步更新UI:Handler(二)深入了解:Message你真的会创建?它是如何子线程和主线程通知?

目录 为什么会有HandlerHandler的原理&#xff0c;以及对象讲解主线程的loop在哪里&#xff0c;为什么主线程loop没有阻塞呢&#xff1f;Looper如何保证唯一Handler为什么会引发内存泄漏呢&#xff1f;Message应该如何创建它&#xff1f; 一、为什么会有Handler 线程分为主线…

软件工程造价师习题练习 18

1.在软件估算过程中&#xff0c;我们主要对项目的规模&#xff0c;质量&#xff0c;进度和成本进行估算 错误 正确 软件估算不对质量进行估算&#xff0c;只对项目的规模&#xff0c;进度&#xff0c;成本进行估算。 答案&#xff1a;错误 2.在使用类比法进行估算时&#xf…

基于单片机的电子指南针设计

摘要&#xff1a;随着科技的进步与发展&#xff0c;尤其是电子技术的推动下社会逐渐向智能化、信息化和人工智能等方面发展。与此同时市场更加需要掌握精确的方位角度信息&#xff0c;服务到生活、产业、出行、航行等各方各面。传统的指南针由于本身的物理特性&#xff0c;抗干…

深度剖析C++string(上篇)

目录 前言 1.C string类 2.string类中的常见构造 3.string类对象的容量操作 4.. string类对象的访问及遍历操作 5. auto和范围for(补充&#xff09; auto关键字 范围for 结束语 前言 C语言我们学习了字符串和字符串的相关函数&#xff0c;在C语言中&#xff0c;字符串是…

【Redis基础1】——使用场景-缓存穿透

目录 1-引言&#xff1a;初始缓存穿透1-1 缓存穿透是什么&#xff1f;(What)1-2 缓存穿透是怎么造成的&#xff1f;(Why) 2- 核心&#xff1a;如何避免缓存穿透&#xff08;How&#xff09;2-1 方案1&#xff1a;缓存空数据2-2 方案2&#xff1a;布隆过滤器2-2-1 布隆过滤器原理…

计算机毕业设计Hive+Hadoop深圳共享单车预测系统 共享单车数据分析可视化大屏 共享单车爬虫 共享单车数据仓库 机器学习 深度学习 PySpark

步骤&#xff1a; 1.Python采集深圳政府公开数据平台的共享单车数据(最大可采集上亿2017-2021数据)&#xff0c;并用百度逆地理编码服务解析经纬度获取位置信息。并将数据上传hdfs&#xff1b; 2.可使用sklearn、卷积神经网络等算法对数据进行分析&#xff0c;对共享单车的订单…