无法获得SFML的平稳运动
Cannot get smooth movement in SFML
我搜索了此主题,发现使用sf::Clock
实现帧独立更新(使用deltaTime
)可以帮助解决它。但是,即使在添加后,桨动作也有点结束。另一方面,当我在不使用deltatime
的情况下将整个Playing
情况转移到event polling loop
时,游戏似乎会顺利运行。
我如何在代码中正确使用sf::Clock
,为什么当我在事件池循环中移动Playing
情况时,我的游戏似乎在不使用deltatime
的情况下运行顺利。
游戏初始化:
void Game::start() {
if (_gameState != Uninitialized) {
return;
}
//Creating window
_mainWindow.create(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32), "Pong");
_gameState = ShowingMenu;
//Adding game entities to the manager
VisibleGameObject *paddle1 = new PlayerPaddle("Player1", 1.0f, sf::Keyboard::Key::Up, sf::Keyboard::Key::Down);
VisibleGameObject *paddle2 = new PlayerPaddle("Player2", 1.0f, sf::Keyboard::Key::W, sf::Keyboard::Key::S);
VisibleGameObject *background = new Background("Background", 0.0f);
paddle1 -> setPosition(SCREEN_WIDTH - (paddle1 -> getWidth()), 0);
paddle2->setPosition(0, 0);
manager.addObject(paddle1);
manager.addObject(paddle2);
manager.addObject(background);
//Starting Clock
deltaTime = 0.0f;
frameClock.restart();
while (!isExiting()) {
gameLoop();
}
_mainWindow.close();
}
游戏循环:
void Game::gameLoop()
{
static bool firstPass = true;
sf::Event currentEvent;
//Event loop
while(_mainWindow.pollEvent(currentEvent) || firstPass)
{
if (firstPass) {
currentEvent = sf::Event();
currentEvent.type = sf::Event::GainedFocus;
firstPass = false;
}
if (currentEvent.type == sf::Event::Closed)
{
_gameState = Exiting;
}
switch (_gameState)
{
case ShowingMenu:
{
showingMenu();
break;
}
case Paused:
{
break;
}
default:
break;
}
}
//Extracting deltaTime to update game logic
deltaTime = frameClock.restart().asSeconds();
if(_gameState == Playing)
{
manager.updateAllLayers(deltaTime);
manager.drawAllLayers(_mainWindow);
_mainWindow.display();
}
}
划桨更新逻辑:
void PlayerPaddle::update(const float & elapsedTime)
{
sf::Vector2f currentPos = getPosition();
float displacement = 0.0f;
if (sf::Keyboard::isKeyPressed(controls.up))
{
displacement = -speed * elapsedTime;
}
else if (sf::Keyboard::isKeyPressed(controls.down))
{
displacement = speed * elapsedTime;
}
if (displacement + currentPos.y < 0.0f)
{
setPosition(currentPos.x, 0.0f);
return;
}
else if (displacement + currentPos.y + getHeight() > Game::SCREEN_HEIGHT)
{
setPosition(currentPos.x, Game::SCREEN_HEIGHT - getHeight());
return;
}
setPosition(currentPos.x, currentPos.y + displacement);
}
我没有足够的声誉来发表评论,所以我必须给这个答案...
您更新(并绘制)每个帧。如果要实现固定的更新时间步骤,则您的游戏循环是没有意义的。
这就是您的游戏循环的外观。为了您的方便,我使用您的变量名称:
// ...
sf::Clock frameClock;
const sf::Time timePerFrame = sf::seconds(1.0f / 60.0f);
sf::Time timeSinceLastUpdate = sf::Time::Zero;
while (_mainWindow.isOpen()) {
timeSinceLastUpdate += frameClock.restart();
// events
{
sf::Event evt;
while (_mainWindow.pollEvent(evt)) {
//...
}
}
// update
{
while (timeSinceLastUpdate > timePerFrame) {
timeSinceLastUpdate -= timePerFrame;
manager.updateAllLayers(timePerFrame);
}
}
// render
{
_mainWindow.clear();
// ...
_mainWindow.display();
}
}
// ...
这以固定速率(1/60s)更新您的游戏,并尽可能呈现(您可以使用setFramerateLimit()
来限制FPS;这不会影响固定的更新间隔,因此没有问题)。
您现在将sf::Time
传递给您的manager.updateAllLayers
,它像elapsedTime
一样使用(它具有.asSeconds()
之类的函数,因此本质上没有任何变化,但显然您必须调整speed
的值)
相关文章:
- SFML纹理像播放器
- 如何使用AngelScript注册SFML Vector2运算符
- 如何修复sfml c++代码编译错误
- SFML library: http request
- 落砂模拟碰撞检测C++和SFML
- 使用 SFML 和 C++ 将 Pixel 打印到屏幕上
- SFML RenderWindow打开窗口需要很长时间
- 矢量下标超出SFML游戏中的范围
- 获取 SFML 窗口的 HWND 和高可用性?
- 将 Vulkan 与 SFML 结合使用?
- SFML 文本未绘制在窗口上
- SFML 碰撞永远不会在我的系统中注册
- 使用对象数组对 SFML 进行动画处理
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 如何使用 SFML 在贪吃蛇游戏中定义游戏结束?
- 如何通过多类"Union variable" (sfml) 使用轮询事件
- C++ SFML 精灵运动无法按预期工作
- SFML意外的SF ::顶点运动
- SFML屏幕运动很慢
- 无法获得SFML的平稳运动