The WhoopA Network

Two Pic, Two File HP Bar and Numeric Readout
Devised by WhoopA / Dan Sandstrom
Contact: whoopa@whoopanetwork.com

--- Introduction

RM2k action games. Not common, but not unheard of either. As creative as you are, you still have to find some way of informing the player of how much damage they can sustain before they die... and you'd better put it right on the screen so they don't have to enter the menu every 5 seconds.

There's two standard ways of doing this - the direct HP readout (think Secret of Mana) and the HP percentage bar (Castlevania comes to mind). Some games use both (Dark Cloud anyone?). I'll delve into how to do both.

--- Conventions

Here's the standard conventions I use in my tutorials.

  • Numbers prefaced by "V[" or "Var[" are variables. Those without (prefaced by "S[" or "[") are switches.
  • A line of script in an event begins with <>.
  • Lines of script are edited for readability. Comments to the code are in parenthesis.

--- Direct HP Readout

First I'll tackle the Direct HP display. It's more straightforward than a percentage, and can even be converted to a numeric percentage if you wish.

--- Image setup

For this type of readout, you'll need to create 10 images for the numbers. I'd recommend anywhere from 8x16 to 16x32 pels for the images - they can be any size, really, but just remember how wide and how tall your images are. And don't make them so large they completely obscure the screen - people don't like that. The images themselves don't need to be fancy, just understandable as the numbers 0 through 9. Save them and import them into your RM2k pictures folder.

For the script, I'll refer to the saved images as "Num0" through "Num9".

--- Variable and switch setup

