Ваша проблема в том, что вы делаете класс Paddle расширяющим JPanel, когда вам не следует этого делать.
Только один класс компонентов должен выполнять фактическую визуализацию, один класс, который расширяет JPanel и имеет переопределение метода protected void paintComponent(Graphics g)
.Гораздо лучше сделать класс Paddle логическим классом, конечно, с классом public void draw(Graphics g)
, который позволяет ему рисовать себя, но опять же весь реальный рендеринг должен выполняться внутри метода paintComponent JPanel с одним отображением.В этой единственной JPanel вызовите метод рисования вашего весла и любой другой метод рисования спрайтов, которые вы хотите нарисовать.
например,
// main drawing JPanel where *true* rendering is done
public class MainPanel extends JPanel {
private Paddle paddle1 = new Paddle( /* x and y init positions */ );
private Paddle paddle2 = new Paddle( /* x and y init positions */ );
private Ball ball = new Ball();
public MainPanel() {
// Swing Timer to drive the animation
new Timer(TIMER_DELAY, new TimerListener()).start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paddle1.draw(g);
paddle2.draw(g);
ball.draw(g);
// .....
}
private class TimerListener implements ActionListneer {
@Override
public void actionPerformed(ActionEvent e) {
// move all components here
// check for collisions
// do program logic
repaint();
}
}
}
public interface Drawable {
public void draw(Graphics g);
}
public class Paddle implements Drawable {
private int x;
private int y;
@Override
public void draw(Graphics g) {
// use x and y to draw rectangle
}
public void moveY(....) {
// ....
}
}
На самом деле, вы бы дали ему две переменные Paddle, чтобы можно было нарисовать обе лопасти ...