【Godot 3.5组件】简单血条组件HealthBar

2024-03-22 08:52

本文主要是介绍【Godot 3.5组件】简单血条组件HealthBar,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

说明

本文原文写自2022年,内容基于Godot3.5。是本人早期进行Godot组件化和自定义节点探索时的产物,当时的代码和思想可能不太成熟,但贴出来,供需要学习组件化基础思路的同学食用。

概述

血条作为一个非常基础和常见的组件,Godot并没有给我们提供现成的,相反我们需要通过魔改Progress节点或使用TextureProgress节点和制作一些图片来实现它们。

本篇内容介绍的是我前不久刚制作的一个简单血条组件,它是基于Progress节点和StyleBoxFlat资源修改样式制作的。灵感是Hi小胡的视频。与他一步一步教你不同,我不会教你我是如何一步步制作的。

相反,你只需要在自己的项目里创建一个Progress节点,你可以将它重命名为“HealthBar”。
image.png
为其创建脚本,并复制粘贴如下代码:

# ======================================================================
# 名称:HealthBar
# 描述:一个简单的基于ProgressBar样式修改的参数化血条组件
# 类型:UI组件,原生控件扩展
# 作者:巽星石
# Godot版本:3.5
# 创建时间:2022102422:56:00
# 最后修改时间:2022102921:12:08
# ======================================================================tool
extends ProgressBarsignal dead()    # 已经到达最小值
signal val_changed(value)    # 血量发生变化
signal is_maxed()  # 已经到达最大值export(Color) var bg_color = Color(0.941176, 0.043137, 0.043137) setget set_bg_color # 背景颜色
export(Color) var fg_color = Color(0.286275, 0.8, 0.258824) setget set_fg_color # 前景颜色
export(Color) var border_color = Color(0.952941, 0.952941, 0.952941) setget set_border_color       # 描边 - 颜色
export(int,0,20) var border_width = 2 setget set_border_width   # 描边 - 宽度
export(int,0,200) var corner_radius = 2 setget set_corner_radius # 圆角半径# ========================= Setter&Getter =========================
func set_bg_color(val:Color):bg_color = val# 设置StyleBox中的属性var bg_style = get_bg_style_box()var fg_style = get_fg_style_box()bg_style.bg_color = valfunc set_fg_color(val:Color):fg_color = val# 设置StyleBox中的属性var fg_style = get_fg_style_box()var bg_style = get_bg_style_box()fg_style.bg_color = valfunc set_border_color(val:Color):border_color = val# 设置StyleBox中的属性var bg_style = get_bg_style_box()bg_style.border_color = valvar fg_style = get_fg_style_box()var fg_border_color = Color(0,0,0,0)fg_style.border_color = fg_border_colorfunc set_border_width(val:int):border_width = val# 设置StyleBox中的属性var bg_style = get_bg_style_box()bg_style.border_width_bottom = valbg_style.border_width_left = valbg_style.border_width_right = valbg_style.border_width_top = valvar fg_style = get_fg_style_box()fg_style.border_width_bottom = valfg_style.border_width_left = valfg_style.border_width_right = valfg_style.border_width_top = valfunc set_corner_radius(val:int):corner_radius = val# 设置StyleBox中的属性var bg_style = get_bg_style_box()bg_style.corner_radius_bottom_left = valbg_style.corner_radius_bottom_right = valbg_style.corner_radius_top_left = valbg_style.corner_radius_top_right = valvar fg_style = get_fg_style_box()fg_style.corner_radius_bottom_left = valfg_style.corner_radius_bottom_right = valfg_style.corner_radius_top_left = valfg_style.corner_radius_top_right = val# ========================= 加载 =========================func _enter_tree(): # 替换原有的stylebox# 背景var box = create_styleboxflat(bg_color,border_color,border_width,[corner_radius,corner_radius,corner_radius,corner_radius])set("custom_styles/bg",box)var fg_border_color = Color(0,0,0,0)# 前景var box2 = create_styleboxflat(fg_color,fg_border_color,border_width,[corner_radius,corner_radius,corner_radius,corner_radius])set("custom_styles/fg",box2)func _ready():percent_visible = false  # 关闭百分比显示size_flags_horizontal = SIZE_EXPAND_FILLsize_flags_vertical = SIZE_EXPAND_FILL# ========================= 方法 =========================
# 增加血量值
func add(val:int):var tween = create_tween()tween.tween_property(self,"value",value + val,0.2)# 减少血量值
func sub(val:int):var tween = create_tween()tween.tween_property(self,"value",value - val,0.2)# ========================= 信号处理 =========================
func _on_HealthBar_value_changed(value):if value == min_value:emit_signal("dead")if value == max_value:emit_signal("is_maxed")emit_signal("val_changed",value)pass# ========================= 底层方法 =========================
# 获取或创建背景所需的StyleBox
func get_bg_style_box() -> StyleBoxFlat:var boxif get("custom_styles/bg"):box = get("custom_styles/bg")else:# 不存在box = create_styleboxflat(bg_color,border_color,border_width,[corner_radius,corner_radius,corner_radius,corner_radius])set("custom_styles/bg",box)return box# 获取或创建前景所需的StyleBox
func get_fg_style_box() -> StyleBoxFlat:var boxif get("custom_styles/fg"):box = get("custom_styles/fg")else:# 不存在var fg_border_color = Color(0,0,0,0)box = create_styleboxflat(fg_color,fg_border_color,border_width,[corner_radius,corner_radius,corner_radius,corner_radius])set("custom_styles/fg",box)return box# 动态创建StyleBoxFlat
func create_styleboxflat(bg_color = ColorN("white",1),border_color = ColorN("gray",1),border_width = 0,corner_radius = [0,0,0,0],content_margin = [5,5,5,5],expand_margin = [0,0,0,0],has_shadow = false,shadow_size = 1,shadow_color = ColorN("gray",0.5),shadow_offset = Vector2(1,1)) -> StyleBoxFlat:var stylebox:StyleBoxFlat = StyleBoxFlat.new()# 背景stylebox.bg_color = bg_color# 边框stylebox.set_border_width_all(border_width)  # 粗细stylebox.border_color =  border_color  # 颜色# 圆角stylebox.set_corner_radius_individual(corner_radius[0],corner_radius[1],corner_radius[1],corner_radius[1])# 内容边距stylebox.content_margin_bottom = content_margin[0]stylebox.content_margin_left = content_margin[1]stylebox.content_margin_right = content_margin[2]stylebox.content_margin_top = content_margin[3]# 外边距stylebox.set_expand_margin_individual(expand_margin[0],expand_margin[1],expand_margin[2],expand_margin[3])# 阴影if has_shadow:stylebox.shadow_size = shadow_sizestylebox.shadow_color = shadow_colorstylebox.shadow_offset = shadow_offsetreturn stylebox

