3

The HUD In need of fillling

I've decided on making a HUD with the picture above, but I don't know what command in Java I need to use so as I can fill the top half and the bottom half separately.

I only know how to use the g.fillRect(); command, and it will take around twenty of these commands to fill said half.

public class HUD {

    private Player player;
    private BufferedImage image;
    private Font font;
    private Font font2;
    private  int Phealth = Player.getHealth();

    public HUD(Player p) {
        player = p;
        try {
            image = ImageIO.read(getClass().getResourceAsStream("/HUD/HUD_TEST.gif"));
            font = new Font("Arial", Font.PLAIN, 10);
            font2 = new Font("SANS_SERIF", Font.BOLD, 10);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void draw(Graphics2D g) {

        g.drawImage(image, 0,  10,  null);
        g.setFont(font2);
        g.setColor(Color.black);
        g.drawString("Health:", 30, 22);
        g.drawString("Mana:", 25, 47);
        g.setFont(font);
        g.drawString(Player.getHealth() + "/" + player.getMaxHealth(), 64, 22);
        g.drawString(player.getCubes() / 100 + "/" + player.getMaxCubes() / 100, 55, 47);
        g.setColor(Color.red);
        g.fillRect(1, 25, Phealth * 25, 4);
        g.setColor(Color.blue);
        g.fillRect(1, 31, player.getCubes() / 33, 4);
    }
}

This is the code for the HUD so far.
Any help in filling the shape will help.

almightyGOSU
  • 3,731
  • 6
  • 31
  • 41
soul6942
  • 67
  • 9
  • Is it possible for you to make the 'area that you wish to fill' in the image transparent? Then you can draw the bars first, and draw the image on top of it? I am not sure if Graphics2D can handle images with transparency though. – almightyGOSU Jun 01 '15 at 04:31
  • I'm not really sure if it would work, or that Graphics2D would be able handle it, but the main problem is the lag. If I add in the 20 rectangles to fill it. the frame rate gets destroyed as it has to update all of the rectangles, so I was hoping that there was a simple way to just fill it in one command. – soul6942 Jun 01 '15 at 04:34
  • I have added an answer to illustrate my idea, take a look and see if you can understand? :) – almightyGOSU Jun 01 '15 at 04:50

1 Answers1

7

Removed Idea #1! (It didn't seem to work.)


Okay, Idea #2:

Image1 Image1

Image2 Image2


Image3 Image3

So, there are 3 .png images.

  • Draw Image1 first, followed by drawing Image2 and Image3 directly on top of it.
  • To fill up either the red/blue bars, clip Image2 and Image3 accordingly (i.e. cut away their left sides)

Take a look at this on clipping.
This will require some minor calculations on how much to clip, based on the HP/Mana of the Player, but it should be good enough.

Image4
This is what it should look like (Clipping and overlaying done in Paint)




UPDATE (Problem solved, using Idea #2!):

HP_AND_MP_BARS

Code:

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

@SuppressWarnings("serial")
public class TestGraphics extends JFrame implements ActionListener
{
    JPanel utilBar = new JPanel();

    JButton hpUpBtn = new JButton("HP++");
    JButton hpDownBtn = new JButton("HP--");
    JButton mpUpBtn = new JButton("MP++");
    JButton mpDownBtn = new JButton("MP--");

    GraphicsPanel drawingArea = new GraphicsPanel();

    TestGraphics()
    {   
        setSize(600, 500);
        setLayout(new BorderLayout());

        add(utilBar, BorderLayout.NORTH);
        utilBar.setLayout(new GridLayout(1, 4));

        utilBar.add(hpUpBtn);
        utilBar.add(hpDownBtn);
        utilBar.add(mpUpBtn);
        utilBar.add(mpDownBtn);

        add(drawingArea, BorderLayout.CENTER);

        hpUpBtn.addActionListener(this);
        hpDownBtn.addActionListener(this);
        mpUpBtn.addActionListener(this);
        mpDownBtn.addActionListener(this);

        setVisible(true);
    }

    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == hpUpBtn) {
            drawingArea.incHp();
        }
        else if (e.getSource() == hpDownBtn) {
            drawingArea.decHp();
        }
        else if (e.getSource() == mpUpBtn) {
            drawingArea.incMp();
        }
        else if (e.getSource() == mpDownBtn) {
            drawingArea.decMp();
        }

        System.out.println("Player HP: " + drawingArea.getHp() +
                " Player MP: " + drawingArea.getMp());

        drawingArea.revalidate();
        drawingArea.repaint();
    }

