在没有游戏引擎/渲染窗口的情况下将游戏服务器线程循环限制为30FPS

时间:2015-01-17 10:39:09

标签: c++ multithreading server frame-rate

我会尽可能轻松地解释这一点。

我基本上有一个主持多场比赛的游戏。 服务器上的所有匹配都由服务器处理,没有玩家通过端口转发在他们的计算机上进行匹配,所有这些都是由服务器完成的,所以他们不需要。

当玩家请求进行匹配时,在服务器上创建具有线程的匹配对象。这很好用。每个匹配对象都有自己的玩家列表。但是,游戏客户端运行速度为30FPS并且需要与服务器同步,因此只更新线程循环中的所有玩家将无法执行,因为它不是以30FPS运行。

我现在正在做的是使用游戏引擎:SFML,它在窗口循环中,遍历服务器中的所有玩家并以30FPS运行他们的更新代码。 然而,这很好,当他们可能是一大块人时,通过匹配线程更新玩家会更好,这样就不会通过在一个渲染中完成所有操作来降低处理速度循环。

我想知道的是,如何在匹配的线程循环中模拟30FPS?基本上有它所以每个玩家的update()函数在30FPS的时间范围内被调用,而不必使用像SFML这样的渲染引擎来限制代码的运行速度?代码在后台运行,输出显示在控制台上,服务器上不需要渲染。

或简单地说,如何在没有游戏引擎的情况下限制while循环代码以30FPS运行?

1 个答案:

答案 0 :(得分:1)

这看起来有点像X Y问题:你试图通过服务器同步玩家" FPS"限制。服务器端并不像那样工作。

服务器在时间上与客户端同步,将服务器的时间传递给客户端每个包或通过特定包(换句话说,所有客户端只有服务器的时间)。 / p>

但关于游戏的服务器端实现:

这个问题比你提到的要广泛得多。我会发布一些有助于您研究的指南。

首先,在服务器上你不需要渲染,因此FPS不相关(为了让我们的眼睛感受到流动性,需要30 fps)。服务器通常处理逻辑,例如各种事件(例如某人发射火箭,或者产生新的敌人)。正如您所看到的,事件并不需要FPS,而且它们是随机触发的。

在服务器上完成的其他事情是物理(或其他玩家 - 玩家或玩家 - 环境交互)。使用固定更新步骤完成冲突。物理通常以20 FPS计算。移动物体获得胶囊碰撞器以正确模拟相互作用。换句话说,服务器虽然没有呈现任何内容,但却负责移动/冲突(这意味着如果您没有与服务器建立连接,则无法移动/通过墙壁等 - 依赖于实现)

现代游戏也有预测,以减少滞后(毕竟,在你给你的角色任何输入后,该输入需要首先到达服务器,得到处理并被收回,以便对其产生任何影响客户)。这意味着当您在客户端上输入时(例如让我们移动),客户端开始预期执行操作,并且当服务器响应到来时(对于我们的示例,新位置),将考虑作为纠正。这就是为什么有时候在游戏中,当你有一个滞后的时候,你会感觉到你正在向某个方向移动,那么突然之间,你就会完全不同。

关于你的问题:

在while循环中,进行deltaT,如果deltaT小于33毫秒,则使用sleep(33-deltaT)。

根据您的要求,我发布了deltaT代码样本:

 while (gameIsRunning)
 {
      double time = GetTickCount();
      UpdateGame();
      double deltaT = GetTickCount()-time;
      if (deltaT < 33 )
      {
          sleep(33- deltaT);
      }
 }

其中gameIsRunning是全局布尔值,UpdateGame是您的游戏更新功能。

请注意,上面的代码适用于Windows。对于linux,您将需要其他函数而不是GetTicksCount并且睡眠。