然后你就可以发现自己有了一个简单的参数化的血条组件。
image.png
当然你还要再做一件事情,手动连接一下value_changed信号到脚本。

image.png

保存和实例化

为了实现复用,你需要将这个场景保存然后关闭,然后在其他场景中实例化这个组件。
比如我们创建有一个Control根节点的场景,实例化一个HealthBar组件。
image.png

通过参数快速调整样式

实例化后的HealthBar组件就像Godot的原生控件一样,可以通过调整其属性来实现快速的样式改变。当然由于我们采用的是export var的形式,也就是“脚本变量”,所以为了区别将其称为“参数”,也可以体现参数化的理念。
image.png image.png
HealthBar组件的“自定义属性”(或叫“参数”)只有5个,但是有于它本质是继承于ProgressBar控件,所以ProgressBar控件所拥有的属性、信号、方法都可以使用。

参数值类型默认值说明
bg_colorColorColor(0.941176, 0.043137, 0.043137)背景颜色
fg_colorColorColor(0.286275, 0.8, 0.258824)前景颜色
border_colorColorColor(0.952941, 0.952941, 0.952941)描边 - 颜色
border_widthint,0,202描边 - 宽度
corner_radiusint,0,2002圆角半径

通过这些参数的设定,你可以快速创建完全不同的颜色和描边样式。
一些参数化后的实例

方法

HealthBar组件提供了两个基础的增加和减少血量的方法,并且通过Godot3.5新增的SceneTreeTween实现了动效。

add(val:int)

当前血量增加给定的数值。变化过程有一个简单的动画效果(使用SceneTreeTween实现)。
并触发val_changed(value)信号,当血量达到最大值时,触发is_maxed()信号。

sub(val:int)

当前血量减少给定的数值。变化过程有一个简单的动画效果(使用SceneTreeTween实现)。
并触发val_changed(value)信号,当血量达到最小值时,触发dead()信号。
效果:
增加和减少血量的动画效果

信号

HealthBar组件自定义了三个信号,你可以在通过节点面板或脚本进行连接。
image.png
具体描述如下。

信号描述
dead()已经到达最小值时触发
is_maxed()已经到达最大值时触发
val_changed(value)值发生变化时触发,参数value返回当前值。

这篇关于【Godot 3.5组件】简单血条组件HealthBar的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/834981

相关文章

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

Mybatis从3.4.0版本到3.5.7版本的迭代方法实现

《Mybatis从3.4.0版本到3.5.7版本的迭代方法实现》本文主要介绍了Mybatis从3.4.0版本到3.5.7版本的迭代方法实现,包括主要的功能增强、不兼容的更改和修复的错误,具有一定的参考... 目录一、3.4.01、主要的功能增强2、selectCursor example3、不兼容的更改二、

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine

Java中数组转换为列表的两种实现方式(超简单)

《Java中数组转换为列表的两种实现方式(超简单)》本文介绍了在Java中将数组转换为列表的两种常见方法使用Arrays.asList和Java8的StreamAPI,Arrays.asList方法简... 目录1. 使用Java Collections框架(Arrays.asList)1.1 示例代码1.

Java8需要知道的4个函数式接口简单教程

《Java8需要知道的4个函数式接口简单教程》:本文主要介绍Java8中引入的函数式接口,包括Consumer、Supplier、Predicate和Function,以及它们的用法和特点,文中... 目录什么是函数是接口?Consumer接口定义核心特点注意事项常见用法1.基本用法2.结合andThen链