游戏设计模式 游戏循环

游戏循环

游戏循环在游戏开发中至关重要,虽然说有游戏引擎,或者一些列框架下无需让我们自己亲手写,但是还是有必要了解一下游戏中的循环,譬如某天你用安卓的surfaceview,去写游戏,又话说直接从openGL底层开始写起,那游戏循环的设计就必不可少了。

设计一个简单的游戏循环
while(true)
{
    double start = getCurrentTime();
    processInput();
    update();
    render();

    sleep(start + MS_PER_FRAME - getCurrentTime());
}

这里使用sleep 能保证在性能比较好的机器上,不会太快的再短时间内运行太多帧,可是对于机器性能比较差的却毫无用处

修改一下,加上detaltime的时间
double lastTime = getCurrentTime();
while(true)
{
    double current = getCurrentTime();
    double detalTime = current - lastTime;
    processInput();
    update(detalTime);
    render();
    lastTime = current;
}

这样,在update的时候,每个物体都能知道实际过了多长时间,例如 5m/s 我就可以 pos.x += 5 * detalTime 保证了在不同机子上,人物的移动速度再游戏世界里面是一样的,而与你的机器性能无关,可是在机器比较差的机子上,还会容易出现一种问题,通常,例如物理碰撞通常是在update里面进行检测的,但是如果机器的性能特别差,detalTime特别大,就会有可能出现穿透的现象,好比这样说, a b c, b 是障碍物宽1m 在 a 和 b 中间,a c距离 10m ,按5/m 的速度 按照正常机子每帧 0.02s 也就是 每帧滑动 0.1的距离应该是可以检测出与物体b碰撞的,但是机器差的机子 detaltime = 0.5s 过大 在移动到4m的时候,下一帧就6.5m了,,就有可能造成穿透的现象.也就是无法检测到物理碰撞~~,这里说得太渣。。自己模拟.

把时间追回来

渲染,通常是游戏引擎中不会受变时步长影响的部分。由于渲染引擎表现的是游戏时间中的一瞬间,所以它并不关心距离上次渲染过去了多久,它只是把当前的游戏状态渲染出来而已。所以我们使用的是固定时长的更新,它像这样运作 : 距离上次的游戏循环已经过去了一段真实的时间,这一段时间就是我们需要时模拟游戏的 “当前时间”,以便赶上玩家的实际时间。

double previous = getCurrentTime();
double lag = 0.0;
while(true)
{
    double current = getCurrentTime();
    double detalTime = current - previous;
    previous = current;
    lag+= detalTime;
    processInput();

    while(lag >= MS_PER_FRAME)
    {
        update();
        lag -= MS_PER_FRAME;
    }
    render();
}

这样,我们便可以在 过慢的机器上,重新模拟快进过去的时间。

参考书籍 《游戏设计模式》 Robert Nystorm 著

你可能感兴趣的:(设计模式)