2

Right now I'm working on a game and I'm implementing a health bar. I got stuck making the right formula. This is my code of the Hud you see in the image:

public class CharacterHUD {

    private Image image;
    private Player player;

    private float xHealth, yHealth;
    private float healthBarWidth, healthBarHeight;
    private double healthBarY = 0;
    private double multiplier;

    public CharacterHUD(float xHealth, float yHealth, Image image, Player player) {
        this.image = image;
        this.player = player;
        this.xHealth = xHealth; // X Offset from the frame, 20 in this case.
        this.yHealth = yHealth; // Y Offset from the frame, 17 in this case.
        healthBarWidth = 38;
        healthBarHeight = 173;
    }

    public void update(int delta) {
        healthBarY = (yHealth / 100 * player.getHealth());
        multiplier = (yHealth / healthBarY);
        Log.log("Percentage: " + multiplier);
        Log.log("yHealth: " + yHealth + "+ Health: " + healthBarY);
        Log.log("Actual yHealth: " + (healthBarHeight * multiplier));

    }

    public void render(Graphics g) {
        // The coordinates are going from top-left(x,y) to bottomright(width,height). Also, the yHealth is the offset from the frame. 
        Resources.healthBar.draw(xHealth, (float) (healthBarHeight / multiplier) + yHealth, healthBarWidth, (float) (healthBarHeight / multiplier));
        image.draw(0, 0);
    }

}

On 50 health it looks like this:

So

On 75 health it looks like this:

So2

What am I doing wrong?

Timon de Groot
  • 7,255
  • 4
  • 23
  • 38
  • What is `multiplier` supposed to do? – DerMike Aug 27 '13 at 14:11
  • 7
    @Dennisch Isn't that just restating the OP's problem? – millimoose Aug 27 '13 at 14:11
  • It would kind of help if you had separate variables for the bounding box of the health bar "container" and the health bar itself. It's not perfectly clear when you're drawing what, you should explain what the parameters to `draw()` mean. Also, if `Player.getHealth()` a `double`? If not the fact you're using integral division might contribute. – millimoose Aug 27 '13 at 14:13
  • Also, shouldn't it be `healthBarHeight * multiplier`? It seems that `multiplier` will be a number between `0` and `1`, so you should, in fact, multiply the maximum height to get the height up to which you should be filling in the bar. – millimoose Aug 27 '13 at 14:16
  • Ok, maybe I answered the question a little bit too literally :) – Dennisch Aug 27 '13 at 14:16
  • Actually what would be ideal if you could provide a test case that doesn't really depend on a bunch of other code. I.e. just fill in a rectangle with a solid color using the most basic Slick2D calls possible, without using resources or depending on the implementation of the `player` object or whatever. If for no other reason than reducing the cognitive load that filling in the blanks requires. – millimoose Aug 27 '13 at 14:19
  • added some comments to the declarations. Also please note that the y should get lower as the health gets lower. – Timon de Groot Aug 27 '13 at 14:59

2 Answers2

2

Would it be

Resources.healthBar.draw(xHealth, (float) (healthBarHeight / multiplier) - yHealth, healthBarWidth, (float) (healthBarHeight / multiplier));

instead of + yHealth?

Note: I am not familiar with the method you are using but it seems like it is using window coordinates (from the top left) which would mean the y-coordinate to start from should decrease as health increases.

John Starich
  • 619
  • 11
  • 15
  • 1
    The coordinates are going from top-left(x,y) to bottomright(width,height). Also, the yHealth is the offset from the frame. – Timon de Groot Aug 27 '13 at 14:29
  • 2
    @TimondeGroot This sort of information belongs in the question. I.e. in comments next to the parameters for `draw()` – millimoose Aug 27 '13 at 14:44
1

Your calculation for the height of the bar is backwards. I don't know what order the parameters in that Resource.HealthBar are in or what they allow, but here's some pseudo code for what you want.

topLeft = (healthBarLeft, healthBarTop + (1 - healthPercent) * healthBarHeight)
bottomRight = (healthBarLeft + healthBarWidth, healthBarTop + healthBarHeight)

The (1 - healthPercent) means that when you have 10% health left, the bar will start 90% of the way down.

Edit: If it doesn't support topLeft / bottomRight and instead expects a width / height, use:

dimensions = (healthBarWidth, healthPercent * healthBarHeight)