我的重写绘制方法没有被调用

发布于 2024-11-26 00:59:58 字数 3174 浏览 0 评论 0原文

我有一个 JPanel 旨在充当我的游戏的 HUD,自然地,我已经重写了绘制方法来执行我自己的自定义显示,这确实被调用,但仅在调整大小或最大化、最小化框架时调用,而不是在我的游戏循环告诉它重新绘制()。这对我来说似乎特别奇怪,因为我的另外两个面板被重新粉刷得很好。

这是我的 HUD 类:

package base;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.BoxLayout;
import javax.swing.JPanel;

public class HUD extends JPanel {

    private Shiphud[] shiphuds;

    public HUD(Ship[] ships) {
        shiphuds = new Shiphud[ships.length];
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i] = new Shiphud(ships[i]);
            this.add(shiphuds[i]);
        }
    }
    @Override
    public void paint(Graphics g) {
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i].repaint();
        }
    }
    public void run() {
            repaint();
    }
    private class Shiphud extends JPanel {

        private Ship ship;

        public Shiphud(Ship ship) {
            this.ship = ship;
        }
        @Override
        public void paint(Graphics g) {
            if (ship != null) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
                int fullbar = (int) (this.getWidth() * 0.8);

                g.setColor(Color.GREEN);
                g.fillRoundRect(getWidth() / 10, getHeight() / 10,
                        (int) ((ship.energy / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.blue);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.4),
                        (int) ((ship.fuel / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.YELLOW);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.6),
                        (int) ((ship.ammo / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.MAGENTA);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.8),
                        (int) ((ship.special / 1000) * fullbar), getHeight() / 6, 10, 10);
                System.out.println("here" + System.currentTimeMillis());
            }
        }
    }
}

它在我的游戏类更新中与我的其他两个面板一起被调用,

public void update() {
  ...
    display.run();
    display2.run();
    hud.run();
}

它们被我的 JFrame 调用

public void runFrame() {
    Thread thread = new Thread() {
        @Override
        public void run() {
            gameLoop();
        }
    };
    thread.start();
}
public void gameLoop() {
    while (true) {
        long beginTime = System.nanoTime();
        game.update();
        long timeTaken = System.nanoTime() - beginTime;
        long timeLeft = (UPDATE_PERIOD - timeTaken) / 1000000;  // in milliseconds
        if (timeLeft < 10) {
            timeLeft = 10;   // set a minimum
        }
        try {
            // Provides the necessary delay and also yields control so that other thread can do work.
            Thread.sleep(timeLeft);
        } catch (InterruptedException ex) {
        }
    }
}

长期以来一直在尝试解决这个问题,但我只是不明白,任何帮助都是高度赞赏

I have a JPanel that is meant to act as a HUD for my game, naturally, I have overridden the paint method to do my own custom display, this does get called, but only upon resizing or maximizing, minimizing the frame, and not when my game loop tells it to repaint(). It seems particularly strange to me on account of my two other panels being repainted completely fine.

Here is my HUD class:

package base;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.BoxLayout;
import javax.swing.JPanel;

public class HUD extends JPanel {

    private Shiphud[] shiphuds;

    public HUD(Ship[] ships) {
        shiphuds = new Shiphud[ships.length];
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i] = new Shiphud(ships[i]);
            this.add(shiphuds[i]);
        }
    }
    @Override
    public void paint(Graphics g) {
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i].repaint();
        }
    }
    public void run() {
            repaint();
    }
    private class Shiphud extends JPanel {

        private Ship ship;

        public Shiphud(Ship ship) {
            this.ship = ship;
        }
        @Override
        public void paint(Graphics g) {
            if (ship != null) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
                int fullbar = (int) (this.getWidth() * 0.8);

                g.setColor(Color.GREEN);
                g.fillRoundRect(getWidth() / 10, getHeight() / 10,
                        (int) ((ship.energy / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.blue);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.4),
                        (int) ((ship.fuel / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.YELLOW);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.6),
                        (int) ((ship.ammo / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.MAGENTA);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.8),
                        (int) ((ship.special / 1000) * fullbar), getHeight() / 6, 10, 10);
                System.out.println("here" + System.currentTimeMillis());
            }
        }
    }
}

