
之前的疑惑
现在看起来客户端大一统啊!哈哈哈
因为游戏的UI界面和玩家很有可能跨了很多层(不管是平层还是父子层,总之你很难在节点树的层面找到他们的关系)但是又需要让他们联动,这个时候一般就会使用事件总线EventBus来做。
这里也有一个通用的生命组件来掺和~
因为游戏中,不只是玩家,每个敌人也是有生命值的,所以我们抽离一个单独的节点来对生命值做管理
extends Node2D
class_name HealthComponent;
signal on_health_changed(current_health: float)
signal on_dead
var current_health: float;
var max_health: float;
# setup 组件初始化
func setup(value: float)->void:
max_health = value
current_health = value
# take_damage 受伤
func take_damage(value: float):
if current_health <= 0:
return
# 保证current 最少只能为0
current_health = max(current_health - value,0)
on_health_changed.emit(current_health)
if current_health <= 0:
on_dead.emit()
EventBus.on_player_health_updated.emit(current_health,max_health)简版的:一个初始化函数,一个受伤函数(里面通过事件总线触发值的改变)
然后把这个节点挂载到你想用这个组件管理的节点就行了!

其实eventBus里面就是定义各种事件信号,多个节点监听就可以互相通信了
extends Node
# on_player_health_updated health_updated的时候
signal on_player_health_updated(current:float,max:float)然后你可以在里面初始化要管理的血量值
# 引入使用
@onready var health_component: HealthComponent = %HealthComponent
# 初始化组件的值
health_component.setup(max_health)
# 模拟受伤
func _input(event: InputEvent) -> void:
if event.is_action_pressed(&"ui_accept"):
health_component.take_damage(1)然后来打其他场景让UI组件去使用

town.gd
@onready var health_bar: ProgressBar = %HealthBar
func _ready() -> void:
# 信号监听
EventBus.on_player_health_updated.connect(_on_player_health_updated)
# 在这里面就可以监听到Player受到HealComponent管理的最新的血条了!
func _on_player_health_updated(current_health:float, max_health:float) -> void:
health_bar.value = current_health/max_health看看效果:
