在 JPanel 中绘制一组对象

Painting a group of objects in a JPanel

我对 Java 和 GUI 世界还很陌生。现在我正在尝试创建一个非常基本的 space 射击游戏。为了创建它,我开始创建一个 JFrame,稍后我在其中放置了一个名为 GamePanelJPanel 的个人扩展,我现在正在尝试在其上显示我的所有组件.到这里为止一切都很清楚,现在问题来了:我有我的 GamePanel 显示我的播放器,在 KeyEvent 按下 S 播放器应该射击子弹。我将项目符号管理为一个名为 Shooter[] 的数组,由 Bullet 个对象组成,由我自己以这种方式创建:

public class Bullet implements ActionListener{

    Timer Time = new Timer(20, this);

    private int BulletY = 430;
    public int PlayerX;
    public Rectangle Bound = new Rectangle();

    public Bullet(int playerx) {
        this.PlayerX = playerx;
        Time.start();
    }

    public void draw(Graphics g){
        g.setColor(Color.RED);
        g.fillRect(PlayerX + 2, BulletY, 3, 10);

        g.dispose();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (Time.isRunning()) {
            BulletY = BulletY - 5;
            Bound = new Rectangle (PlayerX + 2, BulletY, 3, 10);
        }
    }

}

我认为在 GamePanelpaint() 方法中调用 draw 方法可以让我同时显示所有发射的子弹和玩家。实际发生的是,一开始它似乎还好,但是当我按下 S 时,播放器消失了,只发射了一颗子弹。你能解释一下为什么吗?这就是我的 paint() 方法的样子:

public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, 500, 500);

        for(int i = 0; i < BulletsCounter; i++) {
            Shooter[i].draw(g);
        }

        g.setColor(Color.RED);
        g.fillRect(PlayerX, PlayerY, 20, 20);

        //System.out.println("Here I should have painted the player...");

        g.dispose();
    }

BulletsCounter 是我创建的一个计数器,以避免在绘制整个阵列时出现任何 NullPointerExceptions,当按下 S 时它会增加,因此阵列的另一个子弹被初始化并发射。 感谢您的耐心等待,我是该网站的新手,如有任何错误请警告我。

你有几个严重的问题,首先给出最大的问题:

  • 您正在处置 JVM 提供给您的 Graphics 对象。永远不要这样做,因为这会破坏绘画链。相反,只处理您自己创建的 Graphics 对象。
  • 你在画图内绘图,这有几个原因并不好,但对动画尤其不利,因为你没有图像的自动双缓冲
  • 您没有在覆盖中调用超级绘画方法,因此不允许 JPanel 进行内务绘画。

建议:

  • 不要处理 Graphics 对象,除非您自己创建它,例如,如果您从 BufferedImage 中提取一个对象。
  • 覆盖 JPanel 的 paintComponent 方法,而不是其 paint 方法,以提供双缓冲和更流畅的动画效果。
  • 然后在覆盖中首先调用 super.paintComponent(g) 以允许内务处理绘画