2016-12-14 58 views
1

我有一個疑問,這個gameloop實現:gameloop和插值的DeltaTime C++

#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和插值的「advance」嗎?還是應該有所不同?例如:

例子:

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); 
} 

正如你可以看到上面這兩個函數做同樣的事情,所以有一個與作爲參數傳遞的增量和插值來了兩次每個呼叫都會做,但在某些情況下,有兩個funcs會更好,例如也許在處理重力 - 物理遊戲時。你需要了解的是內插值總是預期循環時間的一小部分,因此你將需要你的精靈來移動這個分數以確保平滑移動,而不管幀速率如何。