Creating a hud

Hey!

I am creating hud and i ran to a strange problem.

When i am not looking at entity:

When i look at entity:

As you see, at left down, there is the black circle, then it dissappears when i look at something else than world.
Any ways to fix this?

And how i could draw 10 parts (1 part = 10HP) to that circle like hp?

The code:


Hud = {}
Hud.Colors = {
	Red = Color( 255, 0, 0, 255 ),
	Green = Color( 0, 255, 0, 255 ),
	Blue = Color( 0, 0, 255, 255 ),
	Black = Color( 0, 0, 0, 255 ),
	White = Color( 255, 255, 255, 255 ),
}

Hud.Hide = {
	["CHudHealth"] = true,
	["CHudBattery"] = false,
	["CHudAmmo"] = false,
	["CHudSecondaryAmmo"] = false,
}

function MakeCirclePoly( _x, _y, _r, _points )
    // U is how many times the texture should repeat along the X
    local _u = ( _x + _r * 1 ) - _x;

    // V is how many times the texture should repeat along the Y
    local _v = ( _y + _r * 1 ) - _y;

    local _slices = ( 2 * math.pi ) / _points;
    local _poly = { };
    for i = 0, _points - 1 do
        local _angle = ( _slices * i ) % _points;
        local x = _x + _r * math.cos( _angle );
        local y = _y + _r * math.sin( _angle );
        table.insert( _poly, { x = x, y = y, u = _u, v = _v } )
    end

    return _poly;
end

function drawHud()
	local ply = LocalPlayer()
	local w = ScrW()
	local h = ScrH()
	
	local _poly = MakeCirclePoly( 75, h - 75, 64, 32 );
	surface.SetDrawColor( Hud.Colors.Black );
	surface.DrawPoly( _poly );
	
end

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

function HUDShouldDraw( name )
	if (Hud.Hide[name]) then
		return false;   
	end
end

hook.Add("HUDShouldDraw", "ElementHider", HUDShouldDraw)

--hook.Remove("HUDPaint", "drawHud")
--hook.Remove("HUDShouldDraw", "ElementHider")

You are not setting the texture to draw the poly with. Call draw.NoTexture() before drawing.

Thank you, and how i would draw 10 parts to that circle/radius?

You already made it render a circle. All you need to do now is, on top of that, render a part of a circle matching how much HP the player has.

Actually, AceCool gave me that MakeCirclePoly function. It just would be nice if someone could give me ready code, because i need more math in rendering part or circle and i dont know what is even happening in that function… (I am 13 and i dont know good sin cos tan pi etc.)

[editline]18th February 2015[/editline]

I want something like this:

This is from vgui discussion. I dont take credits for this and anything else not made by me.

You want to learn how to make it or you just want it done?

Well, example would be nice with explanation.

Trigonometry is generally taught in highschool, but if you’re ambitious you can try and learn it early. Here is a great place to get started: http://wiki.garrysmod.com/page/Trigonometry

Best of luck!

Well… I dont want to wait… We are on degrees and thats easy. Example/code would be very nice…

The page he linked has example code.

That tutorial is a good way to learn how to use sine and cosine to draw circles, but if you’re looking for an example here you go:

[lua]

– startang and endang are in degrees.
– radius is the total radius of the outside edge to the center.
function surface.PrecacheArc(cx,cy,radius,thickness,startang,endang,roughness,bClockwise)
local triarc = {}
local deg2rad = math.pi / 180

-- Correct start/end ang
local startang,endang = startang or 0, endang or 0
if bClockwise and (startang < endang) then
	local temp = startang
	startang = endang
	endang = temp
	temp = nil
elseif (startang > endang) then 
	local temp = startang
	startang = endang
	endang = temp
	temp = nil
end


-- Define step
local roughness = math.max(roughness or 1, 1)
local step = roughness
if bClockwise then
	step = math.abs(roughness) * -1
end


-- Create the inner circle's points.
local inner = {}
local r = radius - thickness
for deg=startang, endang, step do
	local rad = deg2rad * deg
	table.insert(inner, {
		x=cx+(math.cos(rad)*r),
		y=cy+(math.sin(rad)*r)
	})
end


-- Create the outer circle's points.
local outer = {}
for deg=startang, endang, step do
	local rad = deg2rad * deg
	table.insert(outer, {
		x=cx+(math.cos(rad)*radius),
		y=cy+(math.sin(rad)*radius)
	})
end


-- Triangulize the points.
for tri=1,#inner*2 do -- twice as many triangles as there are degrees.
	local p1,p2,p3
	p1 = outer[math.floor(tri/2)+1]
	p3 = inner[math.floor((tri+1)/2)+1]
	if tri%2 == 0 then --if the number is even use outer.
		p2 = outer[math.floor((tri+1)/2)]
	else
		p2 = inner[math.floor((tri+1)/2)]
	end

	table.insert(triarc, {p1,p2,p3})
end

-- Return a table of triangles to draw.
return triarc

end

function surface.DrawArc(arc)
for k,v in ipairs(arc) do
surface.DrawPoly(v)
end
end

function draw.Arc(cx,cy,radius,thickness,startang,endang,roughness,color,bClockwise)
surface.SetDrawColor(color)
surface.DrawArc(surface.PrecacheArc(cx,cy,radius,thickness,startang,endang,roughness,bClockwise))
end
[/lua]

