So I am working on a game in SFML and am having a weird problem with movement. I have implemented a delta time so the movement speed is constant but I have this weird issue where I press a move key, the object jumps by speed units, pauses, then proceeds to move smoothly. I haven't been able to find much on this as I don't really know what problems I should be looking for. Here is a copy of my current code.
#include <SFML/Graphics.hpp>
#include "Player.h"
#include <iostream>
#include <vector>
void handleKeyPress(sf::Event &event, Player &player, float dt);
int main() {
sf::ContextSettings settings;
settings.antialiasingLevel = 16;
sf::RenderWindow window(sf::VideoMode(800, 600), "Title", sf::Style::Default, settings);
sf::Event event;
Player player;
player.setPosition(100, 100);
sf::Clock dtClock;
while (window.isOpen()) {
float dt = dtClock.getElapsedTime().asSeconds();
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
handleKeyPress(event, player, dt);
window.clear(sf::Color::Black);
//drawing happens hear
window.draw(player);
//end of frame
window.display();
dtClock.restart();
}
}
}
void handleKeyPress(sf::Event& event, Player& player, float dt) {
sf::Vector2f moveVector(0.0f, 0.0f);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
moveVector.x = -player.speed;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
moveVector.x = player.speed;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
moveVector.y = -player.speed;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
moveVector.y = player.speed;
player.move(moveVector * dt);
}
Note that player is just an SFML Transformable object/drawable object.
Your main is mixing event processing and state updates with drawing, which makes it hard to respect the fractional updates you intend to do with dt
.
The code below undoes that: it first eats all events, then updates the game state, then draws.
In order to have smooth movement, you need to remember the Player velocity depending on which keys are pressed/released:
velocity
vector to Playerupdate
method to player that adds a dt
fraction of velocity
to position.Change it to:
while (window.isOpen()) {
float dt = dtClock.getElapsedTime().asSeconds();
// process events
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
} else if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased) {
// rewrite this to update player.velocity depending on what key is pressed if released
handleKeyPress(event, player, dt);
}
}
// apply dt * player.velocity to player.position
player.update(dt);
// draw
window.clear(sf::Color::Black);
//drawing happens hear
window.draw(player);
// restart the dtclock here, as display() will pause for a bit
dtClock.restart();
//end of frame
window.display();
}