Help regarding healthbar with drawPoly

As the title suggests, I was wanting help with a drawPoly healthbar, I have it working and everything thanks to a friend, but the one main thing is depending on the resolution, the poly actually extends further out then the background bar, as you can see here.

http://puu.sh/9gHM1/2d8cdfb516.jpg

Depending on the resolution it fixes, on 1280x720 resolution it does this, 1360 x 768 it fixes
Currently I have this for the actual bar itself



local smoothHealth = 0
local smoothPercent = 0
local width = tbl2[1]["x"] -tbl2[2]["x"]
function HUDPaint()
	smoothHealth = math.Approach( smoothHealth, LocalPlayer():Health(), FrameTime() *25 )
	
	local w = ( smoothHealth /100 ) *width
	local health = math.Clamp(LocalPlayer():Health(), 0, 100)
	smoothPercent = math.Approach( smoothPercent, health/100 *100, 25*FrameTime() )
	
	tbl2[1]["x"] = w > 7 and w + 35 or 7
	tbl2[4]["x"] = w  
end

local tex = surface.GetTextureID( "vgui/white" )
local tbl = { {}, {}, {}, {} }
tbl[1]["x"] = ScrW() / 4 + 60
tbl[1]["y"] = ScrH() - 4
tbl[2]["x"] = ScrW() / 4 - 335
tbl[2]["y"] = ScrH() - 4
tbl[3]["x"] = ScrW() / 4 - 335
tbl[3]["y"] = ScrH() - 44
tbl[4]["x"] = ScrW() / 4 + 20
tbl[4]["y"] = ScrH() - 44
 
local tex2 = surface.GetTextureID( "vgui/white" )
local tbl2 = { {}, {}, {}, {} }
tbl2[1]["x"] = ScrW() / 4 + 25
tbl2[1]["y"] = ScrH() - 6
tbl2[2]["x"] = ScrW() / 4 - 333
tbl2[2]["y"] = ScrH() - 6
tbl2[3]["x"] = ScrW() / 4 - 333
tbl2[3]["y"] = ScrH() - 42
tbl2[4]["x"] = ScrW() / 4 - 10
tbl2[4]["y"] = ScrH() - 42

Here are the tables, table 1 being the black bar behind, and table 2 being the red bar inside.


Use modifiers… Here are a few tutorials for using a modifier for different screen scales, and tilted poly health-bar… You should simplify your logic in a similar fashion:

https://dl.dropboxusercontent.com/u/26074909/tutoring/vgui/understanding_hardcoding_of_screensizes.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/poly/tilted_rectangle_poly_as_health_meter.lua.html

remove the .html to see the .lua - things align better in the .lua.

In your example, you’d only need a +tilt to one of the two points ( top right ), and enter a - number, or just subtract a positive number using -tilt in the function.

My question is though, is there a easier way I could do it with what I already have? Because I don’t entirely wanna rework the entire thing.

Sure, but the way you have it now, you’re hard-coding all of the positions. It’d make things easier if you used a poly-function to generate the poly based on x y w h and tilt because you can then target w and h and make it scale properly with screen.

What is the ENTIRE snippet of code you’re trying to fix?



surface.CreateFont( "HealthFont", {
        font    = "Coolvetica",
        size    = 34,
        weight  = 400
} )
 
local tex = surface.GetTextureID( "vgui/white" )
local tbl = { {}, {}, {}, {} }
tbl[1]["x"] = ScrW() / 4 + 60
tbl[1]["y"] = ScrH() - 4
tbl[2]["x"] = ScrW() / 4 - 335
tbl[2]["y"] = ScrH() - 4
tbl[3]["x"] = ScrW() / 4 - 335
tbl[3]["y"] = ScrH() - 44
tbl[4]["x"] = ScrW() / 4 + 20
tbl[4]["y"] = ScrH() - 44
 
local tex2 = surface.GetTextureID( "vgui/white" )
local tbl2 = { {}, {}, {}, {} }
tbl2[1]["x"] = ScrW() / 4 + 25
tbl2[1]["y"] = ScrH() - 6
tbl2[2]["x"] = ScrW() / 4 - 333
tbl2[2]["y"] = ScrH() - 6
tbl2[3]["x"] = ScrW() / 4 - 333
tbl2[3]["y"] = ScrH() - 42
tbl2[4]["x"] = ScrW() / 4 - 10
tbl2[4]["y"] = ScrH() - 42

