• Print

Author Topic: Animated Health Bar  (Read 9976 times)

0 Members and 1 Guest are viewing this topic.

Offline DankNessProvides

  • Newbie
  • *
  • Posts: 26
  • Karma: -3
Animated Health Bar
« on: June 07, 2016, 06:51:03 pm »
I am making a custom HUD and I am quite new to GLua and what I wish to know is how do I make a health bar that will actually slide to the new updated health rather than just jump to it as that looks rather bad and I want to make a nice looking hud.

I would also like somewhere where I can find a basic easy to edit TTT hud can be found or a guide on doing it as I want to start making a HUD for a community for their TTT server already done their DarkRP one.
« Last Edit: June 07, 2016, 07:12:35 pm by DankNessProvides »

Offline MrPresident

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 2727
  • Karma: 430
    • |G4P| Gman4President
Re: Animated Health Bar
« Reply #1 on: June 07, 2016, 07:35:14 pm »
You could use a timer to update the health bar. When the health changes, the timer will update the bar length one unit at a time until it reaches the current health. You'd just have the track the bar value separately from the health value.

I've done something similar to this in a gamemode UI I worked on some time back. It's a neat idea.

Offline DankNessProvides

  • Newbie
  • *
  • Posts: 26
  • Karma: -3
Re: Animated Health Bar
« Reply #2 on: June 08, 2016, 12:43:47 am »
You could use a timer to update the health bar. When the health changes, the timer will update the bar length one unit at a time until it reaches the current health. You'd just have the track the bar value separately from the health value.

I've done something similar to this in a gamemode UI I worked on some time back. It's a neat idea.

Only issue with that is my coding ability extremely bad at coding and decently fast learner :/. All I need is an explanation or a wiki page for it :)
« Last Edit: June 08, 2016, 01:11:31 am by DankNessProvides »

Offline roastchicken

  • Respected Community Member
  • Sr. Member
  • *****
  • Posts: 476
  • Karma: 84
  • I write code
Re: Animated Health Bar
« Reply #3 on: June 08, 2016, 06:10:18 am »
This is a perfect use case for Lerp.

Here's some example code:

Code: Lua
  1. local red = Color( 100, 0, 0 )
  2.  
  3. local curTime = 0
  4.  
  5. local start = 0 -- starting value
  6. local stop = 100 -- ending value
  7. local seconds = 5 -- number of seconds you want it to take
  8.  
  9. local function drawStuff()
  10.   curTime = curTime + RealFrameTime()
  11.  
  12.   local value = Lerp( curTime / seconds, start, stop )
  13.  
  14.   surface.SetDrawColor( red )
  15.   surface.DrawRect( 500, 500, value, 100 )
  16. end
  17.  
  18. hook.Remove( "HUDPaint", "MyHUDPaint" )
  19. hook.Add( "HUDPaint", "MyHUDPaint", drawStuff )

explanation:

Lerp( decimal, start, stop ) gives you the number that is decimal percent away from start, in the direction of stop. For example Lerp( 0.75, 0, 100 ) would return 75 because it's 75 percent away from 0 in the positive direction (towards 100).

Here we're adding RealFrameTime (the time in seconds  it took to render the last frame) to curTime every frame, to keep track of how long the animation has been running for. We then lerp from start to stop by curTime / seconds pecent. Since passing in 1 as the decimal value to lerp will return 100% (aka stop) it would normally stop after the animation had been going on for 1 second, but dividing it by the desired seconds we get an animation that lasts that many seconds.

To implement this in your HUD, just store the old health (the health value from last frame) and lerp from it to the new health every frame.

If you need any more help, feel free to ask. Looking back on my explanation it looks a bit convolution and confusing, but I'm not sure how to make it clearer so it'll just have to do.

Good luck!
Give a man some code and you help him for a day; teach a man to code and you help him for a lifetime.

Offline DankNessProvides

  • Newbie
  • *
  • Posts: 26
  • Karma: -3
Re: Animated Health Bar
« Reply #4 on: June 08, 2016, 02:46:05 pm »
This is a perfect use case for Lerp.

Here's some example code:

