在Java中填充HUD

3

需要填充的HUD

我决定做一个类似上面图片的HUD,但是我不知道在Java中应该使用哪个命令来分别填充上半部分和下半部分。

我只知道如何使用g.fillRect();命令,并且需要使用大约20条这样的命令来填充半个屏幕。

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);
    }
}

以下是目前的HUD代码。
任何有助于填充形状的帮助都会有所帮助。

你能否将图像中“您希望填充的区域”变为透明?这样,您就可以先绘制条形图,然后在其上绘制图像。但我不确定Graphics2D是否能够处理具有透明度的图像。 - almightyGOSU
我不确定它是否可行,或者Graphics2D是否能够处理它,但主要问题是延迟。如果我添加20个矩形来填充它,帧率会崩溃,因为它必须更新所有矩形,所以我希望有一种简单的方法可以只用一个命令来填充它。 - soul6942
我已经添加了一个答案来阐述我的想法,看看你能不能理解? :) - almightyGOSU
1个回答

7

移除想法 #1!(似乎不起作用。)


好的,想法 #2:

Image1 图像1

Image2 图像2


Image3 图像3

所以有3个.png图像。

  • 首先绘制图像1,然后直接在其上绘制图像2图像3
  • 为了填充红/蓝条,剪辑图像2图像3(即削去它们的左侧)

查看这里关于剪切的内容。
这将需要进行一些小小的计算,根据玩家的HP / Mana来确定要剪辑多少,但应该足够了。

Image4
这就是应该的效果(在Paint中完成剪辑和叠加)




更新(问题已解决,使用想法 #2!):

HP_AND_MP_BARS

代码:

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
Image2和Image3的宽度应该与Image1相同,但它们的高度将是Image1的一半。从逻辑上讲,如果您正确地定位它们,它们应该可以工作。我现在无法访问IDE,因此无法自行尝试。 - almightyGOSU
它们被放置在它们应该在的位置,但由于某种原因底部图片仍然显示。我想到了一种使用顶部和底部块的不同方法,所以将尝试它。 - soul6942
谢谢,我会尝试将这个实现到现有的代码中,如果成功了我会告诉你的。 - soul6942
@soul6942,我已经提供了一个可工作的示例,如果需要可以参考它。 - almightyGOSU
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接