游戏圈的速度不稳定

时间:2011-10-13 18:26:45

标签: java android opengl-es timing

我在Android上用OpenGL(-es)制作一个简单的突破游戏。最初我在同一个循环中更新了游戏的状态和绘图调用:onDrawFrame。现在我决定拆分两个,只将渲染调用留在onDrawFrame中,游戏状态在另一个线程中管理:

public void run() {
    Log.d("GameLogicThread", "GameLogicThread started");
    final long UPDATE_INTERVAL = 1000000000 / 30;
    long endingTime;
    int timeElapsed;
    long startingTime = System.nanoTime();

    while (!running) {// wait for it...

    }
    while (running) {
        endingTime = System.nanoTime();
        timeElapsed = (int) (endingTime - startingTime);
        Log.d("timeElapsed",Integer.toString(timeElapsed));
        if (timeElapsed < UPDATE_INTERVAL-timeElapsed){
            try {
                Thread.sleep(timeElapsed);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        startingTime = System.nanoTime();
        Game.updateGame(timeElapsed);
    }

EDIT
我现在已经改变了这样的代码^^,但它仍然无法正常工作..

循环中的某些东西是错误的,还是我应该向外看(可能不是,因为它在移动代码之前效果很好)。我该怎么办?

2 个答案:

答案 0 :(得分:1)

循环对我来说看起来不会受到影响。分离线程的移动肯定是一个好的,或者当帧的渲染时间太长时你会遇到严重的问题。

您是否尝试过使用nanoTime()以获得更高的准确度?

答案 1 :(得分:1)

以下评论中指出/讨论了一些逻辑错误:

    endingTime = System.currentTimeMillis();
    timeElapsed = (int) (endingTime - startingTime);
    // Why is the "elapsed" time being waited? Hmm.
    // If *any* wait is being done (I'd recommend sleep(0) for starters)
    // it should be the MAXIMUM desired cycle time MINUS the
    // currently used cycle time (MINUS some fudge factor).
    if (timeElapsed < UPDATE_INTERVAL) // I dislike hanging blocks...
        try {
            Thread.sleep(timeElapsed);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    startingTime = System.currentTimeMillis();
    // The game needs to know the TOTAL time elapsed since
    // the last update, not the time "until before the yield".
    // This will likely be passed fictitiously small values as
    // it is only time the the LAST updateGame took to run.
    Game.updateGame(timeElapsed);

我永远不会期望看到timeElapsed(传递给updateGame)下面说{10} sleep(...)和更正的时间计算。

然而,它可能没有所需的精度(增加最小循环长度,比如说1/30秒,这是固定数学的结果,会使更少重要):见Cristian Vrabie's回答有关更高分辨率计时器的建议。 (可能有一些更好的第三方替代方案专门为此设计 - 存在“普通”Java - 我不编程Android; - )

快乐的编码。