Page 1 of 1

Customisable Horizontal Bar Creator

PostPosted: Mon Oct 22, 2012 3:17 am
by GEuser
Hi there all.

Just wanted to share this Global Code for creating Horizontal Bars.


Basic Information


You can customise the size, change colors of border, background and bar. You don't need any images because its uses the canvass actor with all the draw functions. Once you've added the global code you can update the hBar anywhere from your other events (i.e. when HP changes for enemies or players, or whatever...) or create additional canvass actor for more bars (or even use clones). Any way here's all the info. Hope you guy's find it useful :)

Image


The Global Code

Code: Select all
void hBar (int barValue, int barMax, int barHeight, int border_R, int border_G, int border_B, int back_R, int back_G, int back_B, int fill_R, int fill_G, int fill_B)
{

    int bar_i=0;

    // Check valid bar values
    if (barValue <0)
    {
            barValue=0; // if value negative set to 0
    }
    else
    {
        if (barValue>barMax)
        {
            barValue=barMax; // if value larger then barMax set to barMax
        }
    }

   // Clear old display
    erase(0,0,0,1);

// --------------------  Create Background ----------------------

    setpen(back_R, back_G, back_B, 0.0, 1);
    moveto(0, 0);

    for(bar_i = 0; bar_i < barMax+2; bar_i++)
    {
        moveto(bar_i, 0);
        lineto (bar_i, barHeight);
    }

// -------------------- Create Border ---------------------------

    setpen(border_R, border_G, border_B, 0.0, 1);
    moveto (0, 0);
    lineto (barMax+1, 0);
    lineto (barMax+1, barHeight);
    lineto (0, barHeight);
    lineto (0, 0);

// -------------------- Create Value Bar ------------------------------

    setpen(fill_R, fill_G, fill_B, 0.0, 1);
    moveto(1, 1);
 
    for(bar_i = 1; bar_i < barValue+1; bar_i++)
    {
        moveto (bar_i, 1);
        lineto (bar_i, barHeight-1);
 
    }
 
}


Use Instructions

Image
Image
Image

I suppose you could add more fancy images over these (or use Draw From function) to create more stylish looking bars. I decided to keep things simple for now thou.

Re: Customisable Horizontal Bar Creator

PostPosted: Mon Oct 22, 2012 3:26 am
by SuperSonic
That's very nice. +1 for you good sir :wink:

Re: Customisable Horizontal Bar Creator

PostPosted: Mon Oct 22, 2012 4:18 am
by master0500
something similar was made by Hblade
viewtopic.php?f=4&t=11361&p=79626

Re: Customisable Horizontal Bar Creator

PostPosted: Mon Oct 22, 2012 1:18 pm
by SuperSonic
Yeah, I've made one too (I didn't post mine). It's fun to make health bars :D

Re: Customisable Horizontal Bar Creator

PostPosted: Wed Oct 24, 2012 4:51 pm
by GEuser
Thanks for the +1 super.

I called it a Horizontal bar because I want it to be more than just a health bar. That's okay for a simple shoot'em up. For a more busy shoot'em up you might want an ammo or shield bar as well. For example, you could create a ship with 3 bars attached to it (ammo, shield, health). Do it as follows:-

Step 1. Copy and paste the hBar global code into Global Editor and save it as hBar (as shown in original post).