It gets called in my Game classes update along with my other two panels

public void update() {
  ...
    display.run();
    display2.run();
    hud.run();
}

Which gets called by my JFrame

public void runFrame() {
    Thread thread = new Thread() {
        @Override
        public void run() {
            gameLoop();
        }
    };
    thread.start();
}
public void gameLoop() {
    while (true) {
        long beginTime = System.nanoTime();
        game.update();
        long timeTaken = System.nanoTime() - beginTime;
        long timeLeft = (UPDATE_PERIOD - timeTaken) / 1000000;  // in milliseconds
        if (timeLeft < 10) {
            timeLeft = 10;   // set a minimum
        }
        try {
            // Provides the necessary delay and also yields control so that other thread can do work.
            Thread.sleep(timeLeft);
        } catch (InterruptedException ex) {
        }
    }
}

Been trying to figure this for a long time now, and I just don't get it, any help would be highly appreaciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

破晓 2024-12-03 00:59:58

不要重写 Swing 中的 paint 方法。

而是重写 paintComponent

然后,您不必为子组件调用 paintrepaint - 这将自动完成。

Do not override the paint method in Swing.

Override paintComponent instead.

Then you don't have to call paint or repaint for your subcomponents - this will be done automatically.

无妨# 2024-12-03 00:59:58

好吧,伙计们,谢谢你们的帮助,最后它需要结合你们所有的解决方案才能让它工作,最让我惊讶的是它需要是一个 JComponent 才能正确地重新绘制。这是有效的代码,

package base;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class HUD extends JPanel {

    private Shiphud[] shiphuds;

    public HUD(Ship[] ships) {
        shiphuds = new Shiphud[ships.length];
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i] = new Shiphud(ships[i]);
            this.add(shiphuds[i]);
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i].repaint();
        }
    }

    public void run() {
        repaint();
    }

    private class Shiphud extends JComponent {

        private Ship ship;

        public Shiphud(Ship ship) {
            this.ship = ship;
        }

        @Override
        public void paintComponent(Graphics g) {
            if (ship != null) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
                int fullbar = (int) (this.getWidth() * 0.8);

                g.setColor(Color.GREEN);
                g.fillRoundRect(getWidth() / 10, getHeight() / 10,
                        (int) ((ship.energy / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.blue);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.4),
                        (int) ((ship.fuel / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.YELLOW);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.6),
                        (int) ((ship.ammo / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.MAGENTA);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.8),
                        (int) ((ship.special / 1000) * fullbar), getHeight() / 6, 10, 10);

            }
        }
    }
}

干杯伙计们!

Alright guys, thanks for your help, in the end it required a combination of all your solutions to get it to work, what surprised me most was that it needed to be a JComponent for it to repaint properly. Here's the code that works

package base;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class HUD extends JPanel {

    private Shiphud[] shiphuds;

    public HUD(Ship[] ships) {
        shiphuds = new Shiphud[ships.length];
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i] = new Shiphud(ships[i]);
            this.add(shiphuds[i]);
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        for (int i = 0; i < shiphuds.length; i++) {
            shiphuds[i].repaint();
        }
    }

    public void run() {
        repaint();
    }

    private class Shiphud extends JComponent {

        private Ship ship;

        public Shiphud(Ship ship) {
            this.ship = ship;
        }

        @Override
        public void paintComponent(Graphics g) {
            if (ship != null) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
                int fullbar = (int) (this.getWidth() * 0.8);

                g.setColor(Color.GREEN);
                g.fillRoundRect(getWidth() / 10, getHeight() / 10,
                        (int) ((ship.energy / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.blue);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.4),
                        (int) ((ship.fuel / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.YELLOW);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.6),
                        (int) ((ship.ammo / 1000) * fullbar), getHeight() / 6, 10, 10);

                g.setColor(Color.MAGENTA);
                g.fillRoundRect(getWidth() / 10, (int) (getHeight() * 0.8),
                        (int) ((ship.special / 1000) * fullbar), getHeight() / 6, 10, 10);

            }
        }
    }
}

Cheers dudes!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文