-
Notifications
You must be signed in to change notification settings - Fork 0
/
healthbar.py
114 lines (65 loc) · 3.02 KB
/
healthbar.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from panda3d.core import NodePath, CardMaker, Vec4
from direct.task import Task
from direct.showbase.DirectObject import DirectObject
class HealthBar(DirectObject):
def __init__(
self, parent=None, max_health=100, height=0.025, position=(-2, 0, 1 - 0.025)
): # Positioned at the top
self.max_health = max_health
self.current_health = max_health
self.height = height
self.position = position
self.colors = [
Vec4(1, 0, 0, 0.5),
Vec4(1, 0.5, 0, 0.5),
Vec4(1, 1, 0, 0.5),
Vec4(0, 1, 0, 0.5),
Vec4(0, 0, 1, 0.5),
Vec4(0.3, 0, 0.5, 0.5),
Vec4(0.5, 0, 1, 0.5),
]
self.current_color_index = 0
self.root = NodePath("HealthBar")
self.root.reparent_to(parent if parent else base.aspect2d)
# Background bar (oversized full width for dynamic stretch)
self.bg_bar = self.create_bar(Vec4(0.2, 0.2, 0.2, 1), 4, height)
self.bg_bar.reparent_to(self.root)
self.bg_bar.set_pos(*position)
# Foreground bar (health-based width)
self.fg_bar = self.create_bar(Vec4(0, 1, 0, 1), 4, height)
self.fg_bar.reparent_to(self.root)
self.fg_bar.set_pos(*position)
# Update the health bar color based on the current health
self.update_health(self.current_health)
# Start cycling colors periodically based on task or health change
taskMgr.add(self.cycle_colors, "CycleColors")
def create_bar(self, color, width, height):
cm = CardMaker("Bar")
cm.set_frame(0, width, 0, height)
bar = NodePath(cm.generate())
bar.set_color(color)
bar.set_scale(1, 1, 1)
return bar
def update_health(self, new_health):
"""Update the health and adjust bar size and color accordingly."""
self.current_health = max(0, min(self.max_health, new_health))
health_ratio = self.current_health / self.max_health
# Update foreground bar scale (width)
new_width = 4 * health_ratio # Shrink the foreground bar horizontally
self.fg_bar.set_scale(new_width, 1, 1)
# Change color based on health ratio (red for low health, green for full)
if health_ratio <= 0.2:
self.fg_bar.set_color(Vec4(1, 0, 0, 0.5)) # Red for low health
elif health_ratio <= 0.5:
self.fg_bar.set_color(Vec4(1, 1, 0, 0.5)) # Yellow for mid-health
else:
self.fg_bar.set_color(Vec4(0, 1, 0, 0.5)) # Green for high health
# Adjust position (optional, based on your UI layout)
self.fg_bar.set_pos(
self.position[0] + (4 - new_width), self.position[1], self.position[2]
) # Align left
def cycle_colors(self, task):
"""Optional color cycling effect (periodic updates)."""
self.current_color_index = (self.current_color_index + 1) % len(self.colors)
self.fg_bar.set_color(self.colors[self.current_color_index])
return Task.cont