And how to use it:
[lua]
hook.Add(“HUDPaint”,“Draw Health semicircle”,function()
local health = LocalPlayer():Health()
local centerX, centerY = 100, 100
local radius = 50
local thickness = 20
local startang = 0
local endang = 180 * health/100
local roughness = 1
–adjust those settings as you choose and watch it change when you reload.
draw.Arc(centerX, centerY, radius, thickness, startang, endang, roughness, false)
end
[/lua]

Wouldn’t it be better on the health config to divide it by the players maxhealth between 100?

Doesnt work :frowning:


Hud = {}
Hud.Colors = {
	Red = Color( 255, 0, 0, 255 ),
	Green = Color( 0, 255, 0, 255 ),
	Blue = Color( 0, 0, 255, 255 ),
	Black = Color( 0, 0, 0, 255 ),
	White = Color( 255, 255, 255, 255 ),
}

Hud.Hide = {
	["CHudHealth"] = true,
	["CHudBattery"] = false,
	["CHudAmmo"] = false,
	["CHudSecondaryAmmo"] = false,
}

function MakeCirclePoly( _x, _y, _r, _points )
    // U is how many times the texture should repeat along the X
    local _u = ( _x + _r * 1 ) - _x;

    // V is how many times the texture should repeat along the Y
    local _v = ( _y + _r * 1 ) - _y;

    local _slices = ( 2 * math.pi ) / _points;
    local _poly = { };
    for i = 0, _points - 1 do
        local _angle = ( _slices * i ) % _points;
        local x = _x + _r * math.cos( _angle );
        local y = _y + _r * math.sin( _angle );
        table.insert( _poly, { x = x, y = y, u = _u, v = _v } )
    end

    return _poly;
end

//START

function surface.PrecacheArc(cx,cy,radius,thickness,startang,endang,roughness,bClockwise)
	local triarc = {}
	local deg2rad = math.pi / 180
	
	-- Correct start/end ang
	local startang,endang = startang or 0, endang or 0
	if bClockwise and (startang < endang) then
		local temp = startang
		startang = endang
		endang = temp
		temp = nil
	elseif (startang > endang) then 
		local temp = startang
		startang = endang
		endang = temp
		temp = nil
	end
	
	
	-- Define step
	local roughness = math.max(roughness or 1, 1)
	local step = roughness
	if bClockwise then
		step = math.abs(roughness) * -1
	end
	
	
	-- Create the inner circle's points.
	local inner = {}
	local r = radius - thickness
	for deg=startang, endang, step do
		local rad = deg2rad * deg
		table.insert(inner, {
			x=cx+(math.cos(rad)*r),
			y=cy+(math.sin(rad)*r)
		})
	end
	
	
	-- Create the outer circle's points.
	local outer = {}
	for deg=startang, endang, step do
		local rad = deg2rad * deg
		table.insert(outer, {
			x=cx+(math.cos(rad)*radius),
			y=cy+(math.sin(rad)*radius)
		})
	end
	
	
	-- Triangulize the points.
	for tri=1,#inner*2 do -- twice as many triangles as there are degrees.
		local p1,p2,p3
		p1 = outer[math.floor(tri/2)+1]
		p3 = inner[math.floor((tri+1)/2)+1]
		if tri%2 == 0 then --if the number is even use outer.
			p2 = outer[math.floor((tri+1)/2)]
		else
			p2 = inner[math.floor((tri+1)/2)]
		end
	
		table.insert(triarc, {p1,p2,p3})
	end
	
	-- Return a table of triangles to draw.
	return triarc
	
end

function surface.DrawArc(arc)
	for k,v in ipairs(arc) do
		surface.DrawPoly(v)
	end
end

function draw.Arc(cx,cy,radius,thickness,startang,endang,roughness,color,bClockwise)
	surface.SetDrawColor(color)
	surface.DrawArc(surface.PrecacheArc(cx,cy,radius,thickness,startang,endang,roughness,bClockwise))
end

//END

function drawHud()
	local ply = LocalPlayer()
	local w = ScrW()
	local h = ScrH()
	
	local _poly = MakeCirclePoly( 75, h - 75, 64, 32 );
	draw.NoTexture()
	
	surface.SetDrawColor( Hud.Colors.Black );
	surface.DrawPoly( _poly );
	
	local health = LocalPlayer():Health()
    local centerX, centerY = 75, h - 75
    local radius = 50
    local thickness = 20
    local startang = 0
    local endang = 180 * health/100
    local roughness = 1
    --adjust those settings as you choose and watch it change when you reload.
    draw.Arc(centerX, centerY, radius, thickness, startang, endang, roughness, Hud.Colors.Green, false)
end

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

function HUDShouldDraw( name )
	if (Hud.Hide[name]) then
		return false;   
	end
end

hook.Add("HUDShouldDraw", "ElementHider", HUDShouldDraw)

--hook.Remove("HUDPaint", "drawHud")
--hook.Remove("HUDShouldDraw", "ElementHider")

My bad. Here:
[lua]
function drawHud()
local ply = LocalPlayer()
local w = ScrW()
local h = ScrH()

local _poly = MakeCirclePoly( 75, h - 75, 64, 32 );
draw.NoTexture()

surface.SetDrawColor( Hud.Colors.Black );
surface.DrawPoly( _poly );

local health = LocalPlayer():Health()
local centerX, centerY = 75, h - 75
local radius = 50
local thickness = 15
local startang = 180
local endang = 360 * health/100
local roughness = 1
--adjust those settings as you choose and watch it change when you reload.
draw.Arc(centerX, centerY, radius, thickness, startang, endang, roughness, Hud.Colors.Green, true)

end

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

I don’t know why, but this:


local health = LocalPlayer():Health()
    local centerX, centerY = 75, h - 75
    local radius = 50
    local thickness = 15
    local startang = -90
    local endang = 360 * health/100
    local roughness = 1
    draw.Arc(centerX, centerY, radius, thickness, startang, endang, roughness, Hud.Colors.Green, true)

Makes 0 hp at 25% circle.

You’ll have to mess with startang and endang to achieve the desired effect. They are clockwise degrees starting at 3 o’clock.

Also, the getmaxhp