java 如何清除JPanel

ohtdti5x  于 2023-01-01  发布在  Java
关注(0)|答案(1)|浏览(274)

我正在使用Swing开发一个2D游戏。以前,我常常在jPanel上渲染对象和播放器,而不是

panel.repaint();

方法并覆盖panel类中的paint方法。然后我了解了将渲染代码移动到Render类的概念,如下所示:

public class Renderer{
    public void render(Graphics g, Game game){
        game.getObjects.forEach(gameObject -> g.drawImage(....);
    }
}

使用这段代码,在一个绘图上总是有一个绘图,....问题是我不能(或者不知道如何)调用面板的超级方法repaint()。我想保留Render类,因为代码更加结构化。关于如何重置jPanel,有什么建议吗?
我尝试在调用render方法之前使用panel.repaint(),但我只是得到了一个空白屏幕。

public class Renderer {

public void render(Game game, Graphics graphics) {
    Player player = game.getPlayer();
    graphics.drawImage(player.getImage(), (int)player.getPosition().getX(), (int)player.getPosition().getY(), null);
    
}

}

public class Game{

private static Game instance;
private GamePanel gamePanel;
private Player player;
private Renderer renderer;
private boolean isRunning = true;
private final int MAX_FPS = 60;

private Game() {
    initialize();
    startGameLoop();
}

private void initialize() {
    renderer = new Renderer();
    player = Player.getInstance();
    gamePanel = GamePanel.getInstance(this);
    GameWindow.getInstance(gamePanel);
    
}

private void startGameLoop() {
    double timePerCycle = 1_000_000_000 / MAX_FPS;
    int updates = 0;
    long lastInfo = System.currentTimeMillis();
    long timeBefore = System.nanoTime();
    while(isRunning) {
        if(System.nanoTime() - timeBefore >= timePerCycle) {
            timeBefore = System.nanoTime();
            update();
            render();
            updates++;
        }
        
        if(System.currentTimeMillis() - lastInfo >= 1000) {
            System.out.printf("UPS: %d\n", (updates / (( System.currentTimeMillis() - lastInfo) / 1000)));
            lastInfo = System.currentTimeMillis();
            updates = 0;
        }
    }
    
}

private void render() {
    Graphics graphics = gamePanel.getGraphics();
    renderer.render(this, graphics);
    graphics.dispose();
}
qaxu7uf2

qaxu7uf21#

要清除面板,您可以在paintComponent中使用boolean,并通过g.fillRect(x,y, width, height)填充矩形。
这是一个可能的例子,其中boolean clearScreen是一个示例字段。

public void clear() {
    clearScreen = true;  // tested in paintComponent
    repaint();
    clearScreen = false;
}

以下是一些其他建议。

  • 不要为JPanel重写paint。使用paintComponent
  • 第一个语句应该是super.paintComponent(g)。这是panel.setBackground()工作的原因,尤其是它调用重写的方法来执行其他功能。
@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    // your stuff here
}
  • 使用Swing Timer控制重绘循环。
  • 绘制和事件处理在EventDispatch线程中完成。因此处理应该保持在最低限度。游戏所需的任何计算都应该在该线程之外完成,并且在可能的情况下,只有图形方法的实际调用才应该在paintComponent方法中完成。
  • 如果操作正确,随后对repaint()的调用不会添加到那里。每次调用都必须重绘所有内容,包括更改。

有关详细信息,请查看How to paint
这个网站上有很多绘画的例子。使用[Swing][Graphics]标签搜索它们。下面是一个使用了上述一些的例子。还要注意Swing组件默认启用双缓冲

相关问题