【发布时间】:2014-10-12 14:00:06
【问题描述】:
我正在使用 SFML 制作 2D 平台游戏。我阅读了很多时间步长文章,但它们对我来说效果不佳。我正在以 2500 FPS 的时间步长实现它,在我的台式电脑上它非常流畅,在我的笔记本电脑上它达到了 300 FPS(我检查了 Fraps),它在笔记本电脑上不是那么流畅,但仍然可以播放。
这里是sn-ps的代码:
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 时间步长,但所有速度变量都变得如此缓慢,我不能简单地对所有常量执行 *2500.0f / 60.0f,感觉不一样。如果我得到接近的常数,感觉“还可以”,但是当碰撞发生时,角色的位置一直在设置并且它飞出地图,因为每帧都应用高速常数导致物体上的大圈我猜...
我需要补充一下,正常情况下,我拿时间步码使用的书
cImage.move(movementSpeed*TimePerFrame.asSeconds());
但正如你所见,我只是将 /2500.0f 放在每个常量上,我不使用它。
那么,每帧 1/2500 秒好吗?如果没有,如何将所有这些更改为 1/60.0f?
【问题讨论】:
-
您可以让模拟以比动画更高的速率运行,或者您可以在移动之前检查碰撞并根据此调整运动。例如。在移动之前检查新的边界框是否有碰撞,如果它与某物相交,则找出确切的撞击点和时间,然后根据它计算新的路径
-
2500 帧/秒?!你是认真的吗?
标签: c++ time game-physics sfml clock