Reputation: 11
I have written a simple program with C++ and SFML. My problem is that when i move my sprite it is very choppy. My sprite will move a little then accelerate to a smooth movement until I press another key and it will stop again then continue. I hope this makes sense but in short I just want my sprite movement to be smoother. My code:
#include <SFML/Graphics.hpp>
#include <math.h>
#include <iostream>
int main()
{
float x = 0;
float y = 0;
sf::Vector2f position;
sf::Vector2f velocity;
float maxspeed = 3.0f;
float accel = 1.0f;
float decel = 0.02f;
sf::RenderWindow window(sf::VideoMode(400, 400), "SFML works!");
sf::Texture tplayer;
if (!tplayer.loadFromFile("character.png"))
{
// error...
}
sf::Sprite splayer;
splayer.setTexture(tplayer);
splayer.setOrigin(sf::Vector2f(0, 0));
splayer.setTextureRect(sf::IntRect(0, 0, 16, 38));
sf::Vector2f pos = splayer.getPosition();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
velocity.x -= accel;
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
velocity.x += accel;
else
velocity.x *= decel;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
velocity.y -= accel;
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
velocity.y += accel;
else
velocity.y *= decel;
if (velocity.x < -maxspeed) velocity.x = -maxspeed;
if (velocity.x > maxspeed) velocity.x = maxspeed;
if (velocity.y < -maxspeed) velocity.y = -maxspeed;
if (velocity.y > maxspeed) velocity.y = maxspeed;
position += velocity;
splayer.setPosition(position);
}
}
window.clear();
window.draw(splayer);
window.display();
window.setFramerateLimit(60);
}
return 0;
}
Upvotes: 1
Views: 1751
Reputation: 180
Google frame independent movement
//Before main loopp
sf::Clock clock;
// Start main loop
//Somewhere in the main loop
sf::Time deltaTime = clock.restart().asSeconds();
velocity.x *= deltaTime.asSeconds();
velocity.y *= deltaTime.asSeconds();
//move is just a setPosition but it adds given argument to actual position so it's basically splayer.setPosition(sf:Vector2f(position.x + velocity.x,position.y + velocity.y));
splayer.move(velocity);
Upvotes: 2
Reputation: 8581
Don't use the sf::Keyboard::isKeyPressed
-Method in the poll Event loop! This Method provides a way to ask for a key state anywhere in your program. Only writ code in your poll Event loop if you previously checked that the current polled event is that what you think. You do it like so if(event.type == sf::Event::Closed)
as you already found out.
So just move all of your code (except for the window close event) out of the poll event loop.
I have the feeling that you don't understand what exactly the event loop does, so I'll explain it to you:
Every event (e.g. mouse event, key pressed, window resize, ...) that occoured in the previous frame is queued and thes poll event loop goes over every queued event. For example first you have the mouse moved event, then a key pressed event. And you only want to do an action once of one specific event is occoured, so you have to ask with this if-block if the current event matches the events it is searched for. And the do sth. once.
Btw: You can call window.setFramerateLimit(60);
before the window is even open, so you don't waste reccources on setting the limit each frame.
Upvotes: 0