不应该将三重缓冲和Canvas作为被动渲染的最佳解决方案吗?我刚刚写了这个显示圆圈的java代码。如果我将bufferstrategy留给3,它就会闪烁太多。如果我把它调低到2或1就可以了。也许我做错了什么?
public void run(){
while (running){
update();
draw();
}
}
public void update(){
}
public void draw(){
BufferStrategy bs = getBufferStrategy();
if (bs==null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillOval(30, 30, 20, 20);
g.dispose();
bs.show();
}
这是我放置Canvas
的JFrame类public class Game {
public static void main (String [] args){
Pan game = new Pan();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.add(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
}
答案 0 :(得分:2)
有两件事情发生在我身上。
Graphics
。每次从Graphics
获得BufferStrategy
上下文时,您实际上都会获得最后使用的内容。这意味着,绘制的所有内容仍然是。在那里你需要清理它。闪烁(可能)来自这样一个事实:Graphics
个上下文中的一个已经填充了颜色,而其他情况则没有。以下是一个非常基本的例子,包括一些动画
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class DoubleBuffer {
public static void main(String[] args) {
Pan game = new Pan();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.add(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
public static class Pan extends Canvas implements Runnable {
private int xDelta = 2;
private int x = 0;
private int y = 20;
public Pan() {
}
public void start() {
new Thread(this).start();
}
public void run() {
while (true) {
update();
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
draw();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void update() {
x += xDelta;
if (x + 20 > getWidth()) {
x = getWidth() - 20;
xDelta *= -1;
} else if (x < 0) {
x = 0;
xDelta *= -1;
}
}
public void draw() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
g.fillOval(x, y, 20, 20);
g.dispose();
bs.show();
}
}
}
答案 1 :(得分:1)
试试这个:
在BufferedImage
课程中设置myPanel
,如下所示:
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
现在将此图像绘制在绘图方法中的其他所有内容上,如下所示:
public void draw(){
BufferStrategy bs = getBufferStrategy();
if (bs== null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
// Draw your other stuff after this...
g.fillOval(20, 20, 20, 20);
g.dispose();
bs.show();
}
public void draw(){
BufferStrategy bs = getBufferStrategy();
if (bs== null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
// Draw your other stuff after this...
g.fillOval(20, 20, 20, 20);
g.dispose();
bs.show();
}
这将在屏幕上绘制黑色背景,使其不再闪烁。现在,您可以在该图像上绘制任何内容。