Code: Lua
  1. local red = Color( 100, 0, 0 )
  2.  
  3. local curTime = 0
  4.  
  5. local start = 0 -- starting value
  6. local stop = 100 -- ending value
  7. local seconds = 5 -- number of seconds you want it to take
  8.  
  9. local function drawStuff()
  10.   curTime = curTime + RealFrameTime()
  11.  
  12.   local value = Lerp( curTime / seconds, start, stop )
  13.  
  14.   surface.SetDrawColor( red )
  15.   surface.DrawRect( 500, 500, value, 100 )
  16. end
  17.  
  18. hook.Remove( "HUDPaint", "MyHUDPaint" )
  19. hook.Add( "HUDPaint", "MyHUDPaint", drawStuff )

explanation:

Lerp( decimal, start, stop ) gives you the number that is decimal percent away from start, in the direction of stop. For example Lerp( 0.75, 0, 100 ) would return 75 because it's 75 percent away from 0 in the positive direction (towards 100).

Here we're adding RealFrameTime (the time in seconds  it took to render the last frame) to curTime every frame, to keep track of how long the animation has been running for. We then lerp from start to stop by curTime / seconds pecent. Since passing in 1 as the decimal value to lerp will return 100% (aka stop) it would normally stop after the animation had been going on for 1 second, but dividing it by the desired seconds we get an animation that lasts that many seconds.

To implement this in your HUD, just store the old health (the health value from last frame) and lerp from it to the new health every frame.

If you need any more help, feel free to ask. Looking back on my explanation it looks a bit convolution and confusing, but I'm not sure how to make it clearer so it'll just have to do.

Good luck!

Not too clear on how to implement this and the actual explenation is confusing for me as I am new to LUA. I've put it in lined it up and lined it all up with my current health but the issue is it won't slide to the new updated health unless I save the file again then it updates but sometimes bugs out and just jumps between the two.


P.S If anyone has any wiki pages on changing how the info above the head on another player looks like that would be helpful.
« Last Edit: June 08, 2016, 03:14:30 pm by DankNessProvides »

Offline roastchicken

  • Respected Community Member
  • Sr. Member
  • *****
  • Posts: 476
  • Karma: 84
  • I write code
Re: Animated Health Bar
« Reply #5 on: June 08, 2016, 10:02:18 pm »
Not too clear on how to implement this and the actual explenation is confusing for me as I am new to LUA. I've put it in lined it up and lined it all up with my current health but the issue is it won't slide to the new updated health unless I save the file again then it updates but sometimes bugs out and just jumps between the two.

" I've put it in lined it up and lined it all up with my current health" I don't understand what you're trying to say.

Please paste the relevant code (the part that handles drawing the health bar) so I can further diagnose your issue.
Give a man some code and you help him for a day; teach a man to code and you help him for a lifetime.

Offline DankNessProvides

  • Newbie
  • *
  • Posts: 26
  • Karma: -3
Re: Animated Health Bar
« Reply #6 on: June 09, 2016, 05:18:18 am »
Here is the pastebin of my whole code I have 2 health bars in there  one being the jumping one the other being the code you gave me. As far as I am aware they shouldn't effect each other(I think) please alert me to what needs to be changed or removed to make this bar actually update.

Pastebin:
http://pastebin.com/fndgtuif
« Last Edit: June 09, 2016, 08:17:51 am by DankNessProvides »

Offline roastchicken

  • Respected Community Member
  • Sr. Member
  • *****
  • Posts: 476
  • Karma: 84
  • I write code
Re: Animated Health Bar
« Reply #7 on: June 10, 2016, 12:53:25 am »
A few things:

lines 3-7:
Code: Lua
  1.   client = LocalPlayer()
  2.   DrawHealth = LocalPlayer():Health()
  3.   DrawArmor = LocalPlayer():Armor()
  4.   EchoHealth = LocalPlayer():Health()
  5.   EchoArmor = LocalPlayer():Armor()

You set a (global!) variable client to LocalPlayer(), and then never use it.
You have two separate values for LocalPlayer():Health() and LocalPlayer:Armor(). Why do you need two variables to store the exact same value?

