sfml 2.3 pollEvent pauses execution - c++

int main() {
sf::RenderWindow window;
window.create(sf::VideoMode(800,600), "Game");
window.setVerticalSyncEnabled(true);
sf::CircleShape shape(100.f,5);
shape.setFillColor(sf::Color::Green);
shape.setPosition(400,300);
while (window.isOpen())
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
shape.move(0,-5);
}
sf::Event event;
while (window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
window.close();
break;
default:
break;
}
}
window.clear();
window.draw(shape);
window.display();
}
}
I'm running debian 8 and trying to make things using c++ and sfml. Whenever I have a pollEvent loop, my while(window.isOpen()) loop waits for an event, therefore the entire thing is unusable. I am aware there are similar questions to mine, but none of their solutions work for me.

Related

Sfml lostFocus / gainedFocus cpu usage

Why when I run this simple code and just doing nothing CPU usage by this app is around 0.4%
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 800), "hi", sf::Style::Close | sf::Style::Titlebar);
window.setFramerateLimit(60);
sf::Event event;
bool lostFocus = false;
while (window.isOpen())
{
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
else if (event.type == sf::Event::LostFocus)
lostFocus = true;
else if (event.type == sf::Event::GainedFocus)
lostFocus = false;
}
if (!lostFocus)
{
window.clear(sf::Color::White);
window.display();
}
}
}
But when I click on other app, CPU usage by this app increases to 12%.
Does GainedFocus actually eat so much cpu power or what?
(I just wanted to make a simple pause of game and saw this cpu usage)
As already mentioned, when your window doesn't have focus and you're not updating the window, the loop goes into a hot spin where it's continuously checking for events. When you've lost focus, you instead want to block and wait for a GainedFocus event to occur. As a very simple example, you could do something like
void block_until_gained_focus(sf::Window& window) {
sf::Event event;
while (true) {
if (window.waitEvent(event) && event.type == sf::Event::GainedFocus) {
return;
}
}
}
Then your main game loop could look something like
while (window.isOpen())
{
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
else if (event.type == sf::Event::LostFocus)
wait_until_gained_focus(window);
}
window.clear(sf::Color::White);
window.display();
}
Now if you wanted to do additional work while focus is lost you'll need a different implementation, but the key here is to use waitEvent instead of pollEvent.

SFML Window Resizing is very ugly

When I resize my sfml window, when I cut resize to make it smaller and resize to make it larger, it gives you a really weird effect.
How do I make the resizing more prettier? The code is from the installation tutorial for code::blocks.
Code (same as the code in the installation tutorial for code::blocks on the sfml website):
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
You need to manage the resize of the window. Otherwise the coordinates are wrong. Here is an excerpt of your code with the solution. Credits go to the author of this forum post, this is where I once found it when I was looking for a solution: https://en.sfml-dev.org/forums/index.php?topic=17747.0
Additionally you can set the new coordinates based on the new size. The link gives you more information.
// create own view
sf::View view = window.getDefaultView();
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::Resized) {
// resize my view
view.setSize({
static_cast<float>(event.size.width),
static_cast<float>(event.size.height)
});
window.setView(view);
// and align shape
}
}

Trying to make Animated Sprite Class; Sprite Won't Move

So, I was trying to create a class in C++ for an animated sprite that uses spritesheets for input, and when trying to move the sprite, it just sort of bounces back. It won't save to the position.
I tried using .setPostion() but that still bounces back to where it was. I have no other methods of moving the sprite implemented, nor updating it or anything else. The part in concern in the member function run, which is void is:
//if statement
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
curranim[2] = Right;
playerSprite.setPosition(playerSprite.getPosition().x + walkingSpeed, 0);
}
window.draw(playerSprite);
//spritesheet.cpp ends here
Now here is my main function:
int main()
{
sf::RenderWindow Window(sf::VideoMode(900, 600), "RPG");
animsprite sprite("dragon.png", 1, Window);
sprite.setWalkSpeed(10);
sf::Event Event;
while (Window.isOpen())
{
while (Window.pollEvent(Event))
{
switch (Event.type)
{
case sf::Event::Closed:
Window.close();
break;
}
}
Window.clear();
sprite.run(Window);
Window.display();
}
return 0;
}
Will I be stuck to repeating my code forever or is there a fix?

