Godot引擎 4.0 文档 - 循序渐进教程 - 使用信号

news2024/12/26 21:20:59

本文为Google Translate英译中结果,DrGraph在此基础上加了一些校正。英文原版页面:

Using signals — Godot Engine (stable) documentation in English

使用信号¶

在本课中,我们将研究信号。它们是节点在发生特定事件时发出的消息,例如按下按钮。其他节点可以连接到该信号并在事件发生时调用函数。

信号是 Godot 中内置的一种委托机制,它允许一个游戏对象对另一个游戏对象的变化做出反应,而无需它们相互引用。使用信号限制耦合并保持代码的灵活性。

例如,您可能在屏幕上有一个代表玩家生命值的生命条。当玩家受到伤害或使用治疗药水时,您希望条形图反映这种变化。为此,在 Godot 中,您将使用信号。

注:正如介绍中提到的,信号是 Godot 版本的观察者模式。您可以在这里了解更多信息: https: //gameprogrammingpatterns.com/observer.html

现在,我们将使用一个信号让上一课(监听玩家输入)中的 Godot 图标通过按下按钮移动和停止。

场景设置¶

为了向我们的游戏添加一个按钮,我们将创建一个新的主场景,其中将包含一个按钮和我们在之前课程中编写的场景Sprite2D.tscn

通过转到菜单 Scene -> New Scene 创建一个新场景。

在场景停靠栏中,单击 2D 场景按钮。这将添加一个 Node2D 作为我们的根。

在 FileSystem 停靠栏中,单击您之前保存的文件Sprite2D.tscn并将其拖动到 Node2D 上以对其进行实例化。

我们想添加另一个节点作为 Sprite2D 的兄弟节点。为此,右键单击 Node2D 并选择添加子节点。

搜索 Button 节点类型并添加它。

默认情况下,该节点很小。单击并拖动视口中按钮右下角的手柄以调整其大小。

如果您没有看到手柄,请确保选择工具在工具栏中处于活动状态。

单击并拖动按钮本身,使其更靠近精灵。

您还可以通过在 Inspector 中编辑其 Text 属性来在 Button 上写一个标签。输入“切换动作”【Toggle motion】。

您的场景树和视口应如下所示。

保存新创建的场景。然后您可以使用F6(在 macOS 上Cmd + R) 运行它。此刻,该按钮将可见,但如果您按下它,目前不会发生任何事情。

在编辑器中连接信号¶

在这里,我们想要将按钮的“按下”信号连接到我们的 Sprite2D,并且我们想要调用一个新函数来打开和关闭它的运动。我们需要将脚本附加到 Sprite2D 节点,这是我们在上一课中所做的。

您可以在 Node dock 中连接信号。选择 Button 节点,然后在编辑器的右侧,单击 Inspector 旁边名为“Node”的选项卡。

停靠栏显示所选节点上可用的信号列表。

双击“按下”【pressed】信号打开节点连接窗口。

在那里,您可以将信号连接到 Sprite2D 节点。该节点需要一个接收方方法,即当 Button 发出信号时 Godot 将调用的函数。编辑器为您生成一个。按照惯例,我们将这些回调方法命名为“_on_node_name_signal_name”。在这里,【可以命名为】“_on_button_pressed”。

注:当通过编辑器的 Node dock 连接信号时,您可以使用两种模式。简单的只允许您连接到附加有脚本的节点,并在它们上创建一个新的回调函数【上图】。

高级视图允许您连接到任何节点和任何内置函数,向回调添加参数,并设置选项。您可以通过单击在窗口右下角“高级【Advanced】”按钮切换模式。

点击Connect按钮完成信号连接,跳转到Script工作区。您应该会在左边距中看到带有连接图标的新方法。

如果单击该图标,将弹出一个窗口并显示有关连接的信息。此功能仅在编辑器中连接节点时可用。

让我们用切换节点运动的代码替换带有关键字pass的行。

我们的 Sprite2D 在_process()函数中移动了。Godot 提供了一种打开和关闭【_process函数】处理的方法:Node.set_process()。Node 类的另一个方法, 如果当前处于空闲状态,is_processing()则返回true。我们可以使用not关键字来取得其反转值。

GDScript
func _on_button_pressed():
    set_process(not is_processing())

此功能将切换处理【__process】,进而在按下按钮时打开和关闭图标的动作。

在尝试游戏之前,我们需要简化我们的_process()功能以自动移动节点而不是等待用户输入。将其替换为我们在两节课前看到的以下代码:

GDScript
func _process(delta):
    rotation += angular_speed * delta
    var velocity = Vector2.UP.rotated(rotation) * speed
    position += velocity * delta

您的完整sprite_2d.gd代码应如下所示。

