【Godot4自学手册】第二十八节利用组合实现怪物的受伤

news/2024/5/18 15:18:45 标签: godot, 游戏引擎, Godot4, 游戏程序, 游戏, 组合

这节中,我将利用组合思想进一步优化构建怪物。计算机中的“组合”指的是在编程和算法设计中使用的一种技术,它涉及将多个元素或部分以特定方式结合在一起,以创建更复杂的数据结构或处理流程。我把不同对象的共有功能抽象为一个个组件,当构建某一个特定的的对象时再讲这些组件组合到一起。例如:主人公、敌人共有的功能一个是生命、攻击和碰撞,就可以抽象出三个组件,如果我们构建一颗子弹,这颗子弹只有攻击和碰撞,所以我们可以组成这两个组件,如果我们构建一棵树木,这棵树木有生命和碰撞功能,我们可以用这两个组件构成树木的一部分。开始吧。

一、构建生命组件

1.节点布局

新建Node2D场景命名为HealthComponent,保存到新建的Component文件夹内。一是新建TextureProgressBar节点用于血量显示,命名为HealthBar。为其添加TextureProgressBar子节点,命名为BackBar。二是为根节点添加Label子节点,命名为ChargeHealth,用于显示血量减少的数值。三是为根节点添加AnimationPlayer子节点,用于播放血量减少的动画。最终节点目录情况如下:
请添加图片描述

2.节点属性设置
(1)血量显示节点HealthBar的属性配置。

选择该节点,然后在其检查器中设置Textures属性,Over属性对应设置边框背景,Progress对应选择黄色背景图片素材;Range属性中Min Value:0,Max Value:100;Value:100。
选择该节点的子节点BackBar,在其检查器中将Progress对应选择红色背景图片素材,然后开启CanvasItem->Visibility->Show Behind Paren把其放在黄色背景的下面,目的是黄色血量有变化立即减少,这个红色血量有个减少的过程。如果不会设置属性的请参考【Godot4自学手册】第十八节主人公的血量显示这一节有详细的介绍。
请添加图片描述

(2)掉血显示节点ChargeHealth配置。

将ChargeHealth移动到血条的正上方,然后修改对象的旋转轴心。很简单,只需要选中该节点单击上方的修改对象的旋转轴心按钮,移动轴心位置即可。
请添加图片描述

(3)掉血显示动画配置。

选择该节点在其动画面板中新建动画命名为damage,动画时长设置为0.7。position设置: 0秒设置(10,-26),0.1秒设置(10,-53),0.3秒设置(10,-60)。
scale设置: 0秒设置(1,1),0.1秒设置(3,3),0.3秒设置(1,1)。
modulate设置: 0秒,0.4秒不透明度设为1,0.7秒不透明度设为0。
请添加图片描述

如果不知道具体设置的请参考【Godot4自学手册】第十九节敌人的血量显示及掉血特效_godot textureprogressbar-CSDN博客中序号一、创建敌人的血条下面的小4设置文字动画。

3.编写代码

为根节点添加代码,存在Component目录下,命名为HealthComponent.gd,代码如下:

extends Node2D
class_name HealthComponent  #类名
@onready var health_bar = $HealthBar  #获取血量显示节点
@onready var back_bar = $HealthBar/BackBar #获取血量显示背景节点
@onready var charge_health = $ChargeHealth  #获取掉血量显示节点
@onready var animation_player = $AnimationPlayer  #获取掉血动画播放器

@export var MAX_HEALTH:=100.0  #定义最大血量
var health:float  #定义当前血量

func _ready():
	health = MAX_HEALTH  #初始化时,当前血量等于最大血量
	health_bar.value = health  #将血量显示节点设置为当前血量   黄色血条
	back_bar.value = health  #将血量显示背景节点设置为当前血量  红色血条
	
### 受伤函数
func damage(attack:Attack):
	charge_health.text = str("-") + str(attack.attack_damage)  #将当前掉血量赋值给掉血量显示节点
	health -=attack.attack_damage  #计算当前血量
	health_bar.value = health  #更新血量条
	var tween = get_tree().create_tween()  #创建create_tween类
	tween.tween_property(back_bar,"value",health,0.5)	#将血量显示背景血量条调整到当前血量,0.5秒的一个减血过程
	animation_player.play("damage") #播放掉血量动画
	if health<0:  #如果当前血量小于0,销毁当前对象的父对象
		get_parent().queue_free()
二、构建碰撞组件

