Java 三缓冲区重闪烁

Java 三缓冲区重闪烁,java,swing,awt,buffer,bufferstrategy,Java,Swing,Awt,Buffer,Bufferstrategy,三重缓冲和画布不应该是被动渲染的最佳解决方案吗?我刚刚编写了这个显示圆圈的java代码。如果我把bufferstrategy设置为3,它会闪烁很多。如果我把它调低到2或1就可以了。也许我做错了什么 public void run(){ while (running){ update(); draw(); } } public void update(){ } public void draw(){ Buffe

三重缓冲和画布不应该是被动渲染的最佳解决方案吗?我刚刚编写了这个显示圆圈的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();
 }
这是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();

}

}
试试这个:

myPanel
类中创建一个
buffereImage
,如下所示:

private BufferedImage image=新的BufferedImage(宽度、高度、BufferedImage.TYPE_INT_RGB)

现在,在绘制方法中,将该图像绘制在所有其他图像之上,如下所示:


这将在屏幕上绘制黑色背景,使其不再闪烁。现在你可以在那张图片上画任何东西了。

有两样东西向我扑来

  • 您的“循环”正在运行,没有任何延迟。这意味着屏幕将被更新尽可能多的次数,这可能是硬件要跟上的。一般来说,您希望以25fps左右为目标,这有助于提供平稳运动的错觉
  • 您没有准备用于绘制的
    图形。每次从
    BufferStrategy
    中获取
    图形
    上下文时,实际上就是在获取最后使用的上下文。这意味着,所有被画的东西都是静止的。你得把这个清理干净。闪烁(可能)是由于一个
    图形
    上下文已经填充了颜色,而其他上下文则没有
  • 下面是一个非常基本的示例,包括一点动画

    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();
            }
        }
    }
    
    导入java.awt.Canvas;
    导入java.awt.Color;
    导入java.awt.Dimension;
    导入java.awt.Graphics;
    导入java.awt.image.BufferStrategy;
    导入javax.swing.JFrame;
    公共类双缓冲区{
    公共静态void main(字符串[]args){
    Pan游戏=新Pan();
    JFrame=新JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setresizeable(true);
    frame.add(游戏);
    frame.pack();
    frame.setLocationRelativeTo(空);
    frame.setVisible(true);
    game.start();
    }
    公共静态类Pan扩展Canvas实现Runnable{
    私有int xDelta=2;
    私有整数x=0;
    私人智力y=20;
    公共Pan(){
    }
    公开作废开始(){
    新线程(this.start();
    }
    公开募捐{
    while(true){
    更新();
    试一试{
    睡眠(40);
    }捕获(中断异常例外){
    }
    draw();
    }
    }
    @凌驾
    公共维度getPreferredSize(){
    返回新维度(200200);
    }
    公共无效更新(){
    x+=xDelta;
    如果(x+20>getWidth()){
    x=getWidth()-20;
    xDelta*=-1;
    }else如果(x<0){
    x=0;
    xDelta*=-1;
    }
    }
    公众抽签(){
    BufferStrategy bs=getBufferStrategy();
    如果(bs==null){
    创新战略(3);
    返回;
    }
    Graphics g=bs.getDrawGraphics();
    g、 setColor(Color.RED);
    g、 fillRect(0,0,getWidth(),getHeight());
    g、 设置颜色(颜色为黑色);
    g、 椭圆形(x,y,20,20);
    g、 处置();
    b.show();
    }
    }
    }
    
    完美答案。谢谢。我会小心混合重的和轻的成分
    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();
            }
        }
    }