GDScript
extends Sprite2D

var speed = 400
var angular_speed = PI


func _process(delta):
    rotation += angular_speed * delta
    var velocity = Vector2.UP.rotated(rotation) * speed
    position += velocity * delta


func _on_button_pressed():
    set_process(not is_processing())

现在运行场景并单击按钮以查看精灵开始和停止。

通过代码连接信号¶

您可以通过代码而不是使用编辑器连接信号。当您在脚本中创建节点或实例化场景时,这是必需的。

让我们在这里使用不同的节点。Godot 有一个Timer节点,可用于实现技能冷却时间、武器重新加载等。

返回 2D 工作区。您可以单击窗口顶部的“2D”文本或按Ctrl + F1(在 macOS 上Alt + 1)。

在场景停靠栏中,右键单击 Sprite2D 节点并添加一个新的子节点。搜索 Timer 并添加相应的节点。您的场景现在应该如下所示。

选择 Timer 节点后,转到 Inspector 并启用Autostart 属性。

单击 Sprite2D 旁边的脚本图标以跳回脚本工作区。

我们需要做两个操作来通过代码连接节点:

  1. 从 Sprite2D 获取对计时器的引用。

  2. connect()在定时器的“超时”信号上调用该方法。

注:要通过代码连接到信号,您需要调用connect() 要收听的信号的方法。在这种情况下,我们要监听定时器的“超时”信号。

我们希望在实例化场景时连接信号,我们可以使用Node._ready()内置函数来实现,该函数在节点完全实例化时由引擎自动调用。

要获取相对于当前节点的节点引用,我们使用方法 Node.get_node()。我们可以将引用存储在变量中。

GDScript
func _ready():
    var timer = get_node("Timer")

该函数get_node()查看 Sprite2D 的子节点并通过名称获取节点。例如,如果您在编辑器中将 Timer 节点重命名为“BlinkingTimer”,则必须将调用更改为get_node("BlinkingTimer").

我们现在可以在函数中将 Timer 连接到 Sprite2D _ready()

GDScript
func _ready():
    var timer = get_node("Timer")
    timer.timeout.connect(_on_timer_timeout)

该行内容如下:我们将定时器的“超时”信号连接到脚本所附加的节点。当 Timer 发出时timeout,我们要调用函数_on_timer_timeout(),该函数是我们目前需要定义的函数。让我们将它添加到脚本的底部并使用它来切换精灵的可见性。

注:按照惯例,我们将这些回调方法在 GDScript 中命名为“_on_node_name_signal_name”,在 C# 中命名为“OnNodeNameSignalName”。在这里,GDScript 为“_on_timer_timeout”,C# 为 OnTimerTimeout()。

GDScript
func _on_timer_timeout():
    visible = not visible

visible属性是一个布尔值,用于控制节点的可见性。该行visible = not visible切换值visible。如果是true,则变为false,反之亦然。

如果现在运行场景,您会看到精灵以一秒的间隔闪烁。

完整脚本¶

这就是我们移动和闪烁的 Godot 图标小演示!这是完整的sprite_2d.gd文件以供参考。

GDScript
extends Sprite2D

var speed = 400
var angular_speed = PI


func _ready():
    var timer = get_node("Timer")
    timer.timeout.connect(_on_timer_timeout)


func _process(delta):
    rotation += angular_speed * delta
    var velocity = Vector2.UP.rotated(rotation) * speed
    position += velocity * delta


func _on_button_pressed():
    set_process(not is_processing())


func _on_timer_timeout():
    visible = not visible

自定义信号¶

注:本节是关于如何定义和使用您自己的信号的参考,而不是建立在之前课程中创建的项目的基础上。

您可以在脚本中定义自定义信号。例如,当玩家的生命值达到零时,您想要显示游戏结束屏幕。为此,您可以定义一个名为“死亡”或“健康耗尽”的信号,当它们的健康状况达到 0 时。

GDScript
extends Node2D

signal health_depleted

var health = 10

注:由于信号代表刚刚发生的事件,我们通常在其名称中使用过去式的动作动词。

您的信号与内置信号的工作方式相同:它们出现在“节点”选项卡中,您可以像连接任何其他信号一样连接到它们。

要在脚本中发出信号,请调用emit()信号。

GDScript
func take_damage(amount):
    health -= amount
    if health <= 0:
        health_depleted.emit()

信号可以选择性地声明一个或多个参数。在括号之间指定参数名称:

GDScript
extends Node

signal health_changed(old_value, new_value)

var health = 10

注:信号参数显示在编辑器的节点停靠栏中,Godot 可以使用它们为您生成回调函数。但是,您仍然可以在发出信号时发出任意数量的参数。所以由你来发出正确的值。

