我将尽力解释这一点。

我基本上有一款可以举办多个比赛的游戏。
服务器上的所有比赛都由服务器处理,没有玩家通过端口转发在他们的计算机上托管比赛,这完全是由服务器完成的,因此他们不必这样做。

当玩家要求进行比赛时,会在服务器上创建带有线程的比赛对象。这很好。每个比赛对象都有自己的球员列表。但是,游戏客户端以30FPS的速度运行,并且需要与服务器同步,因此仅更新线程循环中的所有玩家都不会这样做,因为它不是以30FPS的速度运行。

我现在正在做的是使用一个游戏引擎:SFML,在其窗口循环中,它会遍历服务器中的所有玩家,并以30FPS的速度运行其更新代码。
很好,但是,当可能有很多人出现时,最好通过比赛线程对玩家进行更新,以免通过一次渲染完成所有处理而减慢处理速度环。

我想知道的是,如何在比赛的线程循环中模拟30FPS?基本上有了它,所以每个播放器的update()函数都在30FPS的时间范围内被调用,而不必使用诸如SFML之类的渲染引擎来限制代码运行的速度?该代码在后台运行,并且输出显示在控制台上,无需在服务器上进行渲染。

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

最佳答案

这似乎有点像X Y问题:您尝试通过服务器“ FPS”限制来同步播放器。服务器端并不是真的那样工作。

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

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

这个问题比您提到的要广泛得多。我将发布一些指南,希望对您的研究有所帮助。

首先,在服务器上不需要渲染,因此FPS无关紧要(需要30 fps以使我们的眼睛感觉流畅)。服务器通常处理逻辑,例如各种事件(例如有人发射火箭,或产生了新的敌人)。如您所见,事件不需要FPS,并且它们是随机触发的。

在服务器上完成的其他工作是物理(或其他播放器-播放器或播放器-环境交互)。冲突是使用固定的更新步骤完成的。例如,物理通常以20 FPS计算。运动对象会遇到胶囊碰撞器,以正确模拟交互。换句话说,服务器虽然没有渲染任何内容,但却引起了移动/冲突(这意味着,如果您没有与服务器的连接,则您将不会移动/穿墙,等等,具体取决于实现)。

现代游戏也进行了预测,以减少滞后现象(毕竟,在向角色提供任何输入后,该输入需要首先到达服务器,进行处理并重新接收,以便对客户端产生任何影响)。这意味着,当您在客户端上有输入时(例如,让我们举个例子),客户端开始按预期进行操作,并且当服务器响应到来时(例如我们的新职位),它将被视为更正。这就是为什么有时候在游戏中,当您出现滞后时,您会感觉到自己朝某个方向移动,然后突然之间您处在完全不同的位置。

关于您的问题:

在while循环内,创建一个deltaT,如果该delT小于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和sleep。

关于c++ - 在没有游戏引擎/渲染窗口的情况下将Game Server Thread循环限制为30FPS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27998595/

10-11 23:12
查看更多