1
votes

I am using SFML making a 2D platformer. I read so many timestep articles but they don't work well for me. I am implementing it like 2500 FPS timestep, on my desktop pc it's amazingly smooth, on my laptop it's getting 300 FPS(I check with Fraps), it's not that smooth at laptop but still playable.

Here are the code snippets:

sf::Clock clock;
const sf::Time TimePerFrame = sf::seconds(1.f/2500.f);
sf::Time TimeSinceLastUpdate = sf::Time::Zero;
sf::Time elapsedTime;

These are variables and here is the game loop,

while(!quit){
        elapsedTime = clock.restart();
        TimeSinceLastUpdate += elapsedTime;

        while (TimeSinceLastUpdate > TimePerFrame){
            TimeSinceLastUpdate -= TimePerFrame;
            Player::instance()->handleAll();
        }

        Player::instance()->render();
}

In the Player.h, I've got movement constants,

    const float GRAVITY = 0.35      /2500.0f; // Uses += every frame
    const float JUMP_SPEED = -400.0f/2500.0f; //SPACE -> movementSpeed.y = JUMP_SPEED;

    //When character is touching to ground
    const float LAND_ACCEL = 0.075  /2500.0f; // These are using += 
    const float LAND_DECEL = 1.5    /2500.0f;
    const float LAND_FRICTION = 0.5 /2500.0f;
    const float LAND_STARTING_SPEED = 0.075; // This uses =, instead of +=

In the handleAll function of Player class, there is

cImage.move(movementSpeed);
checkCollision();

And lastly, checkCollision function, simply checks if character's master bounding box intersects the object's rectangle from each side, sets the speed x or y to 0, then fixes the overlapping by setting character position to the edge.

//Collision
if(masterBB().intersects(objectsIntersecting[i]->GetAABB())){
    //HORIZONTAL
    if(leftBB().intersects(objectsIntersecting[i]->GetAABB())){
        if(movementSpeed.x < 0)
            movementSpeed.x = 0;
        cImage.setPosition(objectsIntersecting[i]->GetAABB().left + objectsIntersecting[i]->GetAABB().width + leftBB().width , cImage.getPosition().y);
    }
    else if(rightBB().intersects(objectsIntersecting[i]->GetAABB())){
        if(movementSpeed.x > 0)
            movementSpeed.x = 0;
        cImage.setPosition(objectsIntersecting[i]->GetAABB().left - rightBB().width , cImage.getPosition().y);
    }

    //VERTICAL
    if(movementSpeed.y < 0 && topBB().intersects(objectsIntersecting[i]->GetAABB())){
        movementSpeed.y = 0;
        cImage.setPosition(cImage.getPosition().x , objectsIntersecting[i]->GetAABB().top + objectsIntersecting[i]->GetAABB().height + masterBB().height/2);
    }

    if(movementSpeed.y > 0 && bottomBB().intersects(objectsIntersecting[i]->GetAABB())){
        movementSpeed.y = 0;
        cImage.setPosition(cImage.getPosition().x , objectsIntersecting[i]->GetAABB().top - masterBB().height/2);
        //and some state updates
    }
}

I tried to use 60 FPS Timestep like million times but all speed variables become so slow, I can't simply do like *2500.0f / 60.0f to all constants, It doesn't feel same. If I get close constants, It feels "ok" but then when the collision happens, character's position is getting setted all the time and it flys out of the map because of the big lap on the object caused by high speed constants applied every frame I guess...

I need to add, Normally, the book I took the timestep code uses

cImage.move(movementSpeed*TimePerFrame.asSeconds());

but as you saw, I just put /2500.0f to every constant and I don't use it.

So, is 1/2500 seconds per frame good? If not, how can I change all of these to 1/60.0f?

1
You can have the simulation run at a higher rate than the animation, or you could check for collision before moving and adjust the motion based on that. E.g. before moving check the new bounding box for collision, and if it intersects something figure out the exact point and time of impact, and then compute a new paths based on thatbames53
2500 FPS?! are you serious?Exceptyon

1 Answers

2
votes

You're doing it wrong.

Your monitor most likely has a refresh rate of 60 Hz (= 60 FPS), thus trying to render an image at 2500 FPS is a huge waste of resources. If the only reason for choosing 2500 FPS is that your movement doesn't work the same, haven't you ever thought about, that the problem then might be with the movement code?

At best you'd implement a fixed timestep (famous article), that way your physics can run at whatever rate you want (2500 "FPS" would still be crazy, so don't do it) and is independent from your rendering rate. So even if you get some varying FPS, it won't influence your physics.