新建Area2D场景命名为HitboxComponent,保存到新建的Component文件夹内。为根据点添加如下代码:

extends Area2D
class_name HitboxComponent #类名

@export var health_component:HealthComponent #定义HealthComponent组件
func damage(attack:Attack): #攻击函数
	if health_component:
		health_component.damage(attack) #调用HealthComponent组件的受伤函数

三、调用构建组件

切换到Monster场景,选中根节点,单击实例化子场景,将我们刚才新建的两个组件实例化到场景中。选中HitboxComponent节点,在检查器中在health_component属性后面选择指定按钮,在弹出的对话框选择HealthComponent。
请添加图片描述

然后在Collison中layer设置Enemy图层,mask不选择。
请添加图片描述

四、定义攻击类

定义攻击类Attack,主要用来传递参数等。代码如下:

class_name  Attack #定义类
var attack_damage:float #攻击力
var konckback_force:float #攻击后退理论
var attack_position:Vector2  #攻击位置

五、设置主人公的碰撞

切换到Player场景,选择结点,Collison中layer设置HitPlayer图层,mask设置为Enemy层。
请添加图片描述

让后切换到信号选项卡,双击area_entered(area:Area2D),在弹出对话框中选择Player,为Player添加信号。
请添加图片描述

在信号中,填写如下代码:

var attack_damage :=20.0  #攻击力
var knockback_force :=100.0 #击退力量

func _on_hit_box_area_entered(area):	
	if area.has_method("damage"):
		var attack = Attack.new()
		attack.attack_damage = attack_damage
		attack.konckback_force = knockback_force
		area.damage(attack)

看一下效果:
请添加图片描述


http://www.niftyadmin.cn/n/5450693.html

相关文章

数据挖掘|数据预处理|基于Python的数据标准化方法

基于Python的数据标准化方法 1. z-score方法2. 极差标准化方法3. 最大绝对值标准化方法 在数据分析之前&#xff0c;通常需要先将数据标准化&#xff08;Standardization&#xff09;&#xff0c;利用标准化后的数据进行数据分析&#xff0c;以避免属性之间不同度量和取值范围差…

面试算法-102-LRU 缓存

题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否则返…

OSCP靶场--Codo

OSCP靶场–Codo 考点 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.229.23 -Pn -sV -sC --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-25 05:04 EDT Nmap scan report for 192.168.229.23 Host is up (0.35s latency). Not sh…

C++ MFC 只启动一个程序实例 唤醒之前的实例(完整源码)

初级代码游戏的专栏介绍与文章目录-CSDN博客 很多时候我们希望只允许启动一个程序实例&#xff0c;如果再次运行&#xff0c;就唤醒之前的实例。 目录 1 概述 2 相关技术介绍 2.1 互斥对象 2.2 查找窗口 2.3 唤醒窗口 1 概述 技术上并不难&#xff0c;涉及到以下几个技术…

Jmeter使用BeanShell保存数据到文件

1、目的 在使用jmeter压测时&#xff0c;业务上下连贯&#xff0c;需要对一些编号进行关联操作。这里使用‘JSON提取器’将值提取出来&#xff0c;后面请求可以直接使用。其它业务想要使用就只能把值保存到文件&#xff0c;再使用文件做参数化了。 2、JSON提取器 提取请求值 提…

前端理论总结(css3)——css新特性//盒模型

css新特性 1&#xff1a;新增各种CSS选择器 &#xff08;:not(.input)&#xff1a;所有class不是“input”的节点&#xff09; 2&#xff1a;RGBA 3&#xff1a;多栏布局&#xff08;column-count/gap/rule&#xff09; 4&#xff1a;多背景图&#xff08;ba…

《C++ Primer Plus》第七章总结

一、函数的基本知识 要使用C函数&#xff0c;需要&#xff1a; 提供函数原型&#xff1b;提供函数定义&#xff1b;调用函数&#xff1b; #include <iostream> using namespace std; void simple ();int main() {cout << "main() will call the simple() f…

为何ChatGPT日耗电超50万度?

看新闻说&#xff0c;ChatGPT每天的耗电量是50万度&#xff0c;国内每个家庭日均的耗电量不到10度&#xff0c;ChatGPT耗电相当于国内5万个家庭用量。 网上流传&#xff0c;英伟达创始人黄仁勋说&#xff1a;“AI的尽头是光伏和储能”&#xff0c;大佬的眼光就是毒辣&#xff…