Step 2. Create 3 canvas actors. Name them ammoBar, sheildBar, healthBar.
(that's: Add actor => type in settings: Name=ammo, Type=canvas => [add] Repeat for other two).

Step 3. Create an actor variable named itsValue.
(that's: Script => Global Code -> [variables] => [add] => type setting as: Name=itsValue, Type=integer, Scope=Actor variable => [add] )

IMPORTANT. Learn to be efficient (comes with practice). Why create 3 additonal actor variables like ammo, sheild and health if you
can get way with just 1 variable and access it's value with ammoBar.itsValue or sheildBar.itsValue or healthBar.itsValue. An additional bonus for doing it this way is that you can use it for all other actors that allow it (anyActor.itsValue), makes life easier, hey?

To set startup state for each bar you would but some code in the canvas actors CREATE ACTOR EVENT (for ammo, sheild and health).

Step 4a. Startup Location. You would obviously want to set your bars position so that they follow your ship as it moves around the screen. So you have to set up the x, y position of each canvas actor (ammo, sheild and health) relative to you player ship Actor (whatever you called it, I call it playerShip for convenience).

Code: Select all
// Your in CREATE ACTOR EVENT (of Health Bar canvas actor) 
x=playerShip.x - healthBar.width/2;   // roughly across middle of playerShip NOT WHAT YOU WANT!
y=playerShip.y - healthBar.height/2;  // roughly down middle of playerShip NOT WHAT YOU WANT!

The problem with the above positioning code is that it places your bar smack in the middle of your player ship. It's good for finding the centre of your ship but you would ideally want to put the bar either above or below your ship. Like the code below (examples given for above, below, left & right of player ship).
Code: Select all
// THIS CODE WOULD GO IN YOUR CANVAS ACTOR'S CREATE EVENT.
// For this positioning to work as intended make sure you resize the canvas as close as possible to dimensions of your bar.

// Place bar CENTRED ABOVE player ship
x=playerShip.x + playerShip.width/2 - healthBar.width/2;
y=playerShip.y - playerShip.height/2 - healthBar.height/2 - offSet; // you would enter offset manually to fine tune positioning

// ALTERNATIVELY Place bar CENTRED BELOW player ship
x=playerShip.x + playerShip.width/2 - healthBar.width/2;
y=playerShip.y + playerShip.height/2 - healthBar.height/2 + offSet; // you would enter offset manually to fine tune positioning

// ALTERNATIVELY Place bar  CENTRED LEFT of player ship
x=playerShip.x - playerShip.width/2 - healthBar.width/2 - offSet; // you would enter offset manually to fine tune positioning
y=playerShip.y + playerShip.height/2 - healthBar.height/2;

// ALTERNATIVELY Place bar CENTRED RIGHT of player ship
x=playerShip.x + playerShip.width/2 + healthBar.width/2 + offSet; // you would enter offset manually to fine tune positioning
y=playerShip.y + playerShip.height/2 - healthBar.height/2;



Step 4b. Display bar. Just add the hBar( your preferences ); code with your design preference in the ( ) brackets part. Example code for placing your bar centred below your player ship:-

Code: Select all
// Place bar CENTRED BELOW player ship
x=playerShip.x + playerShip.width/2 - healthBar.width/2;
y=playerShip.y + playerShip.height/2 - healthBar.height/2 + offSet; // you would enter offset manually to fine tune positioning

// create and display the bar
hbar (50, 50, 5, 0, 255, 0, 128, 128, 128, 0, 255, 0);


Obviously you would repeat this for each of the 3 bars (ammo, shield, health).

Step 5. Working Bar. To actually see the bar move when your ammo, shelld or health changes you would need to change the itsValue variable associated with it but this is not enough you would have to do 2 things.

5a) Change itsValue for ammo, sheild or health as follows:

THIS CODE WOULD GO WHERE EVER THE CHANGE TAKES PLACE IN YOUR GAME
(by using canvases actorName.itsValue you can manipulate ammo, sheilds & health from outside of the canvas code parts, that 's to say, where ever your dealing with changes when enemy strikes a hit, you reload ammo, you get a PowerUp, etc...).

Code: Select all
//ammo reloaded
ammoBar.itsValue += AmountReloadedBy; // AmountReloadedBy whatever it is

//ammo depleted
ammoBar.itsValue -=AmountDepletedBy; // AmountDepletedBy whatever it is

//You get a rare drop from enemy kill (PowerUp is Sheilds)
shieldBar.itsValue += ByPowerUpDropSize; // ByPowerUpDropSize whatever it is

//Enemy strikes a hit at Sheilds
shieldBar.itsValue -= ByEnemyDamageAmount; // ByEnemyDamageAmount whatever it is

//You get a rare drop from enemy kill (PowerUp is Health)
healthBar.itsValue += ByPowerUpDropSize; // ByPowerUpDropSize whatever it is

//Enemy strikes a hit
healthBar.itsValue -= ByEnemyDamageAmount; // ByEnemyDamageAmount whatever it is



5b) Dispay the changes in the bar.. In the DRAW ACTOR EVENT of your bar (ammo, sheild, health) add the following code:

Code: Select all
// In DRAW ACTOR EVENT of ammo bar (the canvas actor)
hbar (ammoBar.itsValue, 50, 5, 0, 255, 0, 128, 128, 128, 0, 255, 0);

// In DRAW ACTOR EVENT of sheild bar (the canvas actor)
hbar (sheildBar.itsValue, 50, 5, 0, 255, 0, 128, 128, 128, 0, 255, 0);

// In DRAW ACTOR EVENT of health bar (the canvas actor)
hbar (healthBar.itsValue, 50, 5, 0, 255, 0, 128, 128, 128, 0, 255, 0);


Hope that helps people with bar positioning and use.

On a different topic altogether, user input. You could use the hBar as an input slider by putting code in its MOUSE DOWN EVENT. Say if xmouse value is left of bar centre (when mouse clicked) decrease barValue or if xmouse is right of bar centre increase barValue. You'd have a very simple way of setting game preferences (e.g. initial game resources: ammo, fuel, etc... difficulty level, easy to hard, so on ... Alternatively, just use left/right mouse clicks on bar to set the value.

Will be creating more gui widgets. Done the Vertical Bar (vBar) version so will add that tonight later...Running out of time, sorry for any typos, in a rush, got more to add...got to go :lol:

Take care all!

Re: Customisable Horizontal Bar Creator

PostPosted: Thu Oct 25, 2012 6:39 pm
by Hblade
good stuff :) +1

