简体   繁体   English

在 JPanel 中绘制一组对象

[英]Painting a group of objects in a JPanel

I'm pretty new to Java and the GUI world.我对 Java 和 GUI 世界还很陌生。 Right now I'm trying to create a really basic space shooter.现在我正在尝试创建一个非常基本的太空射击游戏。 To create it I started creating a JFrame , in which I've later on put a personal extension of a JPanel called GamePanel , on which I'm now trying to display all my components.为了创建它,我开始创建JFrame ,后来我在其中放置了一个名为GamePanelJPanel的个人扩展,我现在正试图在其上显示我的所有组件。 Until here it's all pretty clear, the problem comes now: I have my GamePanel in which I display my player, and on the KeyEvent of pressing S the player should shoot the Bullets.直到这里一切都很清楚,现在问题来了:我有我的GamePanel ,我在其中显示我的玩家,并且在按下 S 的KeyEvent上,玩家应该射击子弹。 I've managed the bullets as an Array, called Shooter[] , of Bullet Objects, created by myself this way:我将子弹作为一个名为Shooter[]Bullet Objects 数组进行管理,由我自己以这种方式创建:

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

}

I thought that calling the draw method in the GamePanel 's paint() method would have allowed me to display both all the bullets shot and the player.我认为在GamePanelpaint()方法中调用 draw 方法可以让我同时显示所有射出的子弹和玩家。 What actually happens is that at the start it seems allright, but when I press S the player disappears and just one bullet is shot.实际发生的情况是,一开始看起来还不错,但是当我按下 S 时,玩家消失了,只射出一颗子弹。 Can you explain me why?你能解释一下为什么吗? This is how my paint() method looks like:这就是我的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 is a counter I've created to avoid any NullPointerException s in painting the whole array, it increases when S is pressed and so another bullet of the array is initialized and shot. BulletsCounter是我创建的一个计数器,用于避免在绘制整个数组时出现任何NullPointerException ,当按下 S 时它会增加,因此数组的另一个子弹被初始化并射击。 Thank you for your patience, I'm new to the site, so warn me for any mistake.感谢您的耐心等待,我是该网站的新手,如有任何错误请警告我。

You've several significant problems, the biggest given first:您有几个重大问题,首先给出最大的问题:

  • You're disposing a Graphics object given to you by the JVM.您正在处理 JVM 给您的图形 object。 Never do this as this will break the painting chain.永远不要这样做,因为这会破坏绘画链。 Instead, only dispose of a Graphics object that you yourself have created.相反,只处理您自己创建的图形 object。
  • You're drawing within paint which is not good for several reasons, but especially bad for animation since you don't have automatic double buffering of the image您在油漆中绘图,这有几个原因,但对 animation 尤其不利,因为您没有图像的自动双缓冲
  • You don't call the super painting method within your override and thus don't allow the JPanel to do house-keeping painting.您不会在覆盖中调用超级绘画方法,因此不允许 JPanel 进行内务绘画。

Recommendations:建议:

  • Don't dispose of the Graphics object, not unless you, yourself, create it, for example if you extract one from a BufferedImage.不要丢弃图形 object,除非您自己创建它,例如从 BufferedImage 中提取一个。
  • Override the JPanel's paintComponent method, not its paint method to give you double buffering and smoother animation.覆盖 JPanel 的 paintComponent 方法,而不是它的 paint 方法,为您提供双缓冲和更平滑的 animation。
  • And call super.paintComponent(g) first thing in your override to allow for housekeeping painting并首先在您的覆盖中调用super.paintComponent(g)以允许进行家务绘制

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM