1

我正在学习一些 Java 中的 swing 和 awt 编程,所以我决定制作 Pong。Main 类是父 JFrame。它实例化一个 Ball 和一个 Paddle 并添加它们(它们是 JPanel)。但是,仅显示添加的最后一个。我该如何解决?

代码:

public class Main extends JFrame {

public Main() {
    super("Pong");
    add(new Ball());
    add(new Paddle());

    setSize(500, 500);
    setBackground(Color.orange);
    setLocationRelativeTo(null);
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    new Main().setVisible(true);
}

}

球类:

public class Ball extends JPanel implements ActionListener {

Timer timer;
private Vec2d position;
private Vec2d velocity;
private Dimension ballSize;

public Ball() {
    super();
    position = new Vec2d(50, 50);
    velocity = new Vec2d(2, 3);
    timer = new Timer(25, this);
    ballSize = new Dimension(40, 40);

    timer.start();
}    


@Override
public void actionPerformed(ActionEvent ae) {
    //Perform game frame logic
    bounceBall();
    repaint(); 
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.fillArc((int)position.x, (int)position.y, ballSize.width, 
            ballSize.height, 0, 360);
    position.add(velocity);
}

private void bounceBall() {
    if(position.x < 0 || position.x > getWidth() - ballSize.width) {
        velocity.x *= -1;
    }

    if (position.y < 0|| position.y > getHeight() - ballSize.height) {
        velocity.y *= -1;
    }
}

}

最后是 Paddle 类:

public class Paddle extends JPanel implements ActionListener {

private Vec2d position;
private double yVelocity;

private Rectangle rect;

private Timer timer;


public Paddle() {
    super();
    position = new Vec2d(30, 250);
    yVelocity = 0;

    timer = new Timer(25, this);
    timer.start();
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.fillRect((int) position.x, (int) position.y, 20, 40);
}

@Override
public void actionPerformed(ActionEvent ae) {
    repaint();
}

}

请注意,这Vec2d只是我放在一起的一个小的二维 Vector 类。此外,Pong 逻辑(桨与球之间的碰撞、得分等)未实现。我只想让它正确绘制

在此先感谢您的帮助!

4

4 回答 4

1

您将Balland添加Paddle到同一BorderLayout.CENTER位置,因此仅显示添加的最后一个(即Paddle)。您可以使用 a GridLayouthere 显示:

setLayout(new GridLayout(1, 2));
add(new Paddle());
add(new Ball());
于 2012-12-29T17:20:37.743 回答
1

首先要做的是将JPanels 添加到窗口的内容窗格中,而不是添加到窗口本身。我很惊讶您没有收到关于此的运行时警告。

此外,看起来您打算让每个面板都填满屏幕,但只绘制其中的一小部分。如果这确实是您想要的方式,那么您需要setOpaque(false)对它们进行操作,以便它们下方的面板可以显示出来。但可能更好的解决方案是有一个单一JPanel的绘图表面,并将其paintComponent()传递Graphics给每个游戏对象,让它们自己绘制。

于 2012-12-29T17:19:37.960 回答
1
add(new Ball());
add(new Paddle());

默认情况下,JFrame 的布局管理器是 BorderLayout。如果您没有指定要添加组件的位置(BorderLayout.WEST、 或EAST等),则会将其添加到中心。所以你在同一个地方添加两个组件:在中心。因此,仅显示其中之一。

于 2012-12-29T17:19:40.610 回答
0

在 Paddle 类中,您永远不会像在球类中那样使用 position.add(velocity) 将速度添加到位置。

于 2012-12-29T17:27:02.760 回答