使用MIDP2.0开发游戏 (7) 设计Scheduler

原创 2004年09月20日 22:39:00

Scheduler负责以固定的频率执行每一帧,所需的时钟由Clock提供,Scheduler还可以计算每帧所需时间和CPU占用率,以便可能的话动态调整任务。

以下的Scheduler的实现参考自Marshall "Game Programming Gems 3"中的C++代码:

package game.engine.core;

public class Scheduler {

    // clock:
    private Clock clock = new Clock();
    
    // 启动Scheduler:
    public void start() {
        clock.start();
    }

    // 停止Scheduler:
    public void stop() {
        clock.stop();
    }

    public int getSystemTime() {
        return clock.getSystemTime();
    }

    public int getVirtualTime() {
        return clock.getVirtualTime();
    }

    // 执行完整的一帧:
    public void executeFrame() {
        System.out.println("-- start execute frame --");
        clock.beginFrame();
        int started = clock.getSystemTime();
        // do time task:
        System.out.println("doing time tasks...");
        try {
            Thread.sleep(500);
        }catch(InterruptedException ie) {}
        clock.advanceToEnd();
        // do frame task:
        System.out.println("doing frame tasks...");
        try {
            Thread.sleep(200);
        }catch(InterruptedException ie) {}
        // do render task:
        int end = clock.getSystemTime();
        int elapsed = end - started;
        int frameLength = clock.getFrameEnd() - clock.getFrameStart();
        System.out.println("elapsed: " + elapsed + ", frame: " + frameLength);
        System.out.println("cpu usage: " + (elapsed * 100 / frameLength) + "%");
        // cleanup:
        System.out.println("-- end execute frame --/n");
    }

    public void waitUntil(int time) {
        try {
            while(clock.getSystemTime()                Thread.sleep(1);
            }
        }catch(InterruptedException ie) {}
    }

    public static void main(String[] args) {
        Scheduler scheduler = new Scheduler();
        scheduler.start();
        int time = 1000;
        do {
            scheduler.waitUntil(time);
            time += 1000;
            scheduler.executeFrame();
        } while(scheduler.getSystemTime()<10000);
    }

}

我们还没有真正的任务要执行,所以只好用两个Thread.sleep()来表示执行任务,分别是500ms和200ms,在main()方法中每1s执行一次executeFrame()方法,可以看到如下输出:

-- start execute frame --
[beginFrame] virtual time = 0, systemTime = 1002
doing time tasks...
[advanceToEnd] virtual time = 992
doing frame tasks...
elapsed: 701, frame: 992
cpu usage: 70%
-- end execute frame --

-- start execute frame --
[beginFrame] virtual time = 992, systemTime = 2003
doing time tasks...
[advanceToEnd] virtual time = 1993
doing frame tasks...
elapsed: 701, frame: 1001
cpu usage: 70%
-- end execute frame --
...

CPU使用率是70%,如果把任务时间延长大于1s,比如700ms和500ms,虚拟时间就变慢,因为CPU不能在1s内处理完任务,输出的CPU使用率100%(除了第一次计算):

-- start execute frame --
[beginFrame] virtual time = 0, systemTime = 1002
doing time tasks...
[advanceToEnd] virtual time = 992
doing frame tasks...
elapsed: 1201, frame: 992
cpu usage: 121%
-- end execute frame --

-- start execute frame --
[beginFrame] virtual time = 992, systemTime = 2203
doing time tasks...
[advanceToEnd] virtual time = 2193
doing frame tasks...
elapsed: 1202, frame: 1201
cpu usage: 100%
-- end execute frame --

-- start execute frame --
[beginFrame] virtual time = 2193, systemTime = 3415
doing time tasks...
[advanceToEnd] virtual time = 3405
doing frame tasks...
elapsed: 1202, frame: 1212
cpu usage: 99%
-- end execute frame --
...

有一些微小的误差,因为调度器自身的代码也会占用一点时间,并且currentTimeMillies()只能精确到毫秒级,不过用户是感觉不出来的,只有当CPU使用达100%时,游戏才会变慢。

