[摘抄]游戏主循环逻辑
1. 最简单的情况
1 bool game_is_running = true; 2 while(game_is_running) 3 { 4 update_game(); // 逻辑帧 5 display_game(); // 渲染帧 6 }
带来的问题:小霸王机器会跑的很慢,牛逼机器上跑得飞快,cpu达到100%。显然不是一个合适的算法。
2. 恒定帧率和恒定游戏速度
1 const int FRAMES_PER_SECOND = 25; 2 const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND; 3 4 // GetTickCount() returns the current number of milliseconds 5 DWORD next_game_tick = GetTickCount(); 6 7 int sleep_time = 0; 8 bool game_is_running = true; 9 while(game_is_running) 10 { 11 update_game(); 12 display_game(); 13 next_game_tick += SKIP_TICKS; 14 sleep_time = next_game_tick - GetTickCount(); 15 if(sleep_time >= 0) 16 { 17 Sleep(sleep_time); 18 } 19 else 20 { 21 // Shit, we are running behind! 22 } 23 }
在这种方案下,游戏的帧率恒定设置为25帧。如果达不到游戏内设定的恒定帧率,例如小霸王的机器,会非常的卡;牛逼的机器顶多也就是25帧,一定程度上有点浪费,但是对于手机游戏来说,能省点电,也许是个好事情。
3. 恒定的游戏速度和独立的帧率
1 const int TICKS_PER_SECOND = 25; 2 const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; 3 const int MAX_FRAMESKIP = 5; 4 DWORD next_game_tick = GetTickCount(); 5 int loops; 6 float interpolation; 7 bool game_is_running = true; 8 while(game_is_running) 9 { 10 loops = 0; 11 while(GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) 12 { 13 update_game(); 14 next_game_tick += SKIP_TICKS; // 保证25帧 15 loops++; 16 } 17 18 // interpolation代表插值 19 interpolation = float(GetTickCount() + SKIP_TICKS - next_game_tick) / float(SKIP_TICKS); 20 display_game(interpolation); 21 }
如果是牛逼的机器,在保持逻辑帧率25帧的情况下,会尽可能的提高渲染帧率,当然前提是需要计算需要渲染的插值。
如果是小霸王的机器,渲染帧率不足以达到25帧时,会在渲染一帧的同时跑多次逻辑帧,来尽量保证逻辑帧率一致,如果渲染帧率下降到TICKS_PER_SECOND/MAX_FRAMESKIP时,逻辑帧率也会随之降低。
4. 渲染帧率是否真的需要尽可能的高?
如果没有限制的话,那跑渲染的那个cpu肯定到100%了,这个应该在大部分的情况下是不能接受的。而且在视觉效果表现上来看,一定有个阈值的渲染帧率,超过了这个数值,再高的帧率的意义对画面的提升也有限,显得意义不大。如果是手机游戏的话,考虑到电池电量的因素,更应该控制一下帧率。

浙公网安备 33010602011771号