I am new to SFML and was following a tutorial. However, I have encountered a very strange bug. I have a simple script that runs player.move whenever press WASD.
Although this script works, the player moves at extremely slow speeds. However, when I move my mouse while moving, it moves at a correct speed.
I have Visual Studio 2022 and SFML 2.6.
I researched a lot of issues on the internet but could not find anyone who had a similar issue.
My code is
#include <SFML\Graphics.hpp>
#include <iostream>
int main() {
sf::RenderWindow window(sf::VideoMode(512, 512), "SFML Tutorial", sf::Style::Close | sf::Style::Resize);
sf::RectangleShape player(sf::Vector2f(100.0f, 100.0f));
player.setFillColor(sf::Color::Red);
while (window.isOpen())
{
sf::Event evnt;
while (window.pollEvent(evnt)) {
switch (evnt.type) {
case sf::Event::Closed:
window.close();
break;
case sf::Event::Resized:
printf("New Window Width: %i New Window Height: %i\n", evnt.size.width, evnt.size.height);
break;
case sf::Event::TextEntered:
if (evnt.text.unicode < 128) {
printf("%c", evnt.text.unicode);
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) {
player.move(-0.1f, 0.0f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) {
player.move(0.1f, 0.0f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)) {
player.move(0.0f, -0.1f);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) {
player.move(0.0f, 0.1f);
}
window.clear();
window.draw(player);
window.display();
}
}
return 0;
}
I don't see anywhere where I detect mouse movement, so I am very confused by this issue.
You need to measure how much time that has passed since the last time you iterated in the main input loop and then use that time to multiply the player's movement. Also, don't check if the keys are pressed down inside the while (window.pollEvent(evnt))
loop.
Something like this:
sf::Clock clock;
float time{};
while (window.isOpen()) {
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) {
player.move(-10.0f * time, 0.0f); // multiply
}
// ... do the same on the rest too ...
time = clock.restart().asSeconds(); // last thing in the loop
}
It could look like this:
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(512, 512), "SFML Tutorial",
sf::Style::Close | sf::Style::Resize);
window.setFramerateLimit(120); // not strictly needed
sf::RectangleShape player(sf::Vector2f(100.0f, 100.0f));
player.setFillColor(sf::Color::Red);
sf::Clock clock;
float time{};
float speed = 10.0f;
while(window.isOpen()) {
sf::Event evnt;
while(window.pollEvent(evnt)) {
switch(evnt.type) {
case sf::Event::Closed:
window.close();
break;
}
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) {
player.move({-speed * time, 0.0f});
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) {
player.move({speed * time, 0.0f});
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)) {
player.move({0.0f, -speed * time});
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) {
player.move({0.0f, speed * time});
}
window.clear();
window.draw(player);
window.display();
time = clock.restart().asSeconds();
}
}