待续...

使用MIDP2.0开发游戏(7)设计Scheduler

文章来源:J2ME开发网Scheduler负责以固定的频率执行每一帧,所需的时钟由Clock提供,Scheduler还可以计算每帧所需时间和CPU占用率,以便可能的话动态调整任务。以下的Schedul...
  • mobilechannel
  • mobilechannel
  • 2005年11月29日 16:32
  • 639

使用MIDP2.0开发游戏 (6) 设计Clock

Clock负责提供一个真实时间和一个虚拟时间,真实时间从0开始按ms递增,和硬件时钟是同步的;虚拟时间也从0开始按ms递增,但不一定和真实时间同步。要获得系统时间可以用System.currentTi...
  • asklxf
  • asklxf
  • 2004年09月19日 15:56
  • 3196

使用MIDP2.0开发游戏

http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=20177&threadID=27237&tstart=60
  • zypsg
  • zypsg
  • 2005年11月25日 21:14
  • 1258

使用MIDP2.0开发游戏(6)设计Clock

文章来源:J2ME开发网Clock负责提供一个真实时间和一个虚拟时间,真实时间从0开始按ms递增,和硬件时钟是同步的;虚拟时间也从0开始按ms递增,但不一定和真实时间同步。要获得系统时间可以用Syst...
  • mobilechannel
  • mobilechannel
  • 2005年11月29日 16:12
  • 642

使用MIDP2.0开发游戏 (5) 游戏内核

我们准备开始设计游戏内核。通常,游戏和桌面Windows程序不同(扫雷等桌面游戏除外),它不能依赖消息驱动,因为游戏通常只有一个画面,而且需要高速更新。因此,游戏只能靠时钟驱动。大部分游戏都在一个时钟...
  • asklxf
  • asklxf
  • 2004年09月18日 23:24
  • 3228

使用MIDP2.0开发游戏(5)游戏内核

文章来源:J2ME开发网我们准备开始设计游戏内核。通常,游戏和桌面Windows程序不同(扫雷等桌面游戏除外),它不能依赖消息驱动,因为游戏通常只有一个画面,而且需要高速更新。因此,游戏只能靠时钟驱动...
  • mobilechannel
  • mobilechannel
  • 2005年11月29日 16:11
  • 638

使用MIDP2.0开发游戏 (2) 使用Sprite

Sprite,精灵,顾名思义,专用来代表游戏中的动画角色,比如飞机,坦克等等。在MIDP1.0中,我们必须自己写专门的类来实现Sprite,幸运的是,MIDP2.0为Sprite提供了强力支持,可以创...
  • shiyonggang
  • shiyonggang
  • 2004年08月29日 18:29
  • 740

使用MIDP2.0开发游戏 (2) 使用Sprite

Sprite,精灵,顾名思义,专用来代表游戏中的动画角色,比如飞机,坦克等等。在MIDP1.0中,我们必须自己写专门的类来实现Sprite,幸运的是,MIDP2.0为Sprite提供了强力支持,可以创...
  • asklxf
  • asklxf
  • 2004年08月27日 19:38
  • 7974

使用MIDP2.0开发游戏(2)使用Sprite

文章来源:J2ME开发网Sprite,精灵,顾名思义,专用来代表游戏中的动画角色,比如飞机,坦克等等。在MIDP1.0中,我们必须自己写专门的类来实现Sprite,幸运的是,MIDP2.0为Sprit...
  • mobilechannel
  • mobilechannel
  • 2005年11月29日 16:07
  • 608

使用MIDP2.0开发游戏(1)GameCanvas基础

文章来源:J2ME开发网MIDP2.0提供了对游戏的强有力支持,通过javax.microedition.lcdui.game包,原来在MIDP1.0中很多需要自己写的功能现在都被当作标准API实现了...
  • mobilechannel
  • mobilechannel
  • 2005年11月29日 16:06
  • 717
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用MIDP2.0开发游戏 (7) 设计Scheduler
举报原因:
原因补充:

(最多只允许输入30个字)