local tex3 = surface.GetTextureID( "vgui/white" )
local tbl3 = { {}, {}, {}, {} }
tbl3[1]["x"] = ScrW() / 4 + 61
tbl3[1]["y"] = ScrH() - 3
tbl3[2]["x"] = ScrW() / 4 - 336
tbl3[2]["y"] = ScrH() - 3
tbl3[3]["x"] = ScrW() / 4 - 336
tbl3[3]["y"] = ScrH() - 45
tbl3[4]["x"] = ScrW() / 4 + 20
tbl3[4]["y"] = ScrH() - 45

local tex4 = surface.GetTextureID( "vgui/white" )
local tbl4 = { {}, {}, {}, {} }
tbl4[1]["x"] = ScrW() / 2 + 49
tbl4[1]["y"] = 45
tbl4[2]["x"] = ScrW() / 2 - 49
tbl4[2]["y"] = 45
tbl4[3]["x"] = ScrW() / 2 - 100
tbl4[3]["y"] = - 5
tbl4[4]["x"] = ScrW() / 2 + 100
tbl4[4]["y"] = - 5

local tex5 = surface.GetTextureID( "vgui/white" )
local tbl5 = { {}, {}, {}, {} }
tbl5[1]["x"] = ScrW() / 2 + 49
tbl5[1]["y"] = 44
tbl5[2]["x"] = ScrW() / 2 - 49
tbl5[2]["y"] = 44
tbl5[3]["x"] = ScrW() / 2 - 99
tbl5[3]["y"] = - 5
tbl5[4]["x"] = ScrW() / 2 + 99
tbl5[4]["y"] = - 5