要随信号发出值,请将它们作为额外参数添加到函数中 emit()

GDScript
func take_damage(amount):
    var old_health = health
    health -= amount
    health_changed.emit(old_health, health)

总结¶

Godot 中的任何节点都会在特定事件发生时发出信号,例如按下按钮。其他节点可以连接到单独的信号并对选定的事件出反应 。

信号有很多用途。有了它们,您可以对进入或退出游戏世界的节点、碰撞、角色进入或离开区域、界面元素大小变化等等做出反应。

例如,每当玩家的物理身体进入其碰撞形状时,表示硬币 的Area2Dbody_entered就会发出信号,让您知道玩家何时收集了它。

在下一节“您的第一个 2D 游戏”中,您将创建一个完整的 2D 游戏并将到目前为止所学的一切付诸实践。

【DrGraph】:信号类似于Windows应用程序中的消息,而且更为简单。从Godot的设计思路来看,信号只是将本对象(节点、脚本、场景...)的某些消息暴露给本对象的父对象调用,这些消息是本对象的一些业务逻辑时机(时刻),若父对象绑定了这些信号,则在本对象的相应业务逻辑时刻会调用父对象的相应函数。因为是父对象内部调用,如果修改了父对象的一些属性等,就可以影响父对象的业务逻辑。

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

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

相关文章

S7-1200中通过MODBUS TCP客户端在一次请求中实现从服务器读写一个或多个保持性寄存器的具体方法

S7-1200中通过MODBUS TCP客户端在一次请求中实现从服务器读写一个或多个保持性寄存器的具体方法 TIA博途V17中增加了MODBUS TCP客户端功能码 23,可以在一次请求作业下实现从服务器读取和写入一个或多个保持性寄存器,这样省去了轮询的编程工作量,提高了工作效率,如下图所示,…

第三章 卷积神经网络

目录 一、CNN 基础二、CNN 进阶 卷积神经网络&#xff0c;Convolutinal Neural Network&#xff0c;CNN 在之前两章的由线性模型构成的神经网络都是全连接神经网络 一、CNN 基础 在之前全连接层处理二维图像的时候&#xff0c;直接将二维图像从 N 1 28 28 N \times 1 \t…

【DolphinScheduler 安装部署】DolphinScheduler调度系统如何安装部署?

要安装DolphinScheduler&#xff08;以下简称DS&#xff09;调度系统&#xff0c;请按照以下步骤进行操作&#xff1a; 系统要求&#xff1a; 确保您的计算机满足DS的最低系统要求&#xff0c;例如操作系统版本、内存和处理器要求等。DS通常在Linux系统上运行良好。 下载DS安装…

k8s部署mongodb副本高可用集群

此版本的NFS为单点&#xff0c;仅为练习使用&#xff0c;生产环境建议使用cephfs的卷类型&#xff0c;避免单点。或者通过keepalived加Sersync的方案对NFS作容灾处理即可用于生产环境。当然&#xff0c;对于开发或测试环境&#xff0c;方便起见&#xff0c;直接使用单点的NFS加…

Oracle OCP 和MySQL OCP 考试完成后查询成绩和下载证书的步骤

我的一些学员考完Oracle OCP和MySQL OCP不知道如何查看自己的考试成绩和证书&#xff0c;姚远老师现在详细说明具体的操作步骤&#xff0c;一共8步。 关于号主&#xff0c;姚远&#xff1a; Oracle ACE&#xff08;Oracle和MySQL数据库方向&#xff09;Oracle MAA 大师华为云…

基于Java+Springmvc+vue+element实现大学生科技创新创业项目管理系统

基于JavaSpringmvcvueelement实现大学生科技创新创业项目管理系统 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源…

【校园网设计】基于ensp的跨地区的校园网组网方案

本博客是基于模拟器ensp的校园网组网方案&#xff0c;有总校区和分校区&#xff0c;主要用了vlan划分、dhcp、nat、ospf、acl、bgp等技术。首先说一下本博客的局限性&#xff1a; 总校区和分校区之间只是使用的传统的bgp建立连接&#xff0c;这样可以在运营商上看到内网的明细&…

Squid 代理服务器的应用(传统代理、透明代理、ACL控制列表、sarg日志分析、反向代理)

一、Squid代理服务器的概述 squid 作为一款服务器代理工具&#xff0c;可以缓存网页对象&#xff0c;减少重复请求&#xff0c;从而达到加快网页访问速度&#xff0c;隐藏客户机真实IP&#xff0c;更为安全。 Squid主要提供缓存加速、应用层过滤控制的功能 1、squid代理的工…

Android Studio SDK无法勾选安装的解决方案

