更新是架构里面非常重要的一部分,必须要深入了解透彻才可以。
先放上Unity的更新神图。
上面的图是Unity的更新,其掩盖了一般游戏的更新逻辑,下面放上一个游戏MainLoop的一般逻辑。
http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/
总体来说归结到以下几个部分。
一个最简单的更新
public abstract class GameLoop
{
private boolean runFlag = false;
public void run()
{
runFlag = true;
startup();
while(runFlag)
{
update();
draw();
}
shutdown();
}
public void stop()
{
runFlag = false;
}
public abstract void startup();
public abstract void shutdown();
public abstract void update();
public abstract void draw();
}
限制帧率的更新
public abstract class GameLoop
{
private boolean runFlag = false;
/**
* Begin the game loop
* @param delta time between logic updates (in seconds)
*/
public void run(double delta)
{
runFlag = true;
startup();
// convert the time to seconds
double nextTime = (double)System.nanoTime() / 1000000000.0;
while(runFlag)
{
// convert the time to seconds
double currTime = (double)System.nanoTime() / 1000000000.0;
if(currTime >= nextTime)
{
// assign the time for the next update
nextTime += delta;
update();
draw();
}
else
{
// calculate the time to sleep
int sleepTime = (int)(1000.0 * (nextTime - currTime));
// sanity check
if(sleepTime > 0)
{
// sleep until the next update
try
{
Thread.sleep(sleepTime);
}
catch(InterruptedException e)
{
// do nothing
}
}
}
}
shutdown();
}
public void stop()
{
runFlag = false;
}
public abstract void startup();
public abstract void shutdown();
public abstract void update();
public abstract void draw();
}
高级一些的更新
更加复杂的更新
public abstract class GameLoop
{
private boolean runFlag = false;
/**
* Begin the game loop
* @param delta time between logic updates (in seconds)
*/
public void run(double delta)
{
runFlag = true;
startup();
// convert the time to seconds
double nextTime = (double)System.nanoTime() / 1000000000.0;
double maxTimeDiff = 0.5;
int skippedFrames = 1;
int maxSkippedFrames = 5;
while(runFlag)
{
// convert the time to seconds
double currTime = (double)System.nanoTime() / 1000000000.0;
if((currTime - nextTime) > maxTimeDiff) nextTime = currTime;
if(currTime >= nextTime)
{
// assign the time for the next update
nextTime += delta;
update();
if((currTime < nextTime) || (skippedFrames > maxSkippedFrames))
{
draw();
skippedFrames = 1;
}
else
{
skippedFrames++;
}
}
else
{
// calculate the time to sleep
int sleepTime = (int)(1000.0 * (nextTime - currTime));
// sanity check
if(sleepTime > 0)
{
// sleep until the next update
try
{
Thread.sleep(sleepTime);
}
catch(InterruptedException e)
{
// do nothing
}
}
}
}
shutdown();
}
public void stop()
{
runFlag = false;
}
public abstract void startup();
public abstract void shutdown();
public abstract void update();
public abstract void draw();
}
基本上上面的更新能应付很多问题了。