简体   繁体   English

为什么我不能添加多个 Object 到 JPanel?

[英]Why I can't add more than one Object to the JPanel?

When I add to the GameScreen more than one Object of class Duck only one appears on the screen.当我向 GameScreen 添加多个 class Duck Object 时,屏幕上只出现一个。 When I add Duck outside constructor in GameScreen class I have many Object of Duck but then the mouseClicked method doesn't work on Duck.当我在 GameScreen class 中添加 Duck 外部构造函数时,我有很多 Object 的 Duck,但是 mouseClicked 方法在 Duck 上不起作用。

Take a look at How to Use BorderLayout .看看如何使用 BorderLayout BorderLayout will only present the last component added to any single position. BorderLayout将只显示添加到任何单个 position 的最后一个组件。

Having said that, I don't think this is the direction you really want to head in. Instead, start with a single JPanel and override its paintComponent method, then render all you game objects directly through.话虽如此,我认为这不是您真正想要进入的方向。相反,从单个JPanel开始并覆盖其paintComponent方法,然后直接渲染所有游戏对象。 Components are heavy objects with a lot of complexity and aren't generally well suited for this kind of operation.组件是非常复杂的重物,通常不太适合这种操作。

Also, you also don't need 3+ threads (Swing Timer s make use of a thread to schedule calls back to the UI).此外,您也不需要 3 个以上的线程(Swing Timer使用线程来安排对 UI 的调用)。 Use a single Swing Timer as your "main game loop", which should be responsible for updating the state and scheduling paint passes.使用单个 Swing Timer作为您的“主游戏循环”,它应该负责更新 state 和安排油漆通道。 Swing is not thread safe, so the use of the Thread to update the label is ill advised. Swing 不是线程安全的,因此不建议使用Thread来更新 label。

在此处输入图像描述

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    BufferedImage img = ImageIO.read(getClass().getResource("/images/Duck.png"));
                    List<Duck> ducks = new ArrayList<>();
                    ducks.add(new Duck(img));
                    ducks.add(new Duck(img));

                    JFrame frame = new JFrame();
                    frame.add(new GamePane(ducks));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class Duck {
        private BufferedImage image;

        private int x;
        private int y;

        private int xDelta = 0;
        private int yDelta = 0;

        public Duck(BufferedImage image) {
            this.image = image;
        }

        public BufferedImage getImage() {
            return image;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public void setLocation(int x, int y) {
            setX(x);
            setY(y);
        }

        public void setX(int x) {
            this.x = x;
        }

        public void setY(int y) {
            this.y = y;
        }

        public int getWidth() {
            return image == null ? 0 : image.getWidth();
        }

        public int getHeight() {
            return image == null ? 0 : image.getHeight();
        }

        public void setDelta(int x, int y) {
            xDelta = x;
            yDelta = y;
        }

        public int getXDelta() {
            return xDelta;
        }

        public int getYDelta() {
            return yDelta;
        }

        public void move(Rectangle bounds) {
            int xDelta = getXDelta();
            int yDelta = getYDelta();
            int x = getX() + xDelta;
            int y = getY() + yDelta;

            if (x < bounds.x) {
                x = bounds.x;
                xDelta *= -1;
            } else if (x + getWidth() >= bounds.x + bounds.width) {
                x = (bounds.x + bounds.width) - getWidth();
                xDelta *= -1;
            }

            if (y < bounds.y) {
                y = bounds.y;
                yDelta *= -1;
            } else if (y + getWidth() >= bounds.y + bounds.height) {
                y = (bounds.y + bounds.height) - getHeight();
                yDelta *= -1;
            }
            setDelta(xDelta, yDelta);
            setLocation(x, y);
        }

        public void paint(Graphics2D g2d, ImageObserver observer) {
            g2d.drawImage(getImage(), getX(), getY(), observer);
        }
    }

    public class GamePane extends JPanel {
        private List<Duck> ducks;

        public GamePane(List<Duck> ducks) {
            this.ducks = ducks;

            Random rnd = new Random();

            for (Duck duck : ducks) {
                int width = 400 - duck.getWidth();
                int height = 400 - duck.getHeight();

                int x = rnd.nextInt(width);
                int y = rnd.nextInt(height);

                int xDelta = rnd.nextBoolean() ? 1 : -1;
                int yDelta = rnd.nextBoolean() ? 1 : -1;

                duck.setLocation(x, y);
                duck.setDelta(xDelta, yDelta);
            }

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Rectangle bounds = new Rectangle(getSize());
                    for (Duck duck : ducks) {
                        duck.move(bounds);
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (Duck duck : ducks) {
                Graphics2D g2d = (Graphics2D) g.create();
                duck.paint(g2d, this);
                g2d.dispose();
            }
        }
    }
}

From this, you can start adding more entities as needed, for example, I can modify the Main method to include LOTs of ducks...由此,您可以根据需要开始添加更多实体,例如,我可以修改Main方法以包含很多鸭子......

BufferedImage img = ImageIO.read(getClass().getResource("/images/Duck.png"));
List<Duck> ducks = new ArrayList<>(100);
for (int index = 0; index < 100; index++) {
    ducks.add(new Duck(img));
}

This is obviously and overly simplified example intended only as a demonstration of core concept, you'll need to do more research into basic game development and 2D graphics.这显然是一个过于简化的示例,仅用于演示核心概念,您需要对基本游戏开发和 2D 图形进行更多研究。

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

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