这一节,我主要学习敌人的血量显示、掉血显示和死亡效果。敌人的血量显示和主人公的血量显示有所不同,主要是在敌人头顶有个红色的血条,受到攻击敌人的血条会减少,并且有掉血数量的文字显示,效果如下:
一、创建敌人的血条
1.节点布局
新建Node场景命名为HealthBar,给HealthBar添加3个子节点,一是TextureProgressBar命名为HbarTxp,二是Label命名为ShowLb,三是AnimationPlayer命名为AnimaP。整个场景节点情况如下:
保存场景到Scenes文件夹下。
2.设置血条
选择HbarTxp节点, 在其检查器中Textures->Progress选择新建AtlasTexture(纹理图集),然后单击该图集在其属性面板中,将我们做好的血量图片拖拽到Atlas下,操作图如下:
下一步单击Region->编辑区域按钮,在弹出的区域编辑器中,吸附模式选择自动裁剪,然后单击红色血条,然后选择关闭。操作过程如下:
同理,设置Textures->Over,操作过程类似,只不过背景图片选择血条背景图片框,选择的图片如下:
HbarTxp检查器中将Textures->Progess Offset设置为(1,1),如下:
最后,在HbarTxp检查器中将Radial Fill->Max Value 设置为1,Step设置为0,Value设置为0,5,参数如下:
在编辑器中调整HealthBar居中,最后效果如下:
3.设置文本显示
选择ShowLb结点,在其检查器中将Text属性随便输入一个数字10。Theme Overrides->Colors->Font Color选择红色,如下:
在编辑器中调整ShowLb到血量条的正上方,最后效果如下:
4.设置文字动画
选择AnimaP节点,在其动画面板中“动画”按钮下拉菜单中选择新建动画。
新动画名称设置为Hurt。
动画时长设置为0.6,将播放头放到第1帧,选择ShowLb,在其检查器中Layout->Transform->Position后面的关键帧按钮将此关键帧添加到动画第一帧。
将播放头放到第4帧,向上调整ShowLb到合适位置,同理将该位置添加到第4关键帧。
将播放头放到第1帧,选择ShowLb,在其检查器中Theme Overrides->Colors->Font Color后面的关键帧按钮将此关键帧添加到动画第一帧。
同样设置第3帧。将播放头放到第7帧(动画最后),选择ShowLb,在其检查器中Theme Overrides->Colors->Font Color,将透明度设置为0,如下:
设置完成后单击后方的动画关键帧将透明度为0添加到动画末尾,最后动画面板中Hurt动画设置如下:
最终的动画效果如下:
5.编写脚本代码
给跟节点添加添加脚本,命名为health_bar,保存到Scripts文件夹下。并编写如下代码:
extends Node2D
@export var stats:Stats #定义状态继承自Stats
@onready var hbar_txp = $HbarTxp
@onready var show_lb = $ShowLb
@onready var anima_p = $AnimaP
var oldhealth
# Called when the node enters the scene tree for the first time.
func _ready():
show_lb.visible=false #血量变化文字隐藏显示
oldhealth = stats.health #记录上次血量
stats.health_changed.connect(update_health) #血量变化信号连接到血量更新UI
update_health()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func update_health():
var percentage :=stats.health/ float(stats.max_health) #计算血量百分比
hbar_txp.value = percentage #将百分比赋给进度条
var healthcharge = stats.health-oldhealth #计算血量编号
if(healthcharge!=0):
show_lb.text=str(healthcharge) #血量变化复制给lable
show_lb.visible=true #显示血量变化数字
anima_p.play("Hurt") #播放血量位置隐藏动画
oldhealth=stats.health #记录目前血量
pass
二、给敌人添加血量
切换到Enemy场景,选择根节点,第一是单击添加子节点按钮,在创建Node结点对话框选择Stats,这个类是我们自定义的状态类,单击创建。
第二是单击实例化子场景按钮,在弹出的实例化子场景对话中选择,我们刚才新建的health_bar.tsc场景,然后单击打开按钮,将health_bar实例化到Enemy场景。
选中HealthBar结点,然后在其检查器中Stats属性上单击,在弹出对话框中stats,单击确定,这样stats状态就和HealthBar链接起来了。
三、编写代码
切换到Enemy代码,编写代码。首先获取状态结点,代码如下:
@onready var stats = $Stats
然后修改hurt_state受伤代码:
stats.health -=10 #受伤一次减去10点血量
var dir = hurtdirecion.direction_to(global_position).normalized()
if abs(dir.x)>abs(dir.y):
if dir.x<0:
velocity.x =-knockback
else :
velocity.x =knockback
else:
if dir.y<0:
velocity.y =-knockback
else :
velocity.y =knockback
anima_p.play("TakeHit")
await anima_p.animation_finished
if stats.health<=0:#血量小于等于零时,敌人进入死亡状态
state=DEATH
else:
velocity = Vector2.ZERO
state=CHASE
这样,敌人就有血量显示了。今天就到这了,下节再见!