Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Timestep/game loop explanations needed


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 Predator034   Members   -  Reputation: 213

Like
0Likes
Like

Posted 05 February 2013 - 04:42 PM

Hi there, I need some help with my game's timestep. And yes, I've read over the infamous and all-too reposted gaffer article: gafferongames.com/game-physics/fix-your-timestep/

 

 

Basically my current game loop code is broken and passes a deltatime through each update(elapsedTime) method. Then movements are multiplied based on that value, of course.

 

My game does need to be networked, but I'm hoping that such a thing doesn't change much, (essentially I'll just have the clients act as dumb input terminals and the server will tell everyone the state, it's only for a small number of players so it should be fine and as such will be authoritative).

 

The parts I do not understand about *this* solution, is how the State struct fits into all of this. Why is it only 1 dimensional? Do I add y (it's a 2d game) as well in a same similar manner, along with vy to make this usable for 2d?

 

 

Why is it interpolating the rendering itself and not collision and such?

 

If I have a world->update() call which updates all the entities and checks collision on them..what do I pass to them and how do I use this in a similar manner as I was doing?

 

I don't see how just interpolating the rendering would result in something usable?

 

Where do I place the input collection code and the update (collision/physics etc.) code, as well as networking. Especially since I have a handleEvents() { while (SDL_PollEvent(&event)) {.. }.. } Can I just place all of these in one area? Where, exactly, in the main loop?

 

I've scoured the internet and unfortunately have yet to find a *real* example that uses a fixed time step

 

 

  I'm posting the code below so that it's easy to talk about as I need to understand it, and a lot of it I do not, and so people can hopefully walk me through the parts I'm confused on.

 

Thanks, really hoping someone here can help me understand and use this code. Game loops seem to be an area where from a distance they seem obvious and simple/straight forward, but of course, that is not the case at all.

 


struct State
{
    float x;
    float v;
};


struct Derivative
{
    float dx;
    float dv;
};


State interpolate(const State &previous, const State &current, float alpha)
{
    State state;
    state.x = current.x*alpha + previous.x*(1-alpha);
    state.v = current.v*alpha + previous.v*(1-alpha);
    return state;
}


float acceleration(const State &state, float t)
{
    const float k = 10;
    const float b = 1;
    return - k*state.x - b*state.v;
}


Derivative evaluate(const State &initial, float t)
{
    Derivative output;
    output.dx = initial.v;
    output.dv = acceleration(initial, t);
    return output;
}


Derivative evaluate(const State &initial, float t, float dt, const Derivative &d)
{
    State state;
    state.x = initial.x + d.dx*dt;
    state.v = initial.v + d.dv*dt;
    Derivative output;
    output.dx = state.v;
    output.dv = acceleration(state, t+dt);
    return output;
}


void integrate(State &state, float t, float dt)
{
    Derivative a = evaluate(state, t);
    Derivative b = evaluate(state, t, dt*0.5f, a);
    Derivative c = evaluate(state, t, dt*0.5f, b);
    Derivative d = evaluate(state, t, dt, c);
    
    const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
    const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv);
    
    state.x = state.x + dxdt*dt;
    state.v = state.v + dvdt*dt;
}


int main()
{
    const int width = 640;
    const int height = 480;
    
    if (!openDisplay("Timestep", width, height))
        return 1;


    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, 4.0/3.0, 1, 1000);


    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0,0,150, 0,0,0, 0,1,0);
    
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_POINT_SMOOTH);
    glPointSize(4);    
    
    glClearColor(0.3f, 0.3f, 0.3f, 1);


    State current;
    current.x = 100;
    current.v = 0;
    
    State previous = current;


    float t = 0.0f;
    float dt = 0.1f;
    
    float currentTime = 0.0f;
    float accumulator = 0.0f;
    
    while (!quit) 
    {            
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        const float newTime = time();
        float deltaTime = newTime - currentTime;
        currentTime = newTime;
        
        if (deltaTime>0.25f)
            deltaTime = 0.25f;
        
        accumulator += deltaTime;
        
        while (accumulator>=dt)
        {
            accumulator -= dt;
            previous = current;
            integrate(current, t, dt);
            t += dt;
        }
        
        State state = interpolate(previous, current, accumulator/dt);
        
        glBegin(GL_POINTS);
        glColor3f(1,1,1);
        glVertex3f(state.x, 0, 0);
        glEnd();
        
        updateDisplay();
    }
    
    closeDisplay();
    
    return 0;
}

 


Edited by Predator034, 05 February 2013 - 04:43 PM.


Sponsor:

#2 ultramailman   Prime Members   -  Reputation: 1581

Like
0Likes
Like

Posted 05 February 2013 - 07:58 PM

The example uses one dimension in state, but you can add as many dimensions as you need.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS