Jump to content

Smooth moving health bar


JeViCo

Recommended Posts

local dx_healt = getElementHealth(localPlayer)
local healt = getElementHealth(localPlayer)

function setHealth(_type,_value)
	if _value >= 5 then			
		if _type == "add" then
			dx_healt = dx_healt + 5
		else
			dx_healt = dx_healt - 5
		end
		setTimer(function()
			setHealth(_type,_value-5)
		end,500,1)
	elseif _value > 0 then
		if _type == "add" then
			dx_healt = dx_healt + _value
		else
			dx_healt = dx_healt - _value
		end
	end
end

function healthChecker()
	if getElementHealth(localPlayer) < healt then
		setHealth("add",healt-getElementHealth(localPlayer))
	elseif  getElementHealth(localPlayer) > healt then
		setHealth("loss",getElementHealth(localPlayer)-healt)
	end	
	setTimer(function()
		healthChecker()
	end,500,1)
end

addEventHandler("onClientResourceStart",resourceRoot,function()
	healthChecker()
end)

Now you can use dx_health variable to draw the animated health for your bar... I used recursive timer instead of "onClientPlayerDamege" because you can detect if the player get an HP and animate the bar filling up... you can change the animation speed and rate by change the Timer milisecond value and the "dx_healt = dx_healt + 5" or "dx_healt = dx_healt - 5" number parameter...
Otherway, you should think about what if the player get other damage, while the animation still in progress...
Code not tested, maybe you need to correct it...

Edited by Awang
Link to comment

setTimer is not a good way to do it, it's different if you are using the default hud or your own. Best way to do it is using increments (maybe decimals) in the onClientRender event that changes the health to what it's suppose to be but using a slow motion, animation like movement.

Link to comment

It's some sort of a pseudo code, but it should give you an idea.. As @Shayf said, setTimer doesn't really go well with animations, it will be slow and clunky.

local inRenderHealth = 0
local renderStart = getTickCount()

function drawHealth()
  
  local playerHealth = Math.ceil ( getElementHealth ( localPlayer ) )
  
  if(inRenderHealth ~= playerHealth )
    renderStart = getTickCount()
  end
  
  local now = getTickCount()
  local endTime = renderStart + 500
  local elapsedTime = now - renderStart
  local duration = endTime - renderStart
  local progress = elapsedTime / duration
  local inRenderHealth, _, _ = interpolateBetween ( inRenderHealth, 0, 0, playerHealth, 0, 0, progress, "Linear")
  
  dxDrawRectangle ( 0, 0, inRenderHealth * 4, 20 )
end

 

Edited by pa3ck
  • Like 1
Link to comment
styles = {}
styles['progressBar'] = {
	['default'] = {
		bgColor = tocolor(0,0,0,180),
		barColor = tocolor(255,255,255,200),
		textColor = tocolor(255,0,0,255)
	}
}

local sx,sy = guiGetScreenSize()
local sw,sh = 1360,768-- Change this to your resolution and use absolute values when creating elements.
local draw = {}
local validTypes = {'progressBar'}

function dxRect(...)
	arg[1],arg[2],arg[3],arg[4] = arg[1]/sw*sx,arg[2]/sh*sy,arg[3]/sw*sx,arg[4]/sh*sy
	return dxDrawRectangle(unpack(arg))
end

function dxText(...)
	arg[2],arg[3],arg[4],arg[5],arg[7] = arg[2]/sw*sx,arg[3]/sh*sy,(arg[4]+arg[2])/sw*sx,(arg[5]+arg[3])/sh*sy,(arg[7] or 1)/sw*sx
	return dxDrawText(unpack(arg))
end

function dx(type,theme,x,y,w,h,visible)
	for i=1,#validTypes do
		if type == validTypes[i] then
			local self = {}
			self.type = type
			self.x = x or 0
			self.y = y or 0
			self.w = w or 0
			self.h = h or 0
			self.style = styles[self.type][theme] or styles[self.type]['default'] 
			self.visible = visible or true
			
			self.destroy = function()
				for i=1,#draw do
					if draw[i] == self then
						table.remove(draw,i)
					end
				end
			end
			
			return self
		end
	end
	return false
end

function dxCreateProgressBar(text,x,y,w,h)
	local self = dx('progressBar','default',x,y,w,h,true)
	if self then
		self.progress = 0
		
		local pbText = text
		self.draw = function()
			dxRect(self.x,self.y,self.w,self.h,self.style.bgColor)
			if string.find(pbText,'%progress%',1,true) then pbText = string.gsub(pbText,'%progress%',tostring(math.floor(self.progress))..'%') end
			dxText(pbText,self.x,self.y,self.w,self.h,self.style.textColor)
			dxRect(self.x,self.y,(self.w/100)*self.progress,self.h,self.style.barColor)
		end
		
		table.insert(draw,self)
		return self
	end
end

addEventHandler('onClientRender',root,function()
	for i=1,#draw do
		if draw[i].visible then
			draw[i].draw()
		end
	end
end)

local progressBar = dxCreateProgressBar('Health %progress%',500,500,600,200)-- create a progress bar like this
setTimer(function()
	local health = getPlayerHealth(localPlayer)-- if its 100 then use it, if its 200 then divide it by 2
	if health > 100 then
		health = health/2
	end
	progressBar.progress = health -- then set the progress
end,50,0)
-- you can also set colors like this
progressBar.style.barColor = tocolor(255,0,0,200)
progressBar.style.bgColor = tocolor(255,255,255,160)

This is a bit of code from my dx library, maybe it'll help ya.

Edited by ShayF
Link to comment
18 hours ago, ShayF said:

styles = {}
styles['progressBar'] = {
	['default'] = {
		bgColor = tocolor(0,0,0,180),
		barColor = tocolor(255,255,255,200),
		textColor = tocolor(255,0,0,255)
	}
}

local sx,sy = guiGetScreenSize()
local sw,sh = 1360,768-- Change this to your resolution and use absolute values when creating elements.
local draw = {}
local validTypes = {'progressBar'}

function dxRect(...)
	arg[1],arg[2],arg[3],arg[4] = arg[1]/sw*sx,arg[2]/sh*sy,arg[3]/sw*sx,arg[4]/sh*sy
	return dxDrawRectangle(unpack(arg))
end

function dxText(...)
	arg[2],arg[3],arg[4],arg[5],arg[7] = arg[2]/sw*sx,arg[3]/sh*sy,(arg[4]+arg[2])/sw*sx,(arg[5]+arg[3])/sh*sy,(arg[7] or 1)/sw*sx
	return dxDrawText(unpack(arg))
end

function dx(type,theme,x,y,w,h,visible)
	for i=1,#validTypes do
		if type == validTypes[i] then
			local self = {}
			self.type = type
			self.x = x or 0
			self.y = y or 0
			self.w = w or 0
			self.h = h or 0
			self.style = styles[self.type][theme] or styles[self.type]['default'] 
			self.visible = visible or true
			
			self.destroy = function()
				for i=1,#draw do
					if draw[i] == self then
						table.remove(draw,i)
					end
				end
			end
			
			return self
		end
	end
	return false
end

function dxCreateProgressBar(text,x,y,w,h)
	local self = dx('progressBar','default',x,y,w,h,true)
	if self then
		self.progress = 0
		
		local pbText = text
		self.draw = function()
			dxRect(self.x,self.y,self.w,self.h,self.style.bgColor)
			if string.find(pbText,'%progress%',1,true) then pbText = string.gsub(pbText,'%progress%',tostring(math.floor(self.progress))..'%') end
			dxText(pbText,self.x,self.y,self.w,self.h,self.style.textColor)
			dxRect(self.x,self.y,(self.w/100)*self.progress,self.h,self.style.barColor)
		end
		
		table.insert(draw,self)
		return self
	end
end

addEventHandler('onClientRender',root,function()
	for i=1,#draw do
		if draw[i].visible then
			draw[i].draw()
		end
	end
end)

local progressBar = dxCreateProgressBar('Health %progress%',500,500,600,200)-- create a progress bar like this
setTimer(function()
	local health = getPlayerHealth(localPlayer)-- if its 100 then use it, if its 200 then divide it by 2
	if health > 100 then
		health = health/2
	end
	progressBar.progress = health -- then set the progress
end,50,0)
-- you can also set colors like this
progressBar.style.barColor = tocolor(255,0,0,200)
progressBar.style.bgColor = tocolor(255,255,255,160)

This is a bit of code from my dx library, maybe it'll help ya.

Doesn't work( It is a progress bar instead now with(

Link to comment
On 2/2/2018 at 08:18, JeViCo said:

Doesn't work( It is a progress bar instead now with(

Yes, you set the progress bar progress to the players health, like I showed.. of course it doesn't have borders around it, but you can add borders in the self.draw function.

  • Thanks 1
Link to comment
15 hours ago, ShayF said:

Yes, you set the progress bar progress to the players health, like I showed.. of course it doesn't have borders around it, but you can add borders in the self.draw function.

Not work

Is getPlayerHealth or getElementHealth ? Update your code. No work

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...