Hello folks,
I recently started looking for a C++ Multimedia library and decided to give SFML a try. I have built SFML on Xubuntu 14.04 utilizing Cmake according to official websites instructions. So far so good. I have now implemented a very basic version of the first code example given in the book 'SFML game developement', which is a circle moving about when one of the 'wasd' keys is pressed.
Now this does work, however, since I have not attempted to regulate the circle's speed, I would have expected it to move very rapidly. In reality it takes about 20 seconds for the circle to cross my screen.
I guess the program is very crudely implemented, also I do not have a dedicated graphics-card (my laptop has an Intel 4400 built in). Still I can't believe this sort of behavior is to be expected. I actually compiled the same program on another laptop running arch and the framerate increased about a hundredfold.
Is there anything I might be missing?
Here's the code, pretty much straight from the book.
//The game.h header
class Game
{
public:
Game();
void run();
private:
void processEvents();
void handlePlayerInput(sf::Keyboard::Key, bool);
void update();
void render();
sf::RenderWindow mWindow;
sf::CircleShape mPlayer;
bool mIsMovingUp;
bool mIsMovingDown;
bool mIsMovingLeft;
bool mIsMovingRight;
};
//The implementation
#include<SFML/Graphics.hpp>
#include "game.h"
Game::Game()
: mWindow(sf::VideoMode(640, 480), "SFML Application")
, mIsMovingUp(false), mIsMovingDown(false), mIsMovingLeft(false), mIsMovingRight(false)
, mPlayer()
{
mWindow.setKeyRepeatEnabled(false);
mPlayer.setRadius(40.f);
mPlayer.setPosition(100.f, 100.f);
mPlayer.setFillColor(sf::Color::Cyan);
}
void Game::run()
{
while (mWindow.isOpen())
{
processEvents();
update();
render();
}
}
void Game::render()
{
mWindow.clear();
mWindow.draw(mPlayer);
mWindow.display();
}
void Game::processEvents()
{
static sf::Event event;
if (mWindow.pollEvent(event))
{
switch (event.type)
{
case sf::Event::KeyPressed:
handlePlayerInput(event.key.code, true);
break;
case sf::Event::KeyReleased:
handlePlayerInput(event.key.code, false);
break;
case sf::Event::Closed:
mWindow.close();
break;
}
}
}
void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
if (key == sf::Keyboard::W)
mIsMovingUp = isPressed;
else if (key == sf::Keyboard::S)
mIsMovingDown = isPressed;
else if (key == sf::Keyboard::A)
mIsMovingLeft = isPressed;
else if (key == sf::Keyboard::D)
mIsMovingRight = isPressed;
}
void Game::update()
{
sf::Vector2f movement(0.f, 0.f);
if (mIsMovingUp)
movement.y -= 1.0f;
if (mIsMovingDown)
movement.y += 1.0f;
if (mIsMovingLeft)
movement.x -= 1.0f;
if (mIsMovingRight)
movement.x += 1.0f;
mPlayer.move(movement);
}
//The main function
#include <SFML/Graphics.hpp>
#include "game.h"
int main()
{
Game game;
game.run();
return 0;
}
Your problem is not connected to Ubuntu or your OS in general. The "problem" is this line in Game::Game()
mWindow.setKeyRepeatEnabled(false);
After this, if you press and hold a key, no additional key events are generated. Therefore you must release the key and press it again, to fire a new key-press event. With every key press you only move by 1.f pixel, and therefore you must press it very fast ;)
Do the additional chapters in the book and you will find more elegant solutions to this "problem". For more info google "fix your timestep".
Your problem is not connected to Ubuntu or your OS in general. The "problem" is this line in Game::Game()
mWindow.setKeyRepeatEnabled(false);
After this, if you press and hold a key, no additional key events are generated. Therefore you must release the key and press it again, to fire a new key-press event. With every key press you only move by 1.f pixel, and therefore you must press it very fast ;)
Do the additional chapters in the book and you will find more elegant solutions to this "problem". For more info google "fix your timestep".
This is not entirely the case here ;)
He sets:
mIsMovingUp;
mIsMovingDown;
mIsMovingLeft;
mIsMovingRight;
He only needs to hold it pressed(and generate only one event) to move, since they only get set to false again if he releases the respective button.As long as they are true, update will move his sprite.
The main problem is that the percieved speed is dependend on his framerate(which is why he should google for "fix your timestep" as you said.
If his driver has vsync enabled by default(@60hz for example) this would mean that he needs 18 seconds to get from one side of the screen to the other with a resolution of 1920*1080.