如何完全消除动画闪烁

时间:2019-07-04 06:22:37

标签: java swing animation awt flicker

我无法完全消除动画闪烁。我该怎么办?

我正在使用画布和游戏引擎模型进行动画制作。 尽管我使用缓冲策略,但仍有闪烁现象。另外,“文本”正在平滑滚动,另一方面,某些原因导致闪烁,这是我所不了解的。您能帮助理解问题吗?

这是下面的代码:

public class MyCanvas extends Canvas implements Runnable {

private boolean running;
private static Point pt=null;
String LowLineContentStr = "How to eliminate animation flickering";
Color color=new Color(255,255,255);
Font font=new Font("Agency FB",Font.PLAIN,70);
private static JFrame frame = null;
private static int WIDTH;
private static int HEIGHT;
BufferStrategy bs = null;

private synchronized void start() {
    if(running) return;

    running = true;
    new Thread(this).start();

}

private synchronized void stop() {
    if(!running) return;

    running = false;

}


private void draw(Graphics g) {
    drawString(g);
}


private void drawString(Graphics g) {

    Graphics2D g2d = (Graphics2D) g;

    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g2d.setFont(font);
    g2d.setColor(color);
    g2d.drawString(LowLineContentStr, pt.x,pt.y);
}

private void render() {
    bs = getBufferStrategy();
    if(bs == null) {
        createBufferStrategy(2);
        return;
    }

    do {
        do {
            Graphics g = bs.getDrawGraphics();

            g.clearRect(0, 0, WIDTH, HEIGHT);

            draw(g);

            Toolkit.getDefaultToolkit().sync();

            g.dispose();
        }while(bs.contentsRestored());
        bs.show();
    }while(bs.contentsLost());
}

private void updateData() {

    pt.x-= 3;

    if(pt.x<-2250) {
        pt.x=WIDTH;
    }

}

@Override
public void run() {

    requestFocus();

    double target = 60.0;
    double nsPerTick = 1000000000.0 / target;
    long lastTime = System.nanoTime();
    long timer = System.currentTimeMillis();
    double unprocessed = 0.0;
    int fps = 0, tps = 0;
    boolean canRender = false;
    long timeDiffer = 0;
    long tempTimeDiff = 0;
    while(running) {
        long now = System.nanoTime();
        unprocessed += (now - lastTime) / nsPerTick;
        lastTime = now;
        timeDiffer = now - lastTime;
        if(unprocessed >= 1.0) {

            updateData();
            tps++;
            unprocessed--;
            canRender = true;
        }else {
            canRender = false;
        }


        if(canRender) {
            render();
            fps++;
        }

        if(System.currentTimeMillis() - 1000 > timer) {
            timer+=1000;
            System.out.println("FPS : "+fps+" TPS : "+tps);
            fps = 0;
            tps = 0;
        }


        if(tempTimeDiff != timeDiffer) {

            try {
                Thread.sleep(Math.abs(timeDiffer - tempTimeDiff));
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        tempTimeDiff = timeDiffer;


    }
    stop();

}

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {


            Color color=new Color(29, 36, 48);
            MyCanvas canvas = new MyCanvas();
            frame = new JFrame();

            frame.add(canvas);

            //Get Screen Size
            GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
            int widthScreenDevice = gd.getDisplayMode().getWidth();
            int heightScreenDevice = gd.getDisplayMode().getHeight();

            frame.setSize(new Dimension(widthScreenDevice, heightScreenDevice));
            frame.setPreferredSize(new Dimension(widthScreenDevice, heightScreenDevice));
            frame.setMaximumSize(new Dimension(widthScreenDevice, heightScreenDevice));
            frame.setMinimumSize(new Dimension(widthScreenDevice-10, heightScreenDevice-10));

            canvas.setSize(new Dimension(widthScreenDevice, heightScreenDevice));
            canvas.setPreferredSize(new Dimension(widthScreenDevice, heightScreenDevice));
            canvas.setMaximumSize(new Dimension(widthScreenDevice, heightScreenDevice));
            canvas.setMinimumSize(new Dimension(widthScreenDevice-10, heightScreenDevice-10));

            frame.getContentPane().setBackground(color);

            frame.setUndecorated(true);
            frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            frame.setResizable(false);
            frame.setVisible(true);

            WIDTH = widthScreenDevice;
            HEIGHT = heightScreenDevice;

            pt = new Point(WIDTH, 0);
            pt.y = HEIGHT - 100;

            canvas.start();
        }
    });  

}
}

我计划这些代码在debian OS上运行。我需要最低的硬件要求才能完美地运行这些代码。

0 个答案:

没有答案