lines 9 - 13:
Code: Lua
  1.   if DrawArmor < 0 then DrawArmor = 0 end
  2.   if DrawArmor > 100 then DrawArmor = 100 end
  3.  
  4.   if DrawHealth < 0 then DrawHealth = 0 end
  5.   if DrawHealth > 100 then DrawHealth = 100 end

math.Clamp

lines 48-62:
Code: Lua
  1.   local red = Color( 100, 0, 0 )
  2.   local curTime = 0
  3.  
  4.   local stop = 380 -- ending value
  5.   local seconds = 5 -- number of seconds you want it to take
  6.  
  7.   local function drawStuff()
  8.     curTime = curTime + RealFrameTime()
  9.    
  10.     value = Lerp( curTime / seconds, start, stop )
  11.    
  12.     surface.SetDrawColor( red )
  13.     surface.DrawRect( 20, ScrH() - 85, value, 28 )
  14.   end

Your variable 'red' is a constant, no need to define it every time the HUD is drawn. Move it outside of the Base function.

You're setting curTime to 0 every time the HUD is drawn. Your health bar will just stay at a few pixels because each frame you're resetting it. Move curTime outside of the Base function.

Your variables 'start', 'stop', and 'seconds', are all constant. Move them outside of the Base function.

You're missing the start variable. If you don't have it, you (should) get an error. Define start to be some number (you probably want it to be 0).

Of course, when you run your code you don't get an error, because: you're never running the code within drawStuff. If you define a function but never run it, nothing will happen. Remove the function syntax and just put the code directly in Base.

value should be local.

After all these changes, we get:

Code: Lua
  1. local red = Color( 100, 0, 0 )
  2.  
  3. local curTime = 0
  4.  
  5. local start = 0 -- starting value
  6. local stop = 380 -- ending value
  7. local seconds = 5 -- number of seconds you want it to take
  8.  
  9. function Base()
  10.  
  11.   -- rest of HUD
  12.  
  13.   curTime = curTime + RealFrameTime()
  14.  
  15.   local value = Lerp( curTime / seconds, start, stop )
  16.  
  17.   surface.SetDrawColor( red )
  18.   surface.DrawRect( 20, ScrH() - 85, value, 28 )
  19. end

Now, this is still not going to do what you want it to do. In my first post I said:

To implement this in your HUD, just store the old health (the health value from last frame) and lerp from it to the new health every frame."

You're just lerping from 0 to 380, and you're only doing it once. You need to:

  • Store the health from the previous frame
  • Check if the health has changed
  • Lerp from the old health to the new health (only if the health has changed)

Good luck!
« Last Edit: June 10, 2016, 12:55:24 am by roastchicken »
Give a man some code and you help him for a day; teach a man to code and you help him for a lifetime.

Offline DankNessProvides

  • Newbie
  • *
  • Posts: 26
  • Karma: -3
Re: Animated Health Bar
« Reply #8 on: June 16, 2016, 11:29:00 am »
A few things:

lines 3-7:
Code: Lua
  1.   client = LocalPlayer()
  2.   DrawHealth = LocalPlayer():Health()
  3.   DrawArmor = LocalPlayer():Armor()
  4.   EchoHealth = LocalPlayer():Health()
  5.   EchoArmor = LocalPlayer():Armor()

You set a (global!) variable client to LocalPlayer(), and then never use it.
You have two separate values for LocalPlayer():Health() and LocalPlayer:Armor(). Why do you need two variables to store the exact same value?

lines 9 - 13:
Code: Lua
  1.   if DrawArmor < 0 then DrawArmor = 0 end
  2.   if DrawArmor > 100 then DrawArmor = 100 end
  3.  
  4.   if DrawHealth < 0 then DrawHealth = 0 end
  5.   if DrawHealth > 100 then DrawHealth = 100 end

math.Clamp

lines 48-62:
Code: Lua
  1.   local red = Color( 100, 0, 0 )
  2.   local curTime = 0
  3.  
  4.   local stop = 380 -- ending value
  5.   local seconds = 5 -- number of seconds you want it to take
  6.  
  7.   local function drawStuff()
  8.     curTime = curTime + RealFrameTime()
  9.    
  10.     value = Lerp( curTime / seconds, start, stop )
  11.    
  12.     surface.SetDrawColor( red )
  13.     surface.DrawRect( 20, ScrH() - 85, value, 28 )
  14.   end