问题描述 1、在初次安装好Android Studio后&#xff0c;会启动AS&#xff0c;出现经典的Unable to access Android SDK add-on list报错&#xff0c;点Cancel即可。网上的解决方法分为两种&#xff1a;&#xff08;1&#xff09;设置Proxy为教育网&#xff08;2&#xff09;在…

Linux 下安装SonarQube (版本sonarqube7.6)

公司的虚拟环境坏了&#xff0c;sonarqube需要重新安装。简单记录安装过程和遇到的问题。 相关环境信息 CentOS Linux release 7.6.1810 (Core)MySQL 5.7.30sonarqube7.6JDK 11.0.2 一 安装Sonar前需要知道 1为什么要代码清洁 软件的核心是代码。代码不仅指导业务行为&#…

陈丹琦团队最新力作:上下文学习在上下文“学到”了什么?

深度学习自然语言处理 原创作者 | 鸽鸽 这段时间in-context learning真的很火&#xff0c;陈丹琦组最新的两篇文章都是ICL相关&#xff0c;今天我们拜读其中一篇&#xff1a;丹琦的硕士生、纽约大学准博士生Jane Pan的ACL小短文。 大佬的学生会做出怎样的科研示范呢&#xff1f…

单位、家庭建筑物电气、电子设备防雷举措

前 言 在现实的学习、工作、生活中&#xff0c;有时会面对自然灾害、重特大事故、环境公害及人为破坏等突发事件&#xff0c;为了控制事故的发展&#xff0c;就不得不需要事先制定应急预案。那要怎么制定科学的应急预案呢﹖下面是小编为大家整理的单位、住宅建筑物、电子电气防…

Flink有状态计算的状态容错

状态容错 State Fault Tolerance 首先来说一说状态容错。Flink 支持有状态的计算&#xff0c;可以把数据流的结果一直维持在内存&#xff08;或 disk&#xff09;中&#xff0c;比如累加一个点击数&#xff0c;如果某一时刻计算程序挂掉了&#xff0c;如何保证下次重启的时候&…

VM600 IOCN 输入/输出接口卡

用于CPUM卡的VM600 IOCN输入/输出卡 CPUM卡的输入/输出(接口)卡一个主以太网连接器(8P8C (RJ45))&#xff0c;用于与VM600 MPSx软件和/或Modbus TCP和/或PROFINET通信进行通信一个辅助以太网连接器(8P8C (RJ45))&#xff0c;用于冗余Modbus TCP通信一个主要串行连接器(6P6C (R…

LightningChart JS 4.0.x Crack

Lightning-fast, interactive & responsive 2D & 3D JavaScript charts. Next Generation, World’s Fastest JS Charts Getting Started with LightningChart JS There’s multiple ways to get started with our JS charting library. You can install the package…

CMake Practice 学习笔记二---子目录、安装

让前面的Hello World更像一个工程&#xff1a; 为工程添加一个子目录src&#xff0c;用来放置工程源代码&#xff1b;添加一个子目录doc&#xff0c;用来反之这个工程的文档hello.txt&#xff1b;在工程目录添加文本文件COPYRIGHT&#xff0c;README&#xff1b;在工程目录添加…

Linux常见指令(3)

Linux常见指令 ⑶ date指令引入描述用法例子时间时间戳 cal指令描述用法例子 find指令描述用法例子补充which指令whereis指令 grep指令描述用法例子grep 对文件的操作grep 对目录的操作 补充 打包压缩 和 解压解包zip && unzip描述用法例子对文件的操作对目录的操作 ta…

苹果手机没有备份怎么恢复数据?数据恢复,轻松解决!

案例&#xff1a;苹果手机没有进行过iTunes和iCloud备份&#xff0c;手机还原后数据都被抹掉了&#xff0c;还能恢复数据吗&#xff1f; 【求问各位大神&#xff0c;我几天前把苹果手机的数据还原了&#xff0c;也没有提前进行过数据的备份。现在想起来之前微信上有一些重要的…

uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况

1、使用 json-bigint&#xff0c;失败 2、使用 config 里的 getTask&#xff0c;失败 3、修改 dataType&#xff0c;成功 原因&#xff1a; 通过ajax请求回来的数据在response和preview两种状态显示的是不同的。response中的看到的数据格式其实是字符串&#xff08;ajax请求…

GPT-4 国内使用指南 保姆教程

gpt持续火爆&#xff0c;然鹅国内很多朋友还说不会使用&#xff0c;因此有必要科普一篇文章&#xff01; app.educlub.icu很多朋友因为各种限制无法开通#ChatGPT Plus&#xff0c;而申请OpenAI的GPT-4 API也要慢慢排队&#xff08;我的也还没下来&#xff09;。于是在这里我搜…