I managed to implement this, but it's rather hacky and I would really love a better way. In any event, I'll post what I've done. Maybe others can suggest how to improve it.
I created a
ColorRect attribute for my player called
var damage_block = ColorRect.new()
health_bar.add_child(damage_block) # add to health_bar
damage_block.color = Color('#CFB53B') # set color
damage_block.rect_size = Vector2(0, 6) # set initial size
When my player takes damage, I add the damage value to a variable called
damage_queue is greater than 0, I resize
damage_block and position it within the health bar at the appropriate position. Then, I use a
Timer to decrement the Player's
damage_queue simultaneously. Because resizing and positioning is done every frame, as
damage_queue decrements, so does the size of the
damage_block and the player's health.
To position the damage block correctly, I first calculate how many pixels it takes to represent one HP. I call this
pixels_per_hp. This is just the size of the health bar divided by max health.
The width of the damage block is just
damage_queue * pixels_per_hp.
To position the
damage_block, I first find the width of the player's actual health within the health bar. This is just
health * pixels_per_hp. Then I subtract the width of the
damage_block. (I also add 1 pixel since there is a 1 pixel border around my health bar.)
damage_queue is 0, I set the width of
damage_block back to 0 so that it is no longer visible.
if damage_queue > 0:
# get number of pixels that represent 1 HP
var pixels_per_hp = health_bar.rect_size.x / float(max_health)
# create damage block of appropriate size
damage_block.rect_size = Vector2(damage_queue * pixels_per_hp), 6)
# position damage block inside health bar
damage_block.rect_global_position = health_bar.rect_global_position + Vector2(0,1) + Vector2(health * pixels_per_hp, 0) - Vector2(damage_block.rect_size.x, 0)
if damage_queue == 0 or health <= 0:
damage_block.rect_size.x = 0
I find this implementation rather clumsy, but it works as a first pass. One of the problems is that you can see a slight jitter on the left of the
damage_block, probably relating to the fractions and floating point values in the calculations.
If anyone can suggest improvements or another implementation altogether, that would be swell!