Surprisingly enough, this display can be done with only three variables (RM2k caps player HP at 999. You'll need more if you have a CBS with higher limits.). However, I'm going to use four. It'll help cut out some lag with a constantly running parallel process - they tend to do that.

  • V[0001]: Player's HP Last
  • V[0002]: Player's HP 100s
  • V[0003]: Player's HP 10s
  • V[0004]: Player's HP 1s

--- The script

Ahh, the glory of Common Events. They can be run from any map, so there's no unneccesary copying of events... That's right, I'm going to use a Common Event - Parallel Process. Go ahead and have it activate by a switch. We don't need to run it on every map, only those that are combat-related. Unless you're doing a Zelda-like game. Then feel free to have it run all the time.

You ready? Let's begin.

<> Set Variable: V[0002]-V[0004], Set to Hero's HP

Get the HP of the hero. Keep in mind this is a "Set to Range". It'll help when we split the variables later. As for the HP value itself, we just take it right from the Database - if you're using a more complex system, take it from whatever variable holds the current HP amount.

<> Fork: If V[0001], V[0002] Are Not Equal

Compare the last value of the HP to the current. We only need to update the HP display if it's been changed - this helps IMMENSELY with any and all lag-killing.

<>   Set Variable: V[0001], Set to V[0002]

Copy over the current HP to the last marked value. We won't need to run the code in the fork again until the HP changes. And since we're doing some mathwork on V[0002], we need to copy it over before we change it.

<>   Set Variable: V[0002], Divide by 100
<>   Set Variable: V[0003], Divide by 10
<>   Set Variable: V[0003], Mod by 10
<>   Set Variable: V[0004], Mod by 10

A variable splitter - yeah, like you didn't expect one. When we assigned the HP to variables above, we assigned it to all three of our HP variables at once. For those unclear on the function of Mod (short for Modulus), it divides by the amount given and returns the remainder. So, if the HP was 134 and we performed Mod by 10 on it, the result would be 4. Still unclear? Don't worry. It'll come to you eventually.

And now the ugly. We have to show the pictures. It eventually comes down to 10 nested forks for each digit. More tedious than necessary, but whadayagonnado. It's a bit easier with events, but since we're using pictures...

We also need to figure out where the pictures are going to be. Divide the width of the number images by 2 to get the starting X position, and divide the height by 2 to get the Y. Then add these to the upper-left X and Y position on the screen for the image placement. Remember, the screen is 320x240 pels. A good position for the pictures is 8 pels from the upper-left corner.

I'll use X and Y in the script for the position.

<>   Fork: If V[0002] Is Equal To 1
<>     Show Picture: ID 1, Pic Num1 at (X,Y)
<>   Else
<>     Fork: If V[0002] Is Equal To 2
<>       Show Picture: ID 1, Pic Num2 at (X,Y)
<>     Else
<>       Fork: If V[0002] Is Equal To 3
<>         Show Picture: ID 1, Pic Num3 at (X,Y)
<>       Else
<>         Fork: If V[0002] Is Equal To 4
<>           Show Picture: ID 1, Pic Num4 at (X,Y)
<>         Else
<>           Fork: If V[0002] Is Equal To 5
<>             Show Picture: ID 1, Pic Num5 at (X,Y)
<>           Else
<>             Fork: If V[0002] Is Equal To 6
<>               Show Picture: ID 1, Pic Num6 at (X,Y)
<>             Else
<>               Fork: If V[0002] Is Equal To 7
<>                 Show Picture: ID 1, Pic Num7 at (X,Y)
<>               Else
<>                 Fork: If V[0002] Is Equal To 8
<>                   Show Picture: ID 1, Pic Num8 at (X,Y)
<>                 Else
<>                   Fork: If V[0002] Is Equal To 9
<>                     Show Picture: ID 1, Pic Num9 at (X,Y)
<>                   Else
<>                     Erase Picture: ID 1
<>                   End Fork
<>                 End Fork
<>               End Fork
<>             End Fork
<>           End Fork
<>         End Fork
<>       End Fork
<>     End Fork
<>   End Fork

Ahh, the glory of Erase Picture. If our hundreds digit ends up as a big, fat 0 we really don't want to show it. Leading zeroes are really more trouble (and confusing) then they're worth. So we use Erase Picture instead of showing the 0.

Now we need to show the tens digit. Add the width of your number image to the current X value to get the new X. Leave the Y value unchanged.

<>   Fork: If V[0003] Is Equal To 1
<>     Show Picture: ID 2, Pic Num1 at (X,Y)
<>   Else
<>     Fork: If V[0003] Is Equal To 2
<>       Show Picture: ID 2, Pic Num2 at (X,Y)
<>     Else
<>       Fork: If V[0003] Is Equal To 3
<>         Show Picture: ID 2, Pic Num3 at (X,Y)
<>       Else
<>         Fork: If V[0003] Is Equal To 4
<>           Show Picture: ID 2, Pic Num4 at (X,Y)
<>         Else
<>           Fork: If V[0003] Is Equal To 5
<>             Show Picture: ID 2, Pic Num5 at (X,Y)
<>           Else
<>             Fork: If V[0003] Is Equal To 6
<>               Show Picture: ID 2, Pic Num6 at (X,Y)
<>             Else
<>               Fork: If V[0003] Is Equal To 7
<>                 Show Picture: ID 2, Pic Num7 at (X,Y)
<>               Else
<>                 Fork: If V[0003] Is Equal To 8
<>                   Show Picture: ID 2, Pic Num8 at (X,Y)
<>                 Else
<>                   Fork: If V[0003] Is Equal To 9
<>                     Show Picture: ID 2, Pic Num9 at (X,Y)
<>                   Else
<>                     Fork: If V[0002] Is Greater Than 0 (use "Above" in the dialog)
<>                       Show Picture: ID 2, Pic Num0 at (X,Y)
<>                     Else
<>                       Erase Picture: ID 2
<>                     End Fork
<>                   End Fork
<>                 End Fork
<>               End Fork
<>             End Fork
<>           End Fork
<>         End Fork
<>       End Fork
<>     End Fork
<>   End Fork

Now, if the tens digit is a zero, there's a possibility it's not a leading zero (as in when the hero's HP is 100 or over). So we have to check the hundreds digit if it's a zero as well. If it isn't, display the zero. If it is, kill the tens digit as well.

Once again, add the width of your number image to the current X value. Now we display the ones.

<>   Fork: If V[0004] Is Equal To 1
<>     Show Picture: ID 3, Pic Num1 at (X,Y)
<>   Else
<>     Fork: If V[0004] Is Equal To 2
<>       Show Picture: ID 3, Pic Num2 at (X,Y)
<>     Else
<>       Fork: If V[0004] Is Equal To 3
<>         Show Picture: ID 3, Pic Num3 at (X,Y)
<>       Else
<>         Fork: If V[0004] Is Equal To 4
<>           Show Picture: ID 3, Pic Num4 at (X,Y)
<>         Else
<>           Fork: If V[0004] Is Equal To 5
<>             Show Picture: ID 3, Pic Num5 at (X,Y)
<>           Else
<>             Fork: If V[0004] Is Equal To 6
<>               Show Picture: ID 3, Pic Num6 at (X,Y)
<>             Else
<>               Fork: If V[0004] Is Equal To 7
<>                 Show Picture: ID 3, Pic Num7 at (X,Y)
<>               Else
<>                 Fork: If V[0004] Is Equal To 8
<>                   Show Picture: ID 3, Pic Num8 at (X,Y)
<>                 Else
<>                   Fork: If V[0004] Is Equal To 9
<>                     Show Picture: ID 3, Pic Num9 at (X,Y)
<>                   Else
<>                     Show Picture: ID 3, Pic Num0 at (X,Y)
<>                   End Fork
<>                 End Fork
<>               End Fork
<>             End Fork
<>           End Fork
<>         End Fork
<>       End Fork
<>     End Fork
<>   End Fork

A zero in the ones place is never a leading zero - either the player has at least 10 HP, or the player is dead with a big, fat zero. It's not kind, but it is the facts.

<> End Fork
<> Wait: 0.0 sec.

And that's it. The lag-killer "Wait 0.0" isn't as essential, but it is still a good idea.

But wait! There's more.

--- HP Percentage Bar

Instead of a numeric readout, you can use a percentage bar for the HP. Brings back memories of Castlevania: Circle of the Moon. If your game is more action than RPG, this'd be a good way to go. And best of all, you can do it with only two pictures!

The trick with a two picture setup is butting the edge of the bar right up against the edge of the screen. Any part of the picure that's offscreen will simply not be shown (Editor's note: Well, duh!).

--- Image setup

You'll need two images: the frame and the bar. The frame needs to be at least as large as the bar (pixel-wise); in fact, make it a couple pixels larger. Also make sure the left side of the frame is as large as the bar itself, so no stray pixels of the bar show through from under the frame.

These two images get the honor of being "Frame" and "HPBar".

--- Variable and switch setup

This style of display is great for minimalism: it needs only three variables. Since we're not displaying numbers directly, our HP values can be as large as we need them without fear of overflow. And one again, we use a "last" value to reduce lag.

  • V[0001]: Player's HP Last
  • V[0002]: Player's HP Percent and Bar X position
  • V[0003]: Player's HP Max and Bar Y position

--- The script

Our script starts much the same as the numeric display, but is far shorter. There's a little more math involved, though.

<> Set Variable: V[0002], Set to Hero's HP
<> Fork: If V[0001], V[0002] Are Not Equal
<>   Set Variable: V[0001], Set to V[0002]

I've already explained these lines; I won't do so again. The next requires some explanation, however.

Normally, the percentage of a number is Current / Maximum. To make this a whole number, you multiply by 100. RM2k has a strange quirk that makes using this method impossible; it drops the fraction of any number you pass it. Thus, if your current value is ANYTHING less than the maximum, you'll get 0 for your result. And anything times zero is zero. Solution? Multiply first.

But we're not necessarily multiplying by 100. To make it easy on us for the display, we need to multiply by the resolution of our health bar. The resolution is simply the number of pixels wide you made the bar. If your HP bar is 25 pels wide, multiply by 25. If it's 200, multiply by 200. Plug in that number into the resolution on the next line.

<>   Set Variable: V[0002], Multiply by Resolution (width of HP bar)

Then perform the percentage calculation as normal.

<>   Set Variable: V[0003], Set to Hero's Max HP
<>   Set Variable: V[0002], Divide by V[0003]

Now, where do we put the bar on the screen? This is the tricky number; since the position of a picture is based on its center instead of its corner, we don't add to the variable. We subtract from it. But by how much? And where does the frame come into play? To get this mystical value, take the width of the HP bar in pels and divide by 2. Now subtract the number of pels the frame has on its left edge from this number. There you go; your Displacement.

<>   Set Variable: V[0002], Subtract Displacement (HP bar width / 2 - frame edge width)

We're almost ready to place the thing on the screen. But coordinates always come in twos: an X and a Y. The Y is a little simpler: half the height of your HP bar, plus the height of the frame's top edge. Or a bit lower, if you'd like. And since we're using a variable for the X position we have to use a variable for the Y. Blame it on RM2k.

<>   Set Variable: V[0003], Set to Y Position (HP bar width / 2 + frame edge height)

And now the final placing.

<>   Show Picture: ID 1, Pic HPBar at (V[0002], V[0003])

The frame is even simpler - it's at a fixed position. The only catch is it MUST have a higher ID than the bar, or the bar will show itself over the frame. Not usually desirable.

<>   Show Picture: ID 2, Pic Frame at (X Position (frame width / 2), Y Position)
<> End Fork
<> Wait: 0.0sec

And we're through.

--- The final word

Two tutorials for the price of one? It's ludicrious! But the entry price is right. If you want to use it, feel free - but like anything you put work into, you want credit. I'm no exception. Just drop my name in the credits or send me an email saying "thanks." That's all. Nothing hard.

Feel free to ask questions about the script... but only if they're intelligent. No questions along the lines of "i saw your tutorial i dont understand it help me". Idiotic letters will be printed out and openly mocked at your expense.

Also feel free to tweak the script. If you see an area where you think it can be improved, do it. One possibility is multiple HP/MP bars (maybe for more than one person) or a quad digit display. You don't even have to use it for an HP display. Get creative.

And may the schwartz be with you.

--- Legal and acknowledgements

This document is ©2002 Dan Sandstrom.

RPG Tsukuru 2000 / RPG Maker 2000 is ©2000 ASCII / Yoji Ojima.

Ask if you wish to use this tutorial on your site, I may update it in the future. Violators will be prosecuted to the fullest extent of my foot.

The WhoopA Network - Design and content ©2001-2006 Dan Sandstrom