local smoothHealth = 0
local smoothPercent = 0
local width = tbl2[1]["x"] -tbl2[2]["x"]
local function HUDPaint()

	smoothHealth = math.Approach( smoothHealth, LocalPlayer():Health(), FrameTime() *25 )
	
	local w = ( smoothHealth /100 ) *width
	local health = math.Clamp(LocalPlayer():Health(), 0, 100)
	smoothPercent = math.Approach( smoothPercent, health/100 *100, 25*FrameTime() )
	
	if LocalPlayer():GetObserverMode() == OBS_MODE_NONE then
	tbl2[1]["x"] = w > 7 and w + 35 or 7
	tbl2[4]["x"] = w  

	surface.SetTexture( tex )
	surface.SetTexture( tex2 )
	surface.SetDrawColor( 255, 255, 255, 40 )
	surface.DrawPoly( tbl3 )
	surface.SetDrawColor( 40, 40, 40, 240 )
	surface.DrawPoly( tbl )
	surface.SetDrawColor( 255, 0, 0, 255 )
	surface.DrawPoly( tbl2 )
	draw.SimpleText(math.Round( smoothPercent ) .. "%", "HealthFont", 10, ScrH() - 40, Color(255, 255, 255), 0, 0)
	end
	surface.SetDrawColor( 255, 255, 255, 40 )
	surface.DrawPoly( tbl4 )
	surface.SetDrawColor( 40, 40, 40, 240 )
	surface.DrawPoly( tbl5)
	draw.AAText( string.ToMinutesSeconds(GAMEMODE:GetRoundTime()), "HealthFont", ScrW() / 2 - 0, 0, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
	draw.SimpleText( "Rounds:", "default", ScrW() / 2 - 21, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
	draw.AAText( tostring(GetGlobalInt("dr_rounds_left")), "default", ScrW() / 2 + 7, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
	draw.SimpleText( "of 15.", "default", ScrW() / 2 + 30, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )

	
end
hook.Add("HUDPaint", "HUDPaint", HUDPaint)


A majority of that is for the timer and whatnot, I’m just trying to fix the health bar.

Here:

[lua]local tex4 = surface.GetTextureID( “vgui/white” )
local tbl4 = { {}, {}, {}, {} }
tbl4[1][“x”] = ScrW() / 2 + 49
tbl4[1][“y”] = 45
tbl4[2][“x”] = ScrW() / 2 - 49
tbl4[2][“y”] = 45
tbl4[3][“x”] = ScrW() / 2 - 100
tbl4[3][“y”] = - 5
tbl4[4][“x”] = ScrW() / 2 + 100
tbl4[4][“y”] = - 5

local tex5 = surface.GetTextureID( “vgui/white” )
local tbl5 = { {}, {}, {}, {} }
tbl5[1][“x”] = ScrW() / 2 + 49
tbl5[1][“y”] = 44
tbl5[2][“x”] = ScrW() / 2 - 49
tbl5[2][“y”] = 44
tbl5[3][“x”] = ScrW() / 2 - 99
tbl5[3][“y”] = - 5
tbl5[4][“x”] = ScrW() / 2 + 99
tbl5[4][“y”] = - 5

//
// Simple Rectangle Poly function with easier x, y, w, and h - Josh ‘Acecool’ Moser
//
function MakeRectPoly( _x, _y, _w, _h, _tilt )
// The creation of the Poly without texture support
local _poly = {
{ x = ( _x ), y = _y, u = 0, v = 0 }, // Top Left
{ x = ( _x + _w - _tilt ), y = _y, u = 0, v = 0 }, // Top Right
{ x = ( _x + _w ), y = ( _y + _h ), u = 0, v = 0 }, // Bottom Right
{ x = _x, y = ( _y + _h ), u = 0, v = 0 }, // Bottom Left
};

return _poly;

end

local _hpBarBG = MakeRectPoly( 0, ScrH( ) - 45, 382, 42, 42 );
local _hpBar = MakeRectPoly( 0, ScrH( ) - 45, 382, 42, 42 );

local smoothHealth = 0
local smoothPercent = 0
local width = tbl2[1][“x”] -tbl2[2][“x”]
local function HUDPaint()

smoothHealth = math.Approach( smoothHealth, LocalPlayer():Health(), FrameTime() *25 )

local w = ( smoothHealth /100 ) *width
local health = math.Clamp(LocalPlayer():Health(), 0, 100)
smoothPercent = math.Approach( smoothPercent, health/100 *100, 25*FrameTime() )

// Regenerate size only until at 100
if ( smoothPercent < 100 ) then
	_hpBar = MakeRectPoly( 0, ScrH( ) - 45, 382 * smoothPercent / 100, 42, 42 );
end

if LocalPlayer():GetObserverMode() == OBS_MODE_NONE then
	-- tbl2[1]["x"] = w > 7 and w + 35 or 7 -- not needed
	-- tbl2[4]["x"] = w -- not needed

	-- surface.SetTexture( tex ) -- not needed
	surface.SetTexture( tex2 )
	surface.SetDrawColor( 255, 255, 255, 40 )
	surface.DrawPoly( _hpBarBG )
	surface.SetDrawColor( 40, 40, 40, 240 )
	surface.DrawPoly( _hpBarBG )
	surface.SetDrawColor( 255, 0, 0, 255 )
	surface.DrawPoly( _hpBar )
	draw.SimpleText(math.Round( smoothPercent ) .. "%", "HealthFont", 10, ScrH() - 40, Color(255, 255, 255), 0, 0)
end

surface.SetDrawColor( 255, 255, 255, 40 )
surface.DrawPoly( tbl4 )
surface.SetDrawColor( 40, 40, 40, 240 )
surface.DrawPoly( tbl5)
draw.AAText( string.ToMinutesSeconds(GAMEMODE:GetRoundTime()), "HealthFont", ScrW() / 2 - 0, 0, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
draw.SimpleText( "Rounds:", "default", ScrW() / 2 - 21, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
draw.AAText( tostring(GetGlobalInt("dr_rounds_left")), "default", ScrW() / 2 + 7, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
draw.SimpleText( "of 15.", "default", ScrW() / 2 + 30, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )

end
hook.Add(“HUDPaint”, “HUDPaint”, HUDPaint)[/lua]

That “fixes” it… I’m running on the resolution that you said had the problem…

I replaced the tables using my function; the arguments are simply x, y, w, h, tilt – You may want to set them up differently, but it simplifies things.

Not sure what the other bars were for, I didn’t see them.

Edit: The tabs should line up when pasted; not sure why facepunch treats spaces/tabs differently.

Edit, I forgot, you wanted a 2pixel border around the red bar showing.

Just update these parts:
[lua]local _hpBarBG = MakeRectPoly( 0, ScrH( ) - 45, 382, 42, 42 );
local _hpBar = MakeRectPoly( 0, ScrH( ) - 42, 377, 38, 38 );

// Regenerate size only until at 100
--if ( smoothPercent < 100 ) then // Update this - smoothPercent isn't on 0-100 scale, fix it so it stops reproducing tables
	_hpBar = MakeRectPoly( 0, ScrH( ) - 43, 377 * smoothPercent / 100, 38, 38 );
--end

[/lua]

Edit: I also didn’t use the example of modifiers for you… Basically, hard-code the width you want on your screen. Use the tutorial I posted to create a modifier for W and H, then use those multipliers in the arguments…

[lua]local _hpBarBG = MakeRectPoly( 0, ScrH( ) - 45, 382 * WIDTH_MOD, 42 * HEIGHT_MOD, 42 * HEIGHT_MOD );
local _hpBar = MakeRectPoly( 0, ScrH( ) - 42, 377 * WIDTH_MOD, 38 * HEIGHT_MOD, 38 * HEIGHT_MOD );[/lua]

Use height-mod on the tilt too, if you want an even 45 degree tilt, then the tilt needs to be the same as the height.

It seems whenever I use what you posted, it messes with the deathrun scoreboard giving this error



[ERROR] gamemodes/deathrun/gamemode/cl_scoreboard.lua:18: attempt to call method 'GetScoreboardIcon' (a nil value)
  1. CreatePlayer - gamemodes/deathrun/gamemode/cl_scoreboard.lua:18
   2. Refresh - gamemodes/deathrun/gamemode/cl_scoreboard.lua:170
    3. CreateScoreboard - gamemodes/deathrun/gamemode/cl_scoreboard.lua:197
     4. unknown - gamemodes/deathrun/gamemode/cl_scoreboard.lua:236


It also seems to give an error on this line

local width = tbl2[1][“x”] -tbl2[2][“x”]



[ERROR] gamemodes/deathrun/gamemode/cl_init.lua:136: attempt to index global 'tbl2' (a nil value)
  1. unknown - gamemodes/deathrun/gamemode/cl_init.lua:136


I removed the tbls associated with the health bar, and health bar background. Two of them were identical… Ah, it still uses width for the calculation in percent… Just use the width from the argument for that variable…

Which argument am I looking for for “width”? I can’t seem to find it or w/e

local width = tbl2[1][“x”] -tbl2[2][“x”]
local function HUDPaint()

should be

local width = 382 // * WIDTH_MOD if you use the width mod tutorial.
local function HUDPaint()

I meant what am I looking to change it to, as I don’t see where you actually have the health bar being drawn and stuff

>> At this very moment, i’m just using what you just posted.

[editline]6th June 2014[/editline]

I’ll take a further look into doing all this soon as right now, i’m quite busy, If I need anymore help i’ll let you know, and I appreciate the help you’ve given me sofar

Here, this one works as is… I don’t like the idea of tex1-x since they’re the same here, but you may be using something else so I left them…

[lua]
local tex1 = surface.GetTextureID( “vgui/white” )
local tex2 = surface.GetTextureID( “vgui/white” )
local tex3 = surface.GetTextureID( “vgui/white” )
local tex4 = surface.GetTextureID( “vgui/white” )
local tbl4 = { {}, {}, {}, {} }
tbl4[1][“x”] = ScrW() / 2 + 49
tbl4[1][“y”] = 45
tbl4[2][“x”] = ScrW() / 2 - 49
tbl4[2][“y”] = 45
tbl4[3][“x”] = ScrW() / 2 - 100
tbl4[3][“y”] = - 5
tbl4[4][“x”] = ScrW() / 2 + 100
tbl4[4][“y”] = - 5

local tex5 = surface.GetTextureID( “vgui/white” )
local tbl5 = { {}, {}, {}, {} }
tbl5[1][“x”] = ScrW() / 2 + 49
tbl5[1][“y”] = 44
tbl5[2][“x”] = ScrW() / 2 - 49
tbl5[2][“y”] = 44
tbl5[3][“x”] = ScrW() / 2 - 99
tbl5[3][“y”] = - 5
tbl5[4][“x”] = ScrW() / 2 + 99
tbl5[4][“y”] = - 5

//
// Simple Rectangle Poly function with easier x, y, w, and h - Josh ‘Acecool’ Moser
//
function MakeRectPoly( _x, _y, _w, _h, _tilt )
// The creation of the Poly without texture support
local _poly = {
{ x = ( _x ), y = _y, u = 0, v = 0 }, // Top Left
{ x = ( _x + _w - _tilt ), y = _y, u = 0, v = 0 }, // Top Right
{ x = ( _x + _w ), y = ( _y + _h ), u = 0, v = 0 }, // Bottom Right
{ x = _x, y = ( _y + _h ), u = 0, v = 0 }, // Bottom Left
};

return _poly;

end

local _x = 0;
local _y = ScrH( ) - 45;
local _w = 382;
local _h = 42;
local _hpBarBG = MakeRectPoly( _x, _y, _w, _h, _h );
local _hpBar = nil; – regenerate it for smoothing //MakeRectPoly( _x, _y + 2, _w - 5, _h - 4, _h - 4 );

local smoothHealth = 0
local smoothPercent = 0
local smoothedFully = false;
– local width = tbl2[1][“x”] -tbl2[2][“x”]
local function HUDPaint()

smoothHealth = math.Approach( smoothHealth, LocalPlayer():Health(), FrameTime() *25 )

local w = ( smoothHealth /100 ) * _w
local health = math.Clamp(LocalPlayer():Health(), 0, 100)
smoothPercent = math.Approach( smoothPercent, health/100 *100, 25*FrameTime() )

// Needs to be regenerated for smoothing...
_hpBar = MakeRectPoly( _x, _y + 2, ( _w - 5 ) * smoothPercent / 100, _h - 4, _h - 4 );

if LocalPlayer():GetObserverMode() == OBS_MODE_NONE then
	-- tbl2[1]["x"] = w > 7 and w + 35 or 7 -- not needed
	-- tbl2[4]["x"] = w -- not needed

	-- surface.SetTexture( tex ) -- not needed
	surface.SetTexture( tex2 )
	surface.SetDrawColor( 255, 255, 255, 40 )
	surface.DrawPoly( _hpBarBG )
	surface.SetDrawColor( 40, 40, 40, 240 )
	surface.DrawPoly( _hpBarBG )
	surface.SetDrawColor( 255, 0, 0, 255 )
	surface.DrawPoly( _hpBar )
	draw.SimpleText(math.Round( smoothPercent ) .. "%", "HealthFont", 10, ScrH() - 40, Color(255, 255, 255), 0, 0)
end

surface.SetDrawColor( 255, 255, 255, 40 )
surface.DrawPoly( tbl4 )
surface.SetDrawColor( 40, 40, 40, 240 )
surface.DrawPoly( tbl5)
draw.AAText( string.ToMinutesSeconds(GAMEMODE:GetRoundTime()), "HealthFont", ScrW() / 2 - 0, 0, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
draw.SimpleText( "Rounds:", "default", ScrW() / 2 - 21, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
draw.AAText( tostring(GetGlobalInt("dr_rounds_left")), "default", ScrW() / 2 + 7, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
draw.SimpleText( "of 15.", "default", ScrW() / 2 + 30, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )

end
hook.Add(“HUDPaint”, “HUDPaint”, HUDPaint)[/lua]

It seems to fix it, very much appreciated, one more thing if you don’t mind, the part that you commented out
(




	-- surface.SetDrawColor( 255, 255, 255, 40 )
	-- surface.DrawPoly( tbl4 )
	-- surface.SetDrawColor( 40, 40, 40, 240 )
	-- surface.DrawPoly( tbl5)
	-- draw.AAText( string.ToMinutesSeconds(GAMEMODE:GetRoundTime()), "HealthFont", ScrW() / 2 - 0, 0, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
	-- draw.SimpleText( "Rounds:", "default", ScrW() / 2 - 21, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
	-- draw.AAText( tostring(GetGlobalInt("dr_rounds_left")), "default", ScrW() / 2 + 7, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )
	-- draw.SimpleText( "of 15.", "default", ScrW() / 2 + 30, 29, Color( 255, 255, 255 ), TEXT_ALIGN_CENTER )


)

It seems to work, but whenever it first loads or whatever, it seems to flash a couple times, any ideas why this is?

I uncommented it; I had it commented because I wasn’t running it on TTT.

No idea why it flashes; it essentially acts identically to what you had with a more predictable ( or easily read ) width for the 3 polys.

Can you show a video? I didn’t see it flash on my end…

I can get you a video soon, whenever I say take out the comments or whatever, it flashes for JUST a second or two.

If you auto-refresh then it will “flash”. This is because it reloads the file and it resets the variables of where it was meaning it needs to start from 0% health, and move up to where it is; after auto-refresh process is done there should be no hiccups.

I mean the background for the timer itself, it seems to flashes, is that because of what you said?

I didn’t change the timer part; only the health-bar and health-bar background. A video would help…

Alright, give me one quick minute while I finish up what i’m doing.

EDIT:

It tends to flash like you said, just flash for a couple of seconds and then it seems to be fine afterwards, is this what you said about 3 posts up? Or no?