Re: Customisable Horizontal Bar Creator

PostPosted: Fri Oct 26, 2012 12:42 am
by GEuser
Thanks Hblade. Using ubuntu for gE but sometimes it's a bit unstable get all sorts of issues but I read that you tried on MINT (7.0?) wonder if you could use structs and audio stuff easily? Hate the new ubuntu stuff needs too much upgrades in hardware :(

P.S.Despite all the occasional niggle, gE is a fantastic thing (so thanks gE dev team, don't mean to whine too much :lol: :)

Re: Customisable Horizontal Bar Creator

PostPosted: Fri Jan 18, 2013 4:37 am
by Soullem
for some reason this code doesn't work when eCHP (enemy current health) is less than eMHP (enemy max health).
Code: Select all
if (eMHP !=0)
{
if (eCHP>=eMHP/2)
{
    hBar(ceil((eCHP/eMHP)*224), 224, 16, 0, 0, 0, 0, 0, 0, 30, 200, 30);
}
}

this should mean that the fill is whatever percentage of 224(the max) the CHP is of the MHP.
And its driving me crazy! though its probably really obvious.

Re: Customisable Horizontal Bar Creator

PostPosted: Fri Jan 18, 2013 11:49 pm
by GEuser
Soullem wrote:for some reason this code doesn't work when eCHP (enemy current health) is less than eMHP (enemy max health).
Code: Select all
if (eMHP !=0)
{
if (eCHP>=eMHP/2)
{
    hBar(ceil((eCHP/eMHP)*224), 224, 16, 0, 0, 0, 0, 0, 0, 30, 200, 30);
}
}

this should mean that the fill is whatever percentage of 224(the max) the CHP is of the MHP.
And its driving me crazy! though its probably really obvious.


Hi Soullem. There are two issues causing your problem

1. Trying to use integers to generate a decimal fraction output (0.5, 0.25, etc...)

The proble with this part of the code ...

Code: Select all
(ceil((eCHP/eMHP)*224)


... is that it's working with integers that get rounded off to whole numbers. So you'll never generate the 0.25, 0.5 or whatever the expected result is supposed to be. You have to use double (real values) to get that percentage output that you want. This will example will work:-

Code: Select all
double eMHP=224.0;
double eCHP=110.0;
int tempVal=0; // a temporary value (hBar needs integer for barValue parameter).

tempVal=ceil((eCHP/eMHP)*224);


2. Bad nesting of if() statments.
Nesting the if() statements the way you have done is bad programming, avoid it. Use the && (AND) operators instead to link conditions up, like this:-
Code: Select all
if ((eMHP!=0)&&(eCHP>=eMHP/2))
{
    hBar(tempVal, 224, 16, 0, 0, 0, 0, 0, 0, 30, 200, 30);
}

I am assuming you want the hp bar display only when the enemies current health is half or above its maximum allowed? If your code had worked as it is, you'd display the bar only if eCHP was hal/equal to half of eMHP otherwise no bar iwould be displayed. If this is what you wanted then the solution would be to make eMHP and eCHP into double variables and use the code:-

Code: Select all
int tempVal=0;

tempVal=ceil((eCHP/eMHP)*224); // eCHP & eMHP are doubles

if ((eMHP!=0)&&(eCHP>=eMHP/2))
{
    hBar(tempVal, 224, 16, 0, 0, 0, 0, 0, 0, 30, 200, 30);
}

Good practice to avoid putting calculations directly into the function (hBar). Use temporary variable (tempVal) to hold the calculation and put the temporary variable (tempVal) in the function (hBar). Of course, it's entirely upto you what style you use. If you want the code to do something else when eCHP is less than halfway of it's max health allowed use this code:-
Code: Select all
int tempVal=0;

tempVal=ceil((eCHP/eMHP)*224);

if ((eMHP!=0) && (eCHP>=eMHP/2)) // eCHP equal to and more than half of eMHP.
{
    hBar(tempVal, 224, 16, 0, 0, 0, 0, 0, 0, 30, 200, 30);
}
else
{
    // eCHP less than half of eMHP, so do something else.
}


Hope this helps and thanks for using my function :)

p.s. if for some reason the above doesn't work try making the tempVal a double as well but there shouldn't be any need for this.


Logic Operators

&& AND operator
, when 2 or more conditions MUST be met.
|| OR operator, when 1 or more conditions are met.

there are others search gE wiki

Re: Customisable Horizontal Bar Creator

PostPosted: Sat Jan 19, 2013 2:26 am
by Soullem
I know about nesting, the thing is that I want to change the color of the bar when it gets to halfway. So all I have to do is make the variables into reals instead of integers and do the equation separately, it seems pretty easy. Thanks I didn't know that reals wont make decimal values.

Re: Customisable Horizontal Bar Creator

PostPosted: Sat Jan 19, 2013 9:51 pm
by GEuser
Soullem wrote:I know about nesting, the thing is that I want to change the color of the bar when it gets to halfway. So all I have to do is make the variables into reals instead of integers and do the equation separately, it seems pretty easy. Thanks I didn't know that reals wont make decimal values.


Ahh, that clears up things a bit. You want a color change at a specific percentage. That makes things a bit more complicated.. You can't really do that without making some major changes to the hBar function. What I've done is added 4 more parameters to an updated version called hBar2. This will accept 2 fill colors (fill_R, fill_G, fill_B) and (fill_R2, fill_G2, fill_B2) with last parameter called barPercent( a real value: 0.5, 0.25, etc...).

When your barValue is below barPercent of barMax, fill color 2 is used. All you have to do now is just call hBar2 with all the relevant bits. The hBar2 will do all the work for you. No need for extra code and you can use whatever percentage value you need for the color change.

NOTE: eCHP & eMHP can be kept as integers now (no need for them to be doubles, only the hPercent is a double)

hBar2 Global code

Code: Select all
void hBar2 (int barValue, int barMax, int barHeight, int border_R, int border_G, int border_B, int back_R, int back_G, int back_B, int fill_R, int fill_G, int fill_B, int fill_R2, int fill_G2, int fill_B2, double barPercent)
{

    int bar_i=0;

    // use first fill color as default 
    int useFill_r=fill_R;
    int useFill_g=fill_B;
    int useFill_b=fill_G;


    // Check valid bar values
    if (barValue <0)
    {
            barValue=0; // if value negative set to 0
    }
    else
    {
        if (barValue>barMax)
        {
            barValue=barMax; // if value larger then barMax set to barMax
        }
    }



    // check if valid percentage ( >0 to 1 )
    if ((barPercent>0)&&(barPercent<=1))
    {
           // Check if color change needed
          if(barValue>=ceil(barMax*barPercent))
          {
                 useFill_r=fill_R;
                 useFill_g=fill_G;
                 useFill_b=fill_B;
          }
          else
          {
                 useFill_r=fill_R2;
                 useFill_g=fill_G2;
                 useFill_b=fill_B2;
          }
    }


   // Clear old display
    erase(0,0,0,1);

// --------------------  Create Background ----------------------

    setpen(back_R, back_G, back_B, 0.0, 1);
    moveto(0, 0);

    for(bar_i = 0; bar_i < barMax+2; bar_i++)
    {
        moveto(bar_i, 0);
        lineto (bar_i, barHeight);
    }

// -------------------- Create Border ---------------------------

    setpen(border_R, border_G, border_B, 0.0, 1);
    moveto (0, 0);
    lineto (barMax+1, 0);
    lineto (barMax+1, barHeight);
    lineto (0, barHeight);
    lineto (0, 0);

// -------------------- Create Value Bar ------------------------------

    setpen(useFill_r, useFill_g, useFill_b, 0.0, 1);
    moveto(1, 1);
 
    for(bar_i = 1; bar_i < barValue+1; bar_i++)
    {
        moveto (bar_i, 1);
        lineto (bar_i, barHeight-1);
 
    }
 
}


Example

For a bright red color change (255,0,0) when eCHP is below 50% (0.5) of eMHP use the following code:-

Code: Select all
hBar2(eCHP, eMHP, 16, 0, 0, 0, 0, 0, 0, 30, 200, 30, 255, 0, 0, 0.5);


Test Code
Here's a code snippet (for canvass actor) that you can use to experiment with:-

Code: Select all
// Enemy Maximum  HP
int eMHP=224;

// Enemy Current  HP
int eCHP=112;


// default Color (equal to / above hPercent)
int Fill_r=30;
int Fill_g=200;
int Fill_b=30;

// Color2 for when below hPercent
int Fill_r2=255;
int Fill_g2=0;
int Fill_b2=0;

// change to color2 when below hPercent (here 50%) of enemy Max 2
double hPercent=0.5;

hBar2(eCHP, eMHP, 16, 0, 0, 0, 0, 0, 0, Fill_r, Fill_g, Fill_b, Fill_r2, Fill_g2, Fill_b2, hPercent);


Hope this solves your problem?

Re: Customisable Horizontal Bar Creator

PostPosted: Sun Jan 20, 2013 3:18 am
by Soullem
Thanks, I figured it out now.