代码之家  ›  专栏  ›  技术社区  ›  zkalman

只能添加JLabel背景或JPanel背景

  •  0
  • zkalman  · 技术社区  · 7 年前

    我正在用Java制作我的第一个游戏。这也是第一次使用swing。我很难将对象正确添加到帧中。

    一些不相关的代码已从其他类中删除。可能缺少多个引用的组件。

    主要内容:

    public class Main { 
        Ball ball = new Ball();
        int yBall = 0;
    
        public static void main(String[] args) throws InterruptedException {
            Main main = new Main();
            main.run();
            while (true) {
                main.ball(100);
            }
        }
        public void run() throws InterruptedException {
            Data data = new Data();
            Frame frame = new Frame(700, 500);
            test.setAngleX();
            frame.add(data, BorderLayout.CENTER);
        }
    }
    

    当我在数据(背景)后添加球时,我的球在帧上可见,与我的数据重叠。如果我在这里切换位置,我的数据将可见,但我的球不可见,球仍在下面。 框架添加(球); 框架setVisible(真);

    public void ball(int yBall) throws InterruptedException {
        ball.Ball();
        yBall = ball.SendY();
    }
    

    这是我的框架,我知道这里没有问题:

    public class Frame extends JFrame {
        private int frameWidth;
        private int frameHeight;
        int yBall = 0;
    
        public Frame(int frameWidth, int frameHeight) {
            this.frameWidth=frameWidth;
            this.frameHeight = frameHeight;
    
            setSize(new Dimension(frameWidth, frameHeight));
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        }
    }
    

    这是我的球。paintComponent已经结束了,在此之前,它只是工作逻辑,我猜这与逻辑无关。

    球:

    public class Ball extends JLabel{
    
    Graphics g1;
    
    int x = 325, y = 225;
    int speed = 1;
    int angleX = 0;
    int angleY = 0;
    
    public Ball() {
    }
    
    public void setAngleX() {
    
        angleX = ThreadLocalRandom.current().nextInt(-5, 5 + 1);    
        angleY = ThreadLocalRandom.current().nextInt(-1, 1 + 1);    
    
        if (angleX == 0) {
            setAngleX();
        }
    
        if (angleY == 0) {
            setAngleX();
        }
    }
    
    public void move() {
    
        if (x + angleX < 0) {
            angleX = speed;
        } else if (x + angleX > getWidth() - 25) {
            angleX = -speed;
        } else if (y + angleY < 0) {
            angleY = speed;
        } else if (y + angleY > getHeight() - 25) {
            angleY = -speed;
        }
    
        x = x + angleX;
        y = y + angleY;
    }
    
    public void Ball() throws InterruptedException {
        move();
        repaint();
    
        int sleepSpeed = angleX * speed;
        if (sleepSpeed < 0) {
            sleepSpeed = -sleepSpeed;
    
            Thread.sleep(10*sleepSpeed);
        }
    }
    
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.WHITE);
        g.fillOval(x, y, 25, 25);
    }
    public int SendY() {
        return y;
    }
    

    最后是我的数据;

    public class Data extends JPanel{
        private static final long serialVersionUID = 1L;
        private Graphics2D g2;
        public Data() {
        }
        @Override
        public void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.BLACK);
            g2.fillRect(0, 0, getSize().width, getSize().height);
            g2.setColor(Color.lightGray);
            g2.fillRect(350, 0, 10, 400);
        }
    

    所以,我要么在帧上获取数据(背景),要么让球在空背景上弹来弹去,这取决于我在主帧中最后添加的背景。我猜这是重叠的bcz,但无论我搜索多少,我都找不到适合我的代码的解决方案。。

    1 回复  |  直到 7 年前
        1
  •  1
  •   camickr    7 年前

    我要么在帧上获取数据(背景),要么让球在空背景上弹来弹去,这取决于我在主帧中最后添加的背景。

    不能将两个组件都添加到框架中。你需要有父母/子女关系。

    所以逻辑应该是这样的:

    background.add( ball );
    frame.add( background );
    

    然后将绘制框架,然后绘制背景,最后绘制球。

    此外,Ball类还需要实现 getPreferredSize() 方法使组件具有合理的大小。应该在“绘制组件”方法中的偏移(0,0)处绘制球。当您想在背景面板上移动球时,只需使用setLocation(…)在球上重新定位它在背景上。创建球时,还需要将球的大小设置为首选大小,以便在背景面板上绘制球的大小/位置。背景面板的布局需要设置为null,以便您可以围绕面板自由移动球。

    您不应该扩展JLabel,您没有使用JLabel的任何功能。您正在进行自定义绘制,所以只需扩展JPanel或JComponent即可。阅读Swing教程中的部分 Custom Painting 有关更多信息和工作示例。

    此外,方法名称不应以大写字符开头。 Ball() 不是正确的方法名称。它看起来像类名。该方法应更具描述性。

    或者另一种方法,不是有两个组件,而是有一个组件。然后 paintComopnent(...) 该组件的方法将同时绘制:

    1. 背景

    然后,通过这种方式,您可以相对于背景面板绘制球,这是您的逻辑当前的工作方式。