首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

五-The Game Loop

2013-11-08 
5-The Game Loopmoving th image 跟display差不多,也不翻译了游戏循环式每个游戏的心跳。我们用过一次非常

5-The Game Loop

moving th image 跟display差不多,也不翻译了

游戏循环式每个游戏的心跳。我们用过一次非常基础的,它没有控制游戏状态速度的更新,也没有控制哪些帧要渲染。简单的说,大部分的游戏循环都是在循环里面执行一些指令,知道我们发信号通知结束,通常是设置running为false

1 boolean running = true;  2 while (!running)  3 {  4    updateGameState();  5    displayGameState();  6 } 

上面的代码完全没有关注时间和资源。如果是快的设备,它会运行的很快,如果设备很慢,运行的也会很慢

有两个指标是我们必须要关注的 FPS和UPS

FPS 帧每秒 ---displayGameState每秒被调用的次数

UPS 更新每秒 updateGameState每秒被调用的次数

理想情况下 update和render方法每秒被调用的次数英爱是相当的,每秒不少于20-25帧。25帧对于手机来说已经够用了,通常就不会感觉到动画的迟钝了

比如 如果我们目标是25帧,那么意味着我们要每40m调用一次displayGameState方法。我们要知道updateGameState方法是在display方法之前调用的,为了达到25帧,我们必须要保证update-display序列的执行时间是40ms,如果小于40ms,那么FPS会高一点,否则会慢一点

为了更好理解,看几个例子

下面的图示 正好是1FPS,update-render 正好用了1秒来执行。这就意味着我们一秒就会看到一次更新屏幕

五-The Game Loop

五-The Game Loop

五-The Game Loop

五-The Game Loop

五-The Game Loop

01 // desired fps 02 private final static int MAX_FPS = 50; 03 // maximum number of frames to be skipped 04 private final static int MAX_FRAME_SKIPS = 5; 05 // the frame period 06 private final static int FRAME_PERIOD = 1000 / MAX_FPS; 07 @Override 08 public void run() { 09 Canvas canvas; 10 Log.d(TAG, "Starting game loop"); 11 long beginTime; // the time when the cycle begun 12 long timeDiff; // the time it took for the cycle to execute 13 int sleepTime; // ms to sleep (<0 if we're behind) 14 int framesSkipped; // number of frames being skipped 15 sleepTime = 0; 16 while (running) { 17 canvas = null; 18 // try locking the canvas for exclusive pixel editing 19 // in the surface 20 try { 21 canvas = this.surfaceHolder.lockCanvas(); 22 synchronized (surfaceHolder) { 23 beginTime = System.currentTimeMillis(); 24 framesSkipped = 0; // resetting the frames skipped 25 // update game state 26 this.gamePanel.update(); 27 // render state to the screen 28 // draws the canvas on the panel 29 this.gamePanel.render(canvas); 30 // calculate how long did the cycle take 31 timeDiff = System.currentTimeMillis() - beginTime; 32 // calculate sleep time 33 sleepTime = (int)(FRAME_PERIOD - timeDiff); 34 if (sleepTime > 0) { 35 // if sleepTime > 0 we're OK 36 try { 37 // send the thread to sleep for a short period 38 // very useful for battery saving 39 Thread.sleep(sleepTime); 40 } catch (InterruptedException e) {} 41 } 42 while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) { 43 // we need to catch up 44 // update without rendering 45 this.gamePanel.update(); 46 // add frame period to check if in next frame 47 sleepTime += FRAME_PERIOD; 48 framesSkipped++; 49 } 50 } 51 } finally { 52 // in case of an exception the surface is not left in 53 // an inconsistent state 54 if (canvas != null) { 55 surfaceHolder.unlockCanvasAndPost(canvas); 56 } 57 } // end finally 58 } 59 }

看一下上面的code,它对应图形中的逻辑

还有另外一种方法,最大帧率的不变游戏速率,它 用插值法来画状态,在快速的硬件上被使用,它可以加强游戏效果,使动画更平滑,因为我们是移动设备,给CPU一点休息,还是可以省不少电的

热点排行