Java的面板双缓冲

Java的面板双缓冲

本文介绍了Java的面板双缓冲的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
想知道如果有人能在正确的directon点我,我已经开发了一个乒乓游戏,它需要双缓冲由于闪烁。四tryed一些放在这里后,试图使其工作,但IM仍然摇摆AWT SUFF一个初学者,任何帮助将是惊人的感谢。

 公共类PongPanel继承JPanel实现Runnable {私人INT屏幕宽度= 500;
私人INT screenHeight = 300;私人布尔isPaused得到= FALSE;
私人布尔isGameOver = FALSE;私人INT playToPoints = 10;私人帕德尔PLAYER1,player2;
私人球球;私人螺纹gameThread;
私人图像数据库图像;
私有图形DBG;公共PongPanel(){
   集preferredSize(新尺寸(屏幕宽度,screenHeight));
   的setBackground(Color.BLACK);
   setDoubleBuffered(真);
   setFocusable(真);
   requestFocus()方法;   PLAYER1 =新帕德尔(Position.LEFT,屏幕宽度,screenHeight);
   player2 =新帕德尔(Position.RIGHT,屏幕宽度,screenHeight);
   球=新球(10,屏幕宽度/ 2,screenHeight / 2,Color.WHITE);
}公共无效信息addNotify(){
 super.addNotify();
   开始游戏();
}私人无效startGame(){
  gameThread =新主题(本);
  gameThread.start();
}@覆盖
公共无效的run(){
 而(!isGameOver){
 数据库图像=的createImage(屏幕宽度,screenHeight);
 DBG = this.getGraphics();
 如果(!isPaused得到){
   如果(!gameOverCheck()){
     updateGame();
     paintComponents(DBG);
    }
 }否则如果(isPaused得到){
    dbg.setColor(Color.ORANGE);
    dbg.setFont(新字体(衬,Font.BOLD,50));
    dbg.drawString(暂停,屏幕宽度/ 2-82,screenHeight / 2);
 }
 尝试{
     视频下载(30);
    }赶上(InterruptedException的E){e.printStackTrace();}
   }
   }  私人布尔gameOverCheck(){
  如果(player1.getScore()== playToPoints){
   dbg.setColor(player1.getColour());
   dbg.setFont(新字体(衬,Font.BOLD,50));
   dbg.drawString(玩家1胜!,屏幕宽度/ 2 - 161,screenHeight / 2);
   setGameOver(真);
   返回true;
  }否则如果(player2.getScore()== playToPoints){
   dbg.setColor(player2.getColour());
   dbg.setFont(新字体(衬,Font.BOLD,50));
   dbg.drawString(玩家2胜!,屏幕宽度/ 2 - 161,screenHeight / 2);
   setGameOver(真);
   返回true;
  }  返回false;
 } 私人无效updateGame(){
  ball.move(屏幕宽度,screenHeight,PLAYER1,player2);
  player1.aiForPadel(屏幕宽度,screenHeight,ball.getX(),ball.getY());
  player2.aiForPadel(屏幕宽度,screenHeight,ball.getX(),ball.getY()); }  @覆盖
  公共无效paintComponents(图形G){
  super.paintComponents(G);
  dbg.setColor(Color.BLACK);
  dbg.fillRect(0,0,屏幕宽度+ 20,screenHeight + 20);
  dbg.setColor(Color.WHITE);
  dbg.drawLine(屏幕宽度/ 2,0,屏幕宽度/ 2,screenHeight);
  dbg.setFont(新字体(衬,Font.BOLD,32));
  dbg.drawString(player1.getScore()+,屏幕宽度/ 2-40,screenHeight - 20);
  dbg.drawString(player2.getScore()+,屏幕宽度/ 2 + 20,screenHeight - 20);
  ball.drawBall(DBG);
    player1.drawPadel(DBG);
    player2.drawPadel(DBG);
 }
}


解决方案

有是一个非常好的教程的其中介绍了如何使用的产生无闪烁的动画。