Your variable 'red' is a constant, no need to define it every time the HUD is drawn. Move it outside of the Base function.

You're setting curTime to 0 every time the HUD is drawn. Your health bar will just stay at a few pixels because each frame you're resetting it. Move curTime outside of the Base function.

Your variables 'start', 'stop', and 'seconds', are all constant. Move them outside of the Base function.

You're missing the start variable. If you don't have it, you (should) get an error. Define start to be some number (you probably want it to be 0).

Of course, when you run your code you don't get an error, because: you're never running the code within drawStuff. If you define a function but never run it, nothing will happen. Remove the function syntax and just put the code directly in Base.

value should be local.

After all these changes, we get:

Code: Lua
  1. local red = Color( 100, 0, 0 )
  2.  
  3. local curTime = 0
  4.  
  5. local start = 0 -- starting value
  6. local stop = 380 -- ending value
  7. local seconds = 5 -- number of seconds you want it to take
  8.  
  9. function Base()
  10.  
  11.   -- rest of HUD
  12.  
  13.   curTime = curTime + RealFrameTime()
  14.  
  15.   local value = Lerp( curTime / seconds, start, stop )
  16.  
  17.   surface.SetDrawColor( red )
  18.   surface.DrawRect( 20, ScrH() - 85, value, 28 )
  19. end

Now, this is still not going to do what you want it to do. In my first post I said:

You're just lerping from 0 to 380, and you're only doing it once. You need to:

  • Store the health from the previous frame
  • Check if the health has changed
  • Lerp from the old health to the new health (only if the health has changed)

Good luck!

I changed the code to what you said and now all I am stuck on is how do I actually do the bottom steps as I have no idea how to check previous health. I did say I was a complete noob at Lua/GLua
« Last Edit: June 16, 2016, 11:52:50 am by DankNessProvides »

Offline MrPresident

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 2727
  • Karma: 430
    • |G4P| Gman4President
Re: Animated Health Bar
« Reply #9 on: June 16, 2016, 12:24:03 pm »
It sounds like you're wanting someone to write this for you, in which case you should seek that kind of help up front.

Many people around here are more than willing to point you in the right direction with functions and wiki links, but when you just come back and say, "I don't know how to do that" or "I've added the code you posted, now what?"... that's not really helping yourself.

Offline DankNessProvides

  • Newbie
  • *
  • Posts: 26
  • Karma: -3
Re: Animated Health Bar
« Reply #10 on: June 16, 2016, 12:40:40 pm »
It sounds like you're wanting someone to write this for you, in which case you should seek that kind of help up front.

Many people around here are more than willing to point you in the right direction with functions and wiki links, but when you just come back and say, "I don't know how to do that" or "I've added the code you posted, now what?"... that's not really helping yourself.

I've never been that upfront dude and I am open to wiki links that will help ME do it but if someone will write it and explain what it does so I could possibly use it in other situations, I would be happier than if someone just wrote it for me telling me nothing about it. I would prefer what roastchicken has done with how he did it and explained what it did. :)
« Last Edit: June 17, 2016, 11:43:28 am by DankNessProvides »

Offline roastchicken

  • Respected Community Member
  • Sr. Member
  • *****
  • Posts: 476
  • Karma: 84
  • I write code
Re: Animated Health Bar
« Reply #11 on: June 18, 2016, 03:44:44 am »
Sorry for not replying sooner, I was busy with a few things.

Anyways, I laid out the steps for you:

1. Store the health from the previous frame

Think about how you could do this. Obviously you can't go back in time to the previous frame and get the health value then, so you're going to need to store the health for each frame and then make sure you can access it in the next frame. I'll leave you to figure out how to do that.

2. Check if the health has changed

Pretty straight-forward. Hint: it involves if statements and comparison operators.

3. Lerp from the old health to the new health (only if the health has changed)

This is where the code I gave you a few posts above comes in.

Here are a few helpful links if you're still stuck:

if statements
local variables and blocks
relational operators
Give a man some code and you help him for a day; teach a man to code and you help him for a lifetime.

  • Print