42 lines
1.4 KiB
GDScript
42 lines
1.4 KiB
GDScript
# ScreenHpBar —— 角色头顶的屏幕空间 HP 条(§8.8)。
|
|
#
|
|
# 参考端在 CPythonTextTail / CGraphicTextInstance 的屏幕坐标中绘制尾标;
|
|
# 这里用一个无输入的 Control 自绘背景、边框和填充,NetWorld 每帧负责把
|
|
# 实体的世界坐标投影到屏幕。这样 HP 条不会随 Label3D 的 billboard 深度
|
|
# 缩放,也不会被地图几何遮住。
|
|
extends Control
|
|
|
|
const DEFAULT_SIZE := Vector2(72.0, 6.0)
|
|
const MIN_FILL_RATIO := 0.0
|
|
const MAX_FILL_RATIO := 1.0
|
|
|
|
var hp := 0
|
|
var max_hp := 0
|
|
var ratio := 0.0
|
|
var dead := false
|
|
|
|
func _init() -> void:
|
|
mouse_filter = MOUSE_FILTER_IGNORE
|
|
size = DEFAULT_SIZE
|
|
custom_minimum_size = DEFAULT_SIZE
|
|
|
|
func set_vitals(current_hp: int, current_max_hp: int, is_dead: bool) -> void:
|
|
hp = current_hp
|
|
max_hp = current_max_hp
|
|
dead = is_dead
|
|
ratio = clampf(float(hp) / float(max_hp), MIN_FILL_RATIO, MAX_FILL_RATIO) \
|
|
if max_hp > 0 else 0.0
|
|
queue_redraw()
|
|
|
|
func _draw() -> void:
|
|
var r := Rect2(Vector2.ZERO, size)
|
|
# Dark backing and a one-pixel black border keep the bar legible over terrain.
|
|
draw_rect(r, Color(0.02, 0.02, 0.025, 0.86), true)
|
|
var inner := Rect2(Vector2.ONE, Vector2(maxf(0.0, size.x - 2.0), maxf(0.0, size.y - 2.0)))
|
|
var fill_color := Color(0.35, 0.35, 0.38, 0.95) if dead \
|
|
else Color(0.88, 0.14, 0.14, 0.98)
|
|
inner.size.x *= ratio
|
|
if inner.size.x > 0.0:
|
|
draw_rect(inner, fill_color, true)
|
|
draw_rect(r, Color(0.0, 0.0, 0.0, 0.95), false, 1.0)
|