JavaFx 实时刷新

之前想用JavaFx Canvas写个小游戏,在网上找实时刷新的方式。找到用Platform.runLater把渲染插入到JavaFx 图形线程的方法,不过他却用了Thread的sleep函数。我觉得不好,改用了信号量。

我首先定义了一个接口,便于把操作留给使用者自己定义(说白了就是我不想写太多的演示代码):

public interface Updatable {
    void update(double moment);
}

接着就是实时刷新的类:

import javafx.application.Platform;
import java.util.concurrent.Semaphore;

public class Advancer {
    private boolean able;
    private Updatable worker;

    public Advancer(Updatable worker){
        able = false;
        this.worker = worker;
    }

    public final synchronized void advance(Updatable renderer){
        if(able)return;//防止启动多个线程
        able = true;
        new Thread(()->{
            long timer = System.nanoTime();
            Semaphore semaphore = new Semaphore(1);
            while(able)try{
                //计算瞬间时间
                long now = System.nanoTime();
                double moment = (now - timer) * 0.000000001;
                timer = now;
                //处理事务
                worker.update(moment);
                semaphore.acquire();
                Platform.runLater(()->{
                    renderer.update(moment);
                    semaphore.release();
                });
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    //记得熄火,不过线程不会马上退出。
    public final void misfire(){
        able = false;
    }
}

注意:

worker 执行后台每帧的刷新,renderer执行图形界面的刷新。

分析

其实就是启用一个线程,该线程循环地执行:

1.用nanoTime算出每帧的用时。

2.调用worker,并查看信号量。

3.如果信号量已被释放,那么通过Platform.runLater把renderer传递给JavaFx图形线程(执行完renderer后会释放信号量)。

4.回到第1步。

这个过程后台线程起主导作用,并且在把渲染任务交给图形线程后自己可以处理下一帧(即,图形处理当前帧,后台处理下一帧,这个过程可以并行,所以要注意)。

最后那个misfire只是改变了able,让线程自己退出。用完记得熄火。

注意把JavaFx与图形相关的操作放在renderer里。

并且2个线程如果有数据共享需要格外注意。

转载于:https://my.oschina.net/chaosannals/blog/672993

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值