How can I implement framerate-independant updates?

user975989
  • How can I implement framerate-independant updates? user975989

    Edit: I fixed the problem by making jumpvelocity the one that is modified and added onto, and yvelocity just equal jumpvelocity * t. This is what I have right now:

    if (GUI->Space && grounded){
        jumpvelocity = -185.f * 2  / gravity;
        grounded = false;
    
    }
    
    if(!grounded ){
        if(jumpvelocity < terminaly){
            jumpvelocity += 185.f * t * 4  / gravity;
            yvelocity = jumpvelocity * t;
        }
        else{
            jumpvelocity = terminaly;
            yvelocity = jumpvelocity * t / gravity;
        }
    }
    else{
        yvelocity = 0.f;
        jumpvelocity = 0.f;
    }
    

    Thanks for the help.

    I am trying to get my gravity to work. The code I have so far is

    if (jumpvelocity < 0){
       yvelocity = jumpvelocity * t *2/gravity;
        jumpvelocity += 185.f*t * 2 / gravity;
    }
    
    else if(!grounded ){
        if(yvelocity < terminaly)
            yvelocity += t / gravity;
        else
            yvelocity = terminaly;
    }
    

    Gravity scales upwards, the higher making falling and jumping slower. It's default value is 1. Jumpvelocity is set to 185 when the player wishes to jump. My problem is that you fall slower at a slower framerate, but you jump at the same speed as if it was a higher framerate. How would I make it frame independent? T is delta time.

  • On each main loop iteration:

    1. Check your system timer and store as currentTime (eg. SDL_GetTicks())
    2. timeDelta = currentTime - lastTime
    3. Convert timeDelta to seconds (usually it's in ms or ns), store as timeDeltaSeconds
    4. For each entity in entities: entity.position = velocityInUnitsPerSecond * timeDeltaSeconds
    5. lastTime = currentTime (could also be done before step 1 instead of here)

    ...You will need to adjust your current numbers to be in units per second, i.e. so that they would make sense at 1FPS. For example, if you expected your character's horizontal velocity to be 2 pixels per tenth of a second, then you now need to set it as 20 pixels per second. That way, the above will work out correctly.

    For some applications, it is better to fix your timestep to a given amount. In this case, timestep != timeDelta. The latter is the amount of system time that has actually passed; the former is a quantised amount you want to consume from your time accumulator each time you apply logic updates in your game. This assists integration when you are using iterative solvers like those found in the well-known physics engines, because timesteps must be equal when doing the calculus. In this case, because you are not simply using up all of the time you have remaining on each tick, you will have fractions of time left over, and you need to accumulate these for use in later ticks. For more about this, read Fix Your Timestep by Glenn Fiedler.

  • It does not seem that jumpvelocity is needed at all. Jumping means instantly setting velocity to a given value: once the feet no longer touch the ground, the only thing that can change velocity is gravity (and air resistance, that you implement using terminal velocity).

    Another remark: floating point divisions are extremely slow. I suggest you store 1.0f / gravity instead of gravity.

    Finally, there is a possibility that for one frame yvelocity can be larger than terminaly.

    My suggestion:

    if (GUI->Space && grounded) {
        yvelocity = 185.f;
        grounded = false;
    } else if (!grounded ) {
        yvelocity += t * inv_gravity;
        if (yvelocity > terminaly)
            yvelocity = terminaly;
    }
    

    And remember that the following is not accurate:

    ypos += t * yvelocity;
    

    You need to do:

    ypos += t * 0.5f * (old_yvelocity + yvelocity);
    

Tags
c++
Related questions and answers
  • Alright so i'm making a vertical side scroller where you are an '8' character traveling downward while avoiding my randomly generated walls (the "generation" function) on the left and right sides... until you pop out into an open space, known as a ' ' (space) character. You lose one life for each INITIAL collision with the X wall, and do not lose another until you have popped out and been freed from it. As an added touch i have made it so after you collide while traveling down the randomly generated map (or rather as the walls move uppward while your character stays put) the X chars you've

  • To begin with I am developing a PSP application so I have no clue how to debug a PSP application. That doesn't mean I do not know how debug period. Anyway, when I run the game everything runs fine but when I press the X button on the PSP I see no bullet being drawn or updated on the screen. I know the problem doesn't lie with the pad because I press start and it exits my game so I do not think it is the pad that is causing the problem. Maybe the bullet is being drawn out of the screen already. But I am not sure since I cannot debug maybe somebody can see the flaw in my code. main.cpp class

  • Dear all, this is going to be tough: I have created a game object factory that generates objects of my wish. However, I get memory leaks which I can not fix. Memory leaks are generated by return new Object(); in the bottom part of the code sample. static BaseObject * CreateObjectFunc() { return new Object(); } How and where to delete the pointers? I wrote bool ReleaseClassType(). Despite... true; } Before taking a look at the code below, let me help you in that my CGameObjectFactory creates pointers to functions creating particular object type. The pointers are stored within vFactories

  • i think i just found the solution. 1) the problem is that backbuffer surface and source surface are of different formats - that is why exception was thrown. 2) the image path needed double slash "C\\......." ;) ================================= I have been googling for a while but still cant come up with a solution to the problem - D3DXGetImageInfoFromFile function just doesn't load any images..._VERTEXPROCESSING, &amp;d3dpp, &amp;pd3dDevice))) return false; return true; } void render(void) { // check to make sure you have a valid Direct3D device if (NULL == pd3dDevice) return

  • want to learn on my own) or the something like the SAT (Separating Axis Theorem) if at all possible. Thank you in advance for your help! void world1Level1CollisionDetection() { for(int i; i &lt; blocks...;&amp; ballPrev.coords[2] &lt; block[i].coords[0] &amp;&amp; (((ball.coords[1] &lt; block[i].coords[1]) || (ball.coords[3] &lt; ball.coords[1])) || ((ball.coords[1] &lt; block[i].coords[3]) || ball.coords[3] &lt; block[i].coords[3]))) { left = 1; } if (ballPrev.coords[0] > block[i].coords[2] &amp;&amp; ballPrev.coords[2] > block[i].coords[2] &amp;&amp

  • Right now I create my boxes where 1 meter is 85 pixels. Gravity is 10. And fixtureDef.restitution = 0.1f; fixtureDef.friction = 0.5f; fixtureDef.density = 1.0f; The problem I'm having is illustrated in the image I have provided: As you can see, there is a small gap between many, but not all the crates. What could cause this? Thanks

  • working of windows/linux/osx), I have a toggle to toggle between using the FBO(post-processing) and not. The shaders are working, but it seems the FBO didn't load the texture unit bound to it. The following is the init code for the FBO and it's texture: glGenTextures(1,&amp;fboimg); glBindTexture(GL_TEXTURE_2D,fboimg); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf...; } if(status != GL_FRAMEBUFFER_COMPLETE) { cout<&lt;"status != GL_FRAMEBUFFER_COMPLETE"&lt;&lt;endl; GLUtils::checkForOpenGLError(__FILE__,__LINE__); } else { //shader and VAO setup

  • ; } } toWorldXForm is the object's world transform and toParentXForm is the object's transform relative to the parent. I want to do this using a method within my object class (the code above...) this->child->update(toParentXForm); Sorry if I've not been clear, please tell me if there's anything else you need to know. I've no doubt it's merely a silly mistake on my part, hopefully... to its parent (and its parent's parent etc.). I'm struggling to get it to work recursively, though I can get it to work like this: for(int i = 0; i &lt; NUM_OBJECTS; i++) { // Initialize

  • = xyCoords.y; m_font->DrawTextA(NULL, stateStream.str().c_str(), -1, &amp;rct, DT_LEFT|DT_NOCLIP , D3DXCOLOR(1,0,0,1)); This all works perfectly. Where am I going wrong with the first bit of code...() will return a vector3 that has a 0 z component and x and y values from about 2 to roughly 33. Now how on earth can me with a calculator be better than the computer? what am I missing? 0.0f / 720.0f) * 2.0f...I would have thought that if the object is on-screen that this function should return screen coordinates. When used in conjunction with the directX draw text function, it works fine. Textual overlays

Data information