我尝试遵循双缓冲教程,但我真的不知道我做错了什么。在我完成教程之前它就可以工作,但仍然偶尔会出现闪烁。我有两个文件 Game 和 gameLoop
游戏:
import java.awt.Graphics;
public class Game extends gameLoop
{
public void init()
{
setSize(854,480);
Thread th = new Thread(this);
th.start();
offscreen = createImage(854,480);
d = offscreen.getGraphics();
}
public void paint(Graphics g)
{
d.clearRect(0, 0, 854, 480);
d.drawImage(disk, x, y, this);
g.drawImage(offscreen , 0, 0, this);
}
public void Update(Graphics gfx)
{
paint(gfx);
}
}
游戏循环
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class gameLoop extends Applet implements Runnable, MouseListener, MouseMotionListener
{
public int x, y, counter, mouseX, mouseY;
public Image offscreen;
public Graphics d;
public boolean up, down, left, right, pressed;
public BufferedImage disk1, disk2, disk3, disk4, disk;
public int ballSpeedX = -6;
public int ballSpeedY = -3;
public void run()
{
x = 400;
y = 200;
try {
disk1 = ImageIO.read(new File("disk1.png"));
disk2 = ImageIO.read(new File("disk2.png"));
disk3 = ImageIO.read(new File("disk3.png"));
disk4 = ImageIO.read(new File("disk4.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
while(true)
{
if(x >= (854 - 150))
{
ballSpeedX = ballSpeedX * -1;
}
if(y >= (480 - 140))
{
ballSpeedY = ballSpeedY * -1;
}
if(y < (0 - 10))
{
ballSpeedY = ballSpeedY * -1;
}
if(x < (0- 10))
{
ballSpeedX = ballSpeedX * -1;
}
x = x + ballSpeedX;
y = y + ballSpeedY;
counter ++;
if(counter >= 4)
counter = 0;
if(counter == 0)
disk = disk1;
if(counter == 1)
disk = disk2;
if(counter == 2)
disk = disk3;
if(counter == 3)
disk = disk4;
System.out.println(counter);
repaint();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseMoved(MouseEvent m) {}
public void mousePressed(MouseEvent m)
{
}
public void mouseReleased(MouseEvent m)
{
pressed = false;
}
public void mouseDragged(MouseEvent e) {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
mouseX = (int)b.getX();
mouseY = (int)b.getY();
ballSpeedX = mouseX;
ballSpeedY = mouseY;
}
}
最佳答案
public void Update(Graphics gfx)
{
paint(gfx);
}
应为小写,因为您尝试重写 Applet 中的 update(Graphics g)
方法。
应该是这样
@Override
public void update(Graphics gfx)
{
paint(gfx);
}
至于更改背景,背景只是一个覆盖屏幕并使其具有某种颜色的大矩形。在 paint
中,您正在执行 clearRect
,这会清除屏幕。相反,只需在设置颜色后将其切换为 fillRect
即可。
它可能看起来像
public void paint(Graphics g)
{
//setColor to whatever you want
//fillRect to cover the screen
}
当你这样做时,你必须记住的一件事是不要混淆你的两个图形对象。作为一个概念,双缓冲的工作原理是首先绘制到内存(将其绘制在屏幕外图像上),然后绘制到屏幕。您希望始终在该屏幕外图像上进行绘制,因为它的速度要快得多(并且我们不会出现闪烁)。
因此,请确保您执行的是 imageGraphicsObject.setColor
而不是 screenGraphicsObject.setColor
或 imageGraphicsObject.fillRect而不是
screenGraphicsObject.fillRect`。否则你就不再是双缓冲了。
关于java - 如何修复不良的双缓冲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15891698/