本文介绍了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-levelCanvas
to prevent AWT from repainting it, as you'll typically be doing this yourself within the animation loop. - Obtain the
Graphics2D
object from theBufferStrategy
(rather than using the instance passed in viapaintComponent(Graphics g)
.
这篇关于Java的面板双缓冲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!