游戏主循环逻辑

游戏主循环逻辑

最简单的情况

bool game_is_running = true;
while(game_is_running)
{
  update_game();    // 逻辑帧
  display_game();    // 渲染帧
}

带来的问题:小霸王机器会跑的很慢,牛逼机器上跑得飞快,CPU 达到 100%。显然不是一个合适的算法。

恒定帧率和恒定游戏速度

const int FRAMES_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;

// GetTickCount() returns the current number of milliseconds
DWORD next_game_tick = GetTickCount();

int sleep_time = 0;
bool game_is_running = true;
while (game_is_running) 
{
    update_game();
    display_game();
    next_game_tick += SKIP_TICKS;
    sleep_time = next_game_tick - GetTickCount();
    if(sleep_time >= 0)
    {
      Sleep(sleep_time);
    }
    else
    {
      // Shit, we are running behind!
    }
}

在这种方案下,游戏的帧率恒定设置为 25 帧。如果达不到游戏内设定的恒定帧率,例如小霸王的机器,会非常的卡;牛逼的机器顶多也就是 25 帧,一定程度上有点浪费,但是对于手机游戏来说,能省点电,也许是个好事情。

恒定的游戏速度和独立的帧率

const int TICKS_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 5;
DWORD next_game_tick = GetTickCount();
int loops;
float interpolation;
bool game_is_running = true;
while(game_is_running)
{
    loops = 0;
    while(GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) 
    {
        update_game();
        next_game_tick += SKIP_TICKS;    // 保证25帧
        loops++;
    }

    // interpolation代表插值
    interpolation = float(GetTickCount() + SKIP_TICKS - next_game_tick) / float(SKIP_TICKS);
    display_game(interpolation);
}

如果是牛逼的机器,在保持逻辑帧率 25 帧的情况下,会尽可能的提高渲染帧率,当然前提是需要计算需要渲染的插值。

如果是小霸王的机器,渲染帧率不足以达到 25 帧时,会在渲染一帧的同时跑多次逻辑帧,来尽量保证逻辑帧率一致,如果渲染帧率下降到 TICKS_PER_SECOND / MAX_FRAMESKIP 时,逻辑帧率也会随之降低。

综合来说,这是一个比较优的解决方案。

参考文档

《deWiTTERS Game Loop》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏DannyHoo的专栏

iOS开发中使用算法之二分搜索算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

10420
来自专栏友弟技术工作室

R语言入门

最近在复习python的科学计算,突然心血来潮,想看看R的数据处理和python的区别在哪,所以就有了这篇文章。 R语言简介 四十多年前, R 语言的始祖诞生了...

865110
来自专栏章鱼的慢慢技术路

OpenGL光照设置

21530
来自专栏C语言及其他语言

【每日一题】问题 1429[蓝桥杯][历届试题]兰顿蚂蚁

题目描述 ? 兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。 平面上的正方形格子被填上黑色或白色。在其中一格正方形内有...

29660
来自专栏我和未来有约会

[Silverlight动画]转向行为 - 群落

说到群落,很难不引用Craig Reynolds和他的"boilds"模拟系统。Reynolds很牛的将一个看似非常恐怖的复杂过程,拆成了几个比较简单的行为。 ...

22780
来自专栏天天P图攻城狮

Android上实现频域均衡器

本篇文章主要介绍了将录音从时域数据转化成频域数据的方法。

47320
来自专栏大数据文摘

手把手 | 用StackOverflow访问数据实现主成分分析(PCA)

15970
来自专栏阮一峰的网络日志

布尔代数入门

布尔代数是计算机的基础。没有它,就不会有计算机。 布尔代数发展到今天,已经非常抽象,但是它的核心思想很简单。本文帮助你理解布尔代数,以及为什么它促成了计算机的诞...

32660
来自专栏韩东吉的Unity杂货铺

零基础入门 34:摄像机跟随目标

hello,今天来抽出时间给大家更新一发,之前有好多同学和我反馈说特别想要一个收藏贴可以分享如何制作摄像机追随目标,经过大家一而再再而三的催促,今天来给大家分享...

23440
来自专栏牛客网

58转转前端面经

28700

扫码关注云+社区

领取腾讯云代金券