我正在使用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?
答案 0 :(得分:2)
你做错了。
您的显示器最有可能具有60 Hz(= 60 FPS)的刷新率,因此尝试以2500 FPS渲染图像是一种巨大的资源浪费。如果选择2500 FPS的唯一原因是你的机芯运行不同,你有没有想过,问题可能出在运动代码上?
最好你实现一个固定的时间步长(famous article),这样你的物理可以以任何你想要的速度运行(2500“FPS”仍然是疯狂的,所以不要这样做)并且是独立于您的渲染率。所以,即使你得到一些不同的FPS,它也不会影响你的物理。