سؤال

So I have been playing around with DirectX11 lately and I'm still pretty new at it. I'm trying to move something right now with the translation and this is what I've got. I've been reading Frank D Luna's book on DirectX11 and he provides a gameTimer class but I really am not sure how to use delta time. This is the small snippet of code I was working with. Obviously this won't work because whenever I'm not pressing the key the time is still increasing and it's total time.

// Button down event.
if (GetAsyncKeyState('W') & 0x8000)
{
    XMMATRIX carTranslate;
    // Every quarter second incremete it
    static float t_base = 0.0f;
    if( (mTimer.TotalTime() - t_base) >= 0.25f )
        t_base += 0.25f;

    carPos.x = mTimer.TotalTime();
    carPos.y = 1.0f;
    carPos.z = 0.0f;
    carTranslate = XMMatrixTranslation(carPos.x, carPos.y, carPos.z);

    XMStoreFloat4x4(&mCarWorld, XMMatrixMultiply(carScale, carTranslate));
}
هل كانت مفيدة؟

المحلول

Usually we constantly render frames (redrawing screen) in a while loop (so called "main loop"). To "move" an object we just draw it in another position than it was in previous frame.

To move objects consistently, you need to know a time between frames. We call it "delta time" (dt). So, between frames, time increases by dt. Given velocity (speed) of object (v), we can calculate displacement as dx = dt * v. Then, to get current position, we just add dx to previous position: x += dx.

Note, that is a bad idea to calculate delta just inside your update or rendering code. Avoiding spreading out this functionality, we usually localize this calculations in timer/clock class.

Here is a simplified example:

// somewhere in timer class
// `Time` and `Duration` are some time units
class Timer {
    Time m_previousTime;
    Duration m_delta;
public:
    Duration getDelta() const { return m_delta; }

    void tick() {
        m_delta = currentTime() - m_previousTime; // just subtract
        m_previousTime = currentTime; // `current` becomes `previous` for next frame
    }
};

// main loop
while(rendering) {
    Timer.tick();
    Frame(m_Timer.getDelta());
}

void Frame(Duration dt) {
    if(keyPressed) {
        object.position += dt * object.velocity;
    }
}

You can now even make your object to move with acceleration (throttle, gravity, etc.):

    object.velocity += dt * object.acceleration;
    object.position += dt * object.velocity;

Hope you got the idea! Happy coding!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top