gameloop和deltatime插值c ++

Posted

技术标签:

【中文标题】gameloop和deltatime插值c ++【英文标题】:gameloop and deltatime interpolation c++ 【发布时间】:2016-12-14 16:02:20 【问题描述】:

我对这个游戏循环的实现有疑问:

#include <chrono>
#include <iostream>

using namespace std::chrono_literals;

// we use a fixed timestep of 1 / (60 fps) = 16 milliseconds
constexpr std::chrono::nanoseconds timestep(16ms);

struct game_state 
  // this contains the state of your game, such as positions and velocities
;

bool handle_events() 
  // poll for events

  return false; // true if the user wants to quit the game


void update(game_state *) 
  // update game logic here
  std::cout << "Update\n";


void render(game_state const &) 
  // render stuff here
  //std::cout << "Render\n";


game_state interpolate(game_state const & current, game_state const & previous, float alpha) 
  game_state interpolated_state;

  // interpolate between previous and current by alpha here

  return interpolated_state;


int main() 
  using clock = std::chrono::high_resolution_clock;

  std::chrono::nanoseconds lag(0ns);
  auto time_start = clock::now();
  bool quit_game = false;

  game_state current_state;
  game_state previous_state;

  while(!quit_game) 
    auto delta_time = clock::now() - time_start;
    time_start = clock::now();
    lag += std::chrono::duration_cast<std::chrono::nanoseconds>(delta_time);

    quit_game = handle_events();

    // update game logic as lag permits
    while(lag >= timestep) 
      lag -= timestep;

      previous_state = current_state;
      update(&current_state); // update at a fixed rate each time
    

    // calculate how close or far we are from the next timestep
    auto alpha = (float) lag.count() / timestep.count();
    auto interpolated_state = interpolate(current_state, previous_state, alpha);

    render(interpolated_state);
  

我需要知道我应该如何实现 deltaTime 和插值, 进行平滑的“世界对象”运动。这是使用 deltaTime 和插值实现“提前”的好方法吗?还是应该不同?例如:

例子:

obj* myObj = new myObj();

float movement = 2.0f;
myObj->position.x += (movement*deltaTime)*interpolation;

我需要一些关于使用 deltatime 插值的帮助。

谢谢!

【问题讨论】:

【参考方案1】:

插值将始终用于一种预测功能 - 精灵将在未来的时间。要回答有关如何使用插值变量的问题,您将需要两个更新函数 - 一个将 delta 作为参数,另一个使用插值时间。请参阅下面的函数示例(根据您使用的编码语言实现):

void update_funcA(int delta)

    sprite.x += (objectSpeedperSecond * delta);


void predict_funcB(int interpolation)

    sprite.x += (objectSpeedperSecond * interpolation);

正如您在上面看到的那样,两个函数做同样的事情,因此在每次调用中使用作为参数传递的增量和插值值调用一个函数会做两次,但在某些情况下有两个函数会更好,例如在处理重力时 - 也许是物理游戏。您需要了解的是,插值始终是预期循环时间的一小部分,因此您需要精灵移动该部分,以确保无论帧率如何都能平稳移动。

【讨论】:

以上是关于gameloop和deltatime插值c ++的主要内容,如果未能解决你的问题,请参考以下文章

如果有固定的时间步长和插值,则进行多个游戏更新的目的

C++ Win32 FPS 和 DeltaTime 实现

C# 控制台应用程序 - gameloop / 多个对象

Time.deltaTime使用Unity在C#中执行什么主要功能?

[UE4]根据时间速度进行插值:Finterp to Constant

由于 Time.deltaTime,C#/Unity 相机跟随抖动