【问题标题】:FPS Cap Still Causes FlickerFPS 上限仍会导致闪烁
【发布时间】:2012-01-29 11:30:34
【问题描述】:

我正在使用将 FPS 上限设置为 60 fps。我已经对其进行了测试,并且可以正常工作。问题是它仍然会导致屏幕闪烁。我的显示器设置为 60 fps。我不知道它是如何导致闪烁的。这是我的代码:

package com.bgp.chucknorris;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.net.URL;

public class ChuckNorrisApplet extends Applet implements Runnable {
    private static final long serialVersionUID = 1L;
    Thread thread = null;
    Image title;
    URL base;
    MediaTracker mt;
    String fps = "";

    public void init() {
        thread = new Thread(this);
        thread.start();

        mt = new MediaTracker(this);
        base = getDocumentBase();
        title = getImage(base, "title.png");
        mt.addImage(title, 1);
        try {
            mt.waitForAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public void paint(Graphics g) {
        g.drawImage(title, 0, 0, null);
    }

    public void start() {
        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    public void stop() {
        thread = null;
    }

    public void run() {
        int frames = 0;

        double unprocessedSeconds = 0;
        long lastTime = System.nanoTime();
        double secondsPerTick = 1 / 60.0;
        int tickCount = 0;

        requestFocus();

        while (true) {
            long now = System.nanoTime();
            long passedTime = now - lastTime;
            lastTime = now;
            if (passedTime < 0)
                passedTime = 0;
            if (passedTime > 100000000)
                passedTime = 100000000;

            unprocessedSeconds += passedTime / 1000000000.0;

            boolean ticked = false;
            while (unprocessedSeconds > secondsPerTick) {
                unprocessedSeconds -= secondsPerTick;
                ticked = true;

                tickCount++;
                if (tickCount % 60 == 0) {
                    System.out.println(frames + " fps");
                    fps = Integer.toString(frames);
                    lastTime += 1000;
                    frames = 0;
                }
            }

            if (ticked) {
                repaint();
                frames++;
            } else {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }

}

【问题讨论】:

  • 1) 为什么是Applet(而不是JApplet)? 2) 为什么是小程序而不是框架? 3) 当大多数组件实现 ImageObserver 时,不要在绘图中使用 null。
  • 哇。更改为 JApplet 有效。
  • 现在是 Swing 应该进行的其他更改。代替Thread/Runnable/sleep(),实现一个Swing Timer。将paint() 移动到JPanel 的paintComponent()。使用ImageIO 加载图像并删除MediaTracker.. 我添加了第一个建议作为答案(带有解释)。
  • 当然。不要睡在 EDT 上。使用 Swing Timer 可以避免这种情况。

标签: java animation applet flicker japplet


【解决方案1】:

为什么是Applet(而不是JApplet)?请注意,Swing 组件是双缓冲的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    相关资源
    最近更新 更多