重要的要点是:


  • 呼叫 setIgnoreRepaint(真)的顶级画布重画它prevent AWT,因为你会通常会在动画循环中这样做你自己。

  • 获得来自的Graphics2D 对象 BufferStrategy使用(而不是通过的paintComponent(图形G)。

Hey everyone,wondered if anyone could point me in the right directon, i have developed a pong game and it needs double buffering due to flickering. Iv tryed some of the post on here to try and make it work, but im still a beginner with the swing awt suff, any help would be amazing thanks.

public class PongPanel extends JPanel implements Runnable {

private int screenWidth = 500;
private int screenHeight = 300;

private boolean isPaused = false;
private boolean isGameOver = false;

private int playToPoints = 10;

private Padel player1,player2;
private Ball ball;

private Thread gameThread;
private Image dbImage;
private Graphics dbg;

public PongPanel() {
   setPreferredSize(new Dimension(screenWidth,screenHeight));
   setBackground(Color.BLACK);
   setDoubleBuffered(true);
   setFocusable(true);
   requestFocus();

   player1 = new Padel(Position.LEFT,screenWidth,screenHeight);
   player2 = new Padel(Position.RIGHT,screenWidth,screenHeight);
   ball = new Ball(10,screenWidth/2,screenHeight/2,Color.WHITE);
}

public void addNotify(){
 super.addNotify();
   startGame();
}

private void startGame(){
  gameThread = new Thread(this);
  gameThread.start();
}

@Override
public void run() {
 while (!isGameOver) {
 dbImage = createImage(screenWidth,screenHeight);
 dbg = this.getGraphics();
 if(!isPaused){
   if(!gameOverCheck()){
     updateGame();
     paintComponents(dbg);
    }
 }else if(isPaused){
    dbg.setColor(Color.ORANGE);
    dbg.setFont(new Font("serif",Font.BOLD,50));
    dbg.drawString("Paused", screenWidth/2-82, screenHeight/2);
 }
 try {
     Thread.sleep(30);
    } catch (InterruptedException e) {e.printStackTrace();}
   }
   }

  private boolean gameOverCheck(){
  if(player1.getScore() == playToPoints){
   dbg.setColor(player1.getColour());
   dbg.setFont(new Font("serif",Font.BOLD,50));
   dbg.drawString("Player 1 Wins!", screenWidth/2 - 161, screenHeight/2);
   setGameOver(true);
   return true;
  }else if(player2.getScore() == playToPoints){
   dbg.setColor(player2.getColour());
   dbg.setFont(new Font("serif",Font.BOLD,50));
   dbg.drawString("Player 2 Wins!", screenWidth/2 - 161, screenHeight/2);
   setGameOver(true);
   return true;
  }

  return false;
 }

 private void updateGame(){
  ball.move(screenWidth,screenHeight,player1,player2);
  player1.aiForPadel(screenWidth, screenHeight, ball.getX(), ball.getY());
  player2.aiForPadel(screenWidth, screenHeight, ball.getX(), ball.getY());

 }

  @Override
  public void paintComponents(Graphics g) {
  super.paintComponents(g);
  dbg.setColor(Color.BLACK);
  dbg.fillRect(0, 0, screenWidth+20, screenHeight+20);
  dbg.setColor(Color.WHITE);
  dbg.drawLine(screenWidth/2, 0, screenWidth/2, screenHeight);
  dbg.setFont(new Font("serif",Font.BOLD,32));
  dbg.drawString(player1.getScore()+"", screenWidth/2-40, screenHeight - 20);
  dbg.drawString(player2.getScore()+"", screenWidth/2+20, screenHeight - 20);
  ball.drawBall(dbg);
    player1.drawPadel(dbg);
    player2.drawPadel(dbg);
 }
}
解决方案

There's a really good tutorial here which describes how to use BufferStrategy to produce non-flickering animation.

The important points are:

  • Call setIgnoreRepaint(true) on the top-level Canvas to prevent AWT from repainting it, as you'll typically be doing this yourself within the animation loop.
  • Obtain the Graphics2D object from the BufferStrategy (rather than using the instance passed in via paintComponent(Graphics g).

这篇关于Java的面板双缓冲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 12:01