三重缓冲重闪烁 [英] triple buffer heavy flickering

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

问题描述

不应该三重缓冲和Canvas是被动呈现最佳的解决方案?我刚刚写了这个Java code,显示一个圆圈。如果我离开BufferStrategy中为3,在闪烁这么多。如果我把它归结为2个或1这是确定。也许我做错了什么?

 公共无效的run(){    而(运行){
        更新();
        画();
    }
 }
 公共无效更新(){ }
 公共无效的draw(){
       BufferStrategy中BS = getBufferStrategy();
       如果(BS == NULL){
       createBufferStrategy(3);
       返回;
       }       图形G = bs.getDrawGraphics();
       g.setColor(Color.BLACK);
       g.fillOval(30,30,20,20);
       g.dispose();
       bs.show();
 }

这是JFrame类,我把画布

 公共类游戏{公共静态无效的主要(字串[] args){    泛游戏=新盘();
    JFrame的帧=新的JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(真);
    frame.add(游戏);
    frame.pack();
    frame.setLocationRelativeTo(NULL);
    frame.setVisible(真);
    游戏开始();}}


解决方案

两件事情我跳出来。


  1. 您循环正在运行,没有任何形式的延迟。这意味着在屏幕将多次进行更新,因为它可能可以,这可能是多为跟上硬件。一般来说,你要瞄准25fps的左右,这帮助提供平滑运动的幻觉

  2. 您不是preparing的图形绘画。每次你从一个图形上下文中的 BufferStrategy使用你实际上得到使用的最后一个。这意味着,被涂仍然一切。在那里,您需要打扫一下。闪烁是(可能)的事实,在图形上下文之一已经被填充了一种颜色,而其他还没有到来。

下面是一个非常简单的例子,包括动画的一点点

 进口java.awt.Canvas中;
进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.Graphics;
进口java.awt.image.BufferStrategy;
进口javax.swing.JFrame中;公共类DoubleBuffer {    公共静态无效的主要(字串[] args){        泛游戏=新盘();
        JFrame的帧=新的JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(真);
        frame.add(游戏);
        frame.pack();
        frame.setLocationRelativeTo(NULL);
        frame.setVisible(真);
        游戏开始();    }    公共静态类泛扩展画布实现Runnable {        私人INT xDelta = 2;
        私人INT X = 0;
        私人诠释Y = 20;        公共潘(){
        }        公共无效的start(){
            新的Thread(本)。开始();
        }        公共无效的run(){            而(真){
                更新();
                尝试{
                    视频下载(40);
                }赶上(InterruptedException的前){
                }
                画();
            }
        }        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(200,200);
        }        公共无效更新(){
            X + = xDelta;
            如果(X + 20>的getWidth()){
                X =的getWidth() - 20;
                xDelta * = -1;
            }否则如果(X℃,){
                X = 0;
                xDelta * = -1;
            }
        }        公共无效的draw(){
            BufferStrategy中BS = getBufferStrategy();
            如果(BS == NULL){
                createBufferStrategy(3);
                返回;
            }            图形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();
        }
    }
}

Shouldn't triple buffering and Canvas be an optimal solution for passive rendering? I've just wrote this java code that displays a circle. If I leave bufferstrategy to 3, it flickers so much. If I turn it down to 2 or 1 it's ok. Maybe I'm doing something wrong?

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();
 }

and this is the JFrame class where I put the Canvas

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();

}

}

解决方案

Two things jump out at me.

  1. You "loop" is running without any kind of delay. This means that the screen will be updated as many times as it possible can, this may be to much for the hardware to keep up with. Generally speaking, you want to aim for around 25fps, this help provide the illusion of smooth movement
  2. You are not preparing the Graphics for painting. Each time you get a Graphics context from the BufferStrategy you are actually getting the last that was used. This means, everything that was painted to is still. There you need to clean this up. The flickering is (possibly) coming from the fact that one of the Graphics contexts has already being filled with a color, while the others have not.

The following is a very basic example, including a little bit of animation

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();
        }
    }
}

这篇关于三重缓冲重闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