跳转至

简单的游戏循环

简单的游戏循环

更新日期:2021-01-11


游戏循环分为世界循环和绘制循环。

其中,世界循环需要按照固定频率来重复执行,以模拟现实世界的时间流失。 而绘制循环则按照固定间隔执行,以保证游戏画面及时被刷新。

这两种模式正好Java中的定时器类都已经实现了。来看一看示例代码:

示例代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import java.util.Timer;
import java.util.TimerTask;

public class App {

    private static long lastUpdateTime = System.nanoTime();
    private static long lastDrawTime = System.nanoTime();

    public static void main(String[] args) {
        // 创建一个固定频度执行的定时器来更新世界(每秒更新50次)
        new Timer().scheduleAtFixedRate(new MyUpdateTask(), 0, 1000 / 50);
        // 创建一个固定间隔执行的定时器来绘制世界(60Fps)
        new Timer().schedule(new MyDrawTask(), 0, 1000 / 60);
    }

    // 更新世界
    private static void updateWorld() {
        // 输出执行间隔
        long time = System.nanoTime() - lastUpdateTime;
        lastUpdateTime = System.nanoTime();
        System.out.println("更新世界执行间隔 : " + (double)time / 1000 / 1000);

        doSomeThing();
    }

    // 绘制世界
    private static void drawWorld() {
        // 输出执行间隔
        long time = System.nanoTime() - lastDrawTime;
        lastDrawTime = System.nanoTime();
        System.out.println("绘制世界执行间隔 : " + (double)time / 1000 / 1000);

        doSomeThing();
    }

    // 执行一些耗时任务
    private static void doSomeThing() {
        int cnt = (int)(Math.random() * 90000);
        while(cnt > 0) {
            cnt--;
            for (int i = 0; i < cnt; i++) {
                int[] data = new int[4];
            }
        }
    }

    // 更新世界定时任务
    private static class MyUpdateTask extends TimerTask {
        @Override
        public void run() {
            try {
                updateWorld();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 绘制世界定时任务
    private static class MyDrawTask extends TimerTask {
        @Override
        public void run() {
            try {
                drawWorld();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

从输出结果来看,运行的还是很平稳的。