固定时间尺为2500 FPS?

时间:2014-10-12 14:00:07

标签: c++ time game-physics sfml clock

我正在使用SFML制作2D平台游戏。我读了很多篇章文章,但对我来说效果不好。我正在实现它像2500 FPS时间步,在我的台式机上它非常流畅,在我的笔记本电脑上它获得300 FPS(我用Fraps检查),它在笔记本电脑上并不是那么顺畅但仍然可以播放。

以下是代码段:

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

这些是变量,这是游戏循环,

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

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

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

在Player.h中,我有运动常数,

    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 +=

在Player类的handleAll函数中,有

cImage.move(movementSpeed);
checkCollision();

最后,checkCollision函数,只检查字符的主边界框是否与每边的对象矩形相交,将速度x或y设置为0,然后通过将字符位置设置为边缘来修复重叠。

//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
    }
}

我尝试使用60 FPS Timestep像百万次,但所有速度变量变得如此之慢,我不能简单地对所有常量做* 2500.0f / 60.0f,它感觉不一样。如果我得到接近的常数,感觉“确定”但是当碰撞发生时,角色的位置一直被设定并且它飞出地图,因为每一帧施加的高速常数导致物体上的大圈猜...

我需要补充一下,通常,我采用时间步长代码的书使用

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

但是如你所见,我只是把/2500.0f放到每个常数上,我不使用它。

那么,每帧1/2500秒好吗?如果没有,我怎样才能将所有这些改为1 / 60.0f?

1 个答案:

答案 0 :(得分:2)

你做错了。

您的显示器最有可能具有60 Hz(= 60 FPS)的刷新率,因此尝试以2500 FPS渲染图像是一种巨大的资源浪费。如果选择2500 FPS的唯一原因是你的机芯运行不同,你有没有想过,问题可能出在运动代码上?

最好你实现一个固定的时间步长(famous article),这样你的物理可以以任何你想要的速度运行(2500“FPS”仍然是疯狂的,所以不要这样做)并且是独立于您的渲染率。所以,即使你得到一些不同的FPS,它也不会影响你的物理。