    public static void main(String[]agrs)
    {
        new TestGraphics();
    }
}

@SuppressWarnings("serial")
class GraphicsPanel extends JPanel {

    private static int baseX = 150;
    private static int baseY = 150;

    private static final int BAR_FULL = 287;
    private static final int BAR_EMPTY = 8;

    private BufferedImage image1 = null;
    private BufferedImage image2 = null;
    private BufferedImage image3 = null;

    private int playerHp = 100;
    private int playerMp = 100;

    public GraphicsPanel() {
        try {
            // All 3 images are the same as those posted in answer
            image1 = ImageIO.read(
                    getClass().getResourceAsStream("/Image1.png"));
            image2 = ImageIO.read(
                    getClass().getResourceAsStream("/Image2.png"));
            image3 = ImageIO.read(
                    getClass().getResourceAsStream("/Image3.png"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void incHp() { playerHp += (playerHp < 100) ? 5 : 0; }
    public void decHp() { playerHp -= (playerHp > 0) ? 5 : 0; }
    public void incMp() { playerMp += (playerMp < 100) ? 5 : 0; }
    public void decMp() { playerMp -= (playerMp > 0) ? 5 : 0; }

    public int getHp() { return playerHp; }
    public int getMp() { return playerMp; }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // Clear the graphics
        g.setClip(null);
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, 600, 600);

        g.drawImage(image1, baseX, baseY, null);

        int hpPerc = (int) ((BAR_FULL - BAR_EMPTY) * (playerHp / 100.0));
        g.setClip(baseX + BAR_EMPTY + hpPerc, 0, 600, 500);
        g.drawImage(image2, baseX, baseY, null);
        g.setClip(null);

        int mpPerc = (int) ((BAR_FULL - BAR_EMPTY) * (playerMp / 100.0));
        g.setClip(baseX + BAR_EMPTY + mpPerc, 0, 600, 500);
        g.drawImage(image3, baseX, baseY + 78, null);
        g.setClip(null);
    }
}
almightyGOSU
  • 3,731
  • 6
  • 31
  • 41
  • I tried doing this, but the image is just drawn behind the colour. Gonna try to create my own shape through lines, and the see if i can group them as one and fill it – soul6942 Jun 01 '15 at 06:13
  • Are you drawing the image first? i.e. `g.drawImage(image, 0, 10, null);` followed by `g.setColor(Color.red); g.fillRect(1, 25, Phealth * 25, 4); g.setColor(Color.blue); g.fillRect(1, 31, player.getCubes() / 33, 4);` – almightyGOSU Jun 01 '15 at 06:25
  • Lol forgot to draw it last. But the color is outside the hud as well now. – soul6942 Jun 01 '15 at 06:29
  • Okay, added another possible solution, take a look and hopefully that will help you! – almightyGOSU Jun 01 '15 at 06:54
  • so for some reason, when I try idea #2. the 2nd and 3rd image don't cover up the color. But if i try to put draw or fill a rectangle and then add them on top, it can be seen around it. – soul6942 Jun 01 '15 at 07:27
  • Image2 & Image3 should have the same width as Image1, but their height will be half of that of Image1. Logically, it should work if you position them correctly. I don't have access to an IDE right now so I can't try it out myself. – almightyGOSU Jun 01 '15 at 07:30
  • They were positioned exactly where they were meant to be, but for some reason the bottom picture was still being shown. thought of a different method using the top and bottom pieces and so will try it out. – soul6942 Jun 01 '15 at 07:32
  • thanks for trying to help, but im beginning to think that its impossible with graphics2D to do it. – soul6942 Jun 01 '15 at 09:13
  • thanks man, ill try to implement this into the existing code and I'll tell you if it works. – soul6942 Jun 05 '15 at 09:12
  • @soul6942 I have provided an working example, you can refer to it if needed. – almightyGOSU Jun 05 '15 at 09:13
  • quick question, how big were the pictures you used for it? – soul6942 Jun 05 '15 at 09:23
  • @soul6942 Exactly the same size as what I included in the answer. You can right-click, save image, to see the resolution. – almightyGOSU Jun 05 '15 at 09:25
  • Ah, I was trying to use the small 80x20 pictures i had, so it looked a bit different. – soul6942 Jun 05 '15 at 09:27
  • @soul6942 The figures you use in the clipping will depend on the image size, I got those numbers through some testing. – almightyGOSU Jun 05 '15 at 09:28