Render issues when resetting mouse position inside of a switch case with sfml

I'm making a basic breakout game using SFML in order to familiarize myself with C++ (moving up from C). Inside the game loop, I've placed an event poll that leads to a switch statement. When the mouse is moved, the switch-case will retrieve the mouse xy change and move the paddle accordingly, like so:
while (window.isOpen())
{
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (event.key.code)
{
case sf::Keyboard::Escape:
window.close();
break;
}
break;
case sf::Event::MouseMoved:
paddle.move(sf::Vector2f((sf::Mouse::getPosition(window).x - windowOffset.x) * sensitivity, 0));
break;
}
}
sf::Mouse::setPosition(windowOffset, window);
window.clear();
window.draw(paddle);
window.display();
}
Now, that works just fine and dandy, but I'm resetting the mouse position to the center of the window on every loop, which isn't necessary if the mouse hasn't moved. So, I tried moving sf::Mouse::setPosition() into the switch statement, underneath paddle.move, like so:
case sf::Event::MouseMoved:
paddle.move(sf::Vector2f((sf::Mouse::getPosition(window).x - windowOffset.x) * sensitivity, 0));
sf::Mouse::setPosition(windowOffset, window);
break;
However, when I rebuild the project, I now get a blank white window.
So, my question is: What's causing this to happen?
edit(minimal complete code)
int WinMain()
{
sf::Vector2i windowRes(700, 900);
sf::Vector2i windowOffset(350, 450);
sf::ContextSettings settings;
sf::RectangleShape paddle;
paddle.setSize(sf::Vector2f(150, 20));
paddle.setOrigin(350, 0);
paddle.setPosition(350, 825);
sf::RenderWindow window(sf::VideoMode(windowRes.x, windowRes.y), "Breakout", sf::Style::Default, settings);
window.setMouseCursorVisible(false);
sf::Mouse::setPosition(windowOffset, window);
sf::Event event;
while (window.isOpen())
{
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (event.key.code)
{
case sf::Keyboard::Escape:
window.close();
break;
}
break;
case sf::Event::MouseMoved:
paddle.move(sf::Vector2f((sf::Mouse::getPosition(window).x - windowOffset.x), 0));
//sf::Mouse::setPosition(windowOffset, window);
break;
}
}
sf::Mouse::setPosition(windowOffset, window);
window.clear();
window.draw(paddle);
window.display();
}
return 0;
}
So, through some tinkering, it seems that sf::MOUSE::setposition() generates an event.type of sf::Event::MouseMoved, which would be added to the event queue, causing an infinite loop.

KeyRelease Event not fired in fullscreen mode

Just like the title says, KeyRelease events aren't fired at all in fullscreen mode on Mac OS X (haven't tested Linux/Windows, may be broken as well).
Here's the code:
sf::ContextSettings settings;
settings.antialiasingLevel = 8;
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "My Game", sf::Style::Fullscreen, settings);
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(true);
window.setMouseCursorVisible(false);
while (window.isOpen())
{
while (window.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed) {
window.close();
}
if (event.type == sf::Event::KeyPressed) {
switch (event.key.code) {
case sf::Keyboard::Escape: // Escape pressed : exit
window.close();
break;
default:
game->handleKeyCode(event.key.code);
break;
}
} else if(event.type == sf::Event::KeyReleased) {
printf("KeyRelease Fired!\n");
}
}
}
If I don't use fullscreen mode, and instead initialize the window like so, the KeyRelease event works just fine:
sf::RenderWindow window(sf::VideoMode(1400, 950), "My Game", sf::Style::Default, settings);
A recent commit fix this. Compiling SFML from its git should solve this issue. See the official tutorial for more details about the compilation.