Files
mtgodot-poc/project/screen_hp_bar.gd
T

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)