• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Ring Health Bar Help?

B

Better Nature

Guest
TLDR: I'm looking for a method of creating a "ring" or "circle" health-bar that doesn't use any of the draw_[shape] commands (which are apparently somewhat broken according to the below linked thread)

A lot of the UI in my current game project is designed around a "ring" or "circle" health-bar. I found what I thought was a really good method of achieving the effect I was looking for in this tutorial by r2d2upgrade. The problem is, it uses the draw_triangle_color command, and I recently found out in this thread that the draw_line and draw_[shape] commands are not recommended due to inconsistencies in how they are rendered by different hardware (At first it seemed like it's just the draw_line function, but the ultimate consensus of the thread seems to be that all of them won't function consistently. Let me know if I'm misunderstanding though).

My usual method of creating hp bars using image_xscale won't work here. The only alternative I've come up with is creating a sprite with enough frames to cover every level of HP. As you can imagine, this is far from ideal. if your HP is over 100, that's 100+ frames taking up resources for one hp bar(not to mention the time involved in creating all those frames). I'm really hoping to find another solution.

So that's my question to you, does anyone have any ideas for a better method of creating a health-ring? Or, are there any suggestions of where I might look for ideas?

If it makes any difference, I'm currently working in Studio 1.4, but plan on porting over to Studio 2 soon.

Thanks for taking the time to read my question (even the tldr), and double thanks if you share any suggestions!
 

Bingdom

Googledom
You could use a quadrant of a circle, then add new quadrants as it goes along. This will allow smooth movement with little processing power.
 
B

Better Nature

Guest
ajan-ko: I thought about that, but there's nowhere to hide the smallest portion of the pie when the hp is lower than its size allows. If I made it small enough to be a single unit of health, then I get back to the issue of drawing a ton of images in a really inefficient way. Let me know if I'm misunderstanding you.

Bingdom: Could you elaborate? I think what you're suggesting is more or less what I'm doing right now (I'm drawing pieces of a ring using triangles based on a percentage). I'm trying to avoid any of the draw_shape functions due to their rendering issues though. Did you mean drawing a sprite?

Another thing I should probably mention is that I'm working with pixel art. This means that I can't just create one little piece of a circle and then repeat it over and over until a full circle is created. Unlike with higher resolutions, each segment of a circle is not identical in pixel art. At minimum I'd have to create various sprites for 1/4th of the circle that I could then flip horizontally and vertically to create the rest of the circle. Maybe that's the solution, but it still feels really inefficient for something that's on the screen 99% of the time.

Thanks for your help so far!



Also, sorry to the mods for posting links in my first post (Somehow i missed the giant text at the top of the screen telling me I'm not supposed to do that), and thanks for allowing the thread to go up in spite of that.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
vis-circular-healthbar.gmk
vis-circular-healthbar.png
Code:
/// draw_rectangle_cd_tex(x1, y1, x2, y2, value, texture)
var v, x1, y1, x2, y2, xm, ym, vd, vx, vy, vl;
v = argument4
if (v <= 0) return 0 // nothing to be drawn
x1 = argument0; y1 = argument1; // top-left corner
x2 = argument2; y2 = argument3; // bottom-right corner
if (v >= 1) return draw_rectangle(x1, y1, x2, y2, false) // entirely filled
xm = (x1 + x2) / 2; ym = (y1 + y2) / 2; // middle point
draw_primitive_begin_texture(pr_trianglefan, argument5)
draw_vertex_texture(xm, ym, 0.5, 0.5); draw_vertex_texture(xm, y1, 0.5, 0)
// draw corners:
if (v >= 0.125) draw_vertex_texture(x2, y1, 1, 0)
if (v >= 0.375) draw_vertex_texture(x2, y2, 1, 1)
if (v >= 0.625) draw_vertex_texture(x1, y2, 0, 1)
if (v >= 0.875) draw_vertex_texture(x1, y1, 0, 0)
// calculate angle & vector from value:
vd = pi * (v * 2 - 0.5)
vx = cos(vd)
vy = sin(vd)
// normalize the vector, so it hits -1\+1 at either side:
vl = max(abs(vx), abs(vy))
if (vl < 1) {
    vx /= vl
    vy /= vl
}
draw_vertex_texture(xm + vx * (x2 - x1) / 2, ym + vy * (y2 - y1) / 2, 0.5 + vx * 0.5, 0.5 + vy * 0.5)
draw_primitive_end()
You give the function a sprite_get_texture of the circular healthbar' sprite, the function draws it diagonally in 2..4 triangles. I think it's the most efficient it gets.
I'm meaning to make a separate blog post about this (so that it can be found via search), but the general idea is the same as with circular cooldown rectangle.
 

Genetix

Member
Draw out the ring sprite itself - and each frame. Ideally you should use 100 frames, but you could get away with 50, 20, etc... What you will do is represent the percentage of HP that is left - so for example if your ring has 100 frames, each frame would represent 1% of the max hp. This will work even if maxhp is greater then 100.

image_index = round((hp/maxhp)*100)

So we set the image_index of the ring to a rounded number between 1-100 (or rewrite to 0-99 to fit your frames correctly....) - that number is the percentage of hp.

Example: round((50/200)*100) = 25 - so here if your maxhp = 200 and current hp = 50, we set the image index of the ring to reflect you have 25% of your maxhp. The *100 would change depending on how many frames you have for the ring. You could get away with only having 20 frames, but each one would represent 5% whereas 100 frames would would have each represent 1% which is bit more detailed.

Hopefully that isn't way to confusing.
 
B

Better Nature

Guest
Yellow Afterlife: Thanks a lot! This seems like it might be exactly what I'm looking for. I'll have to dive a bit deeper with it to be sure.

Genetix: No, it's not too confusing. This is basically what I came up with after I found out that I couldn't use r2d2upgrades method (linked in my first post). I really want to avoid a 100 frame sprite if at all possible though. Thanks for posting the idea.
 
Z

zendraw

Guest
genetix, ive had the idea for a sprite with meny images for a healthbar, but that have an impact on performence?
 
Top