SFML - fluid screen update? - c++

i'm starting with sfml 2.1 but i cant find how to make the program to run fluidly
i mean, the program its working but unless i do something, like pressing a button or moving the mouse, the main loop wont run,
here is an example for my main loop code
window.setFramerateLimit(30); // set max fps to 30
while (window.isOpen())
{
// this code ignores the framerate limit and doesnt runs when an event is found
while (window.pollEvent(event))
{
// this code works fine but it wont run unless the user presses a key or moves the mouse
}
}
any ideas?

The main loop does run, you aren't doing anything in it.
From the tutorials for 2.1:
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
// clear the window with black color
window.clear(sf::Color::Black);
// draw everything here...
// window.draw(...);
// end the current frame
window.display();
}

Related

Detecting if a touch pressed, not if its down?

i will make a beat em up game with sfml c++ on mobilephone. So i need to use the Touch function. The problem I have is, what is the best way to detect when the Touch has been pressed, and only execute the code which should be executed when the key has been pressed once? I need it for an animation when the Player make a kick. Now its always repeating the spritesheet animation loop, i wanna fix that, here is the a piece if my code where i need it:
...
if(animHit == true){
if(plrClock.getElapsedTime().asSeconds() > 0.1)
{
animRec.x ++;
if(animRec.x * 103 >= plrtex.getSize().x)
animRec.x = 0;
plrClock.restart();
}
}
FloatRect touchButtonRect = btnSprite.getGlobalBounds();
// the Touch is pressed the button
if(touchButtonRect.contains(worldPos)){
animHit = true;
}
else
{
if(animRec.x * 412<= plrtex.getSize().x){
animHit = false;
}
}
You haven't shown the minimal amount of code needed to replicate the problem, but i think i know where the problem lies. You most likely are trying to get the touch in the while loop without any events. Events are the things that tell your program to run things at, well, a trigger of sorts. This trigger can be a mouse click, resize of window, keyboard buttons or touch events.
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
using namespace std;
using namespace sf;
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
window.setFramerateLimit(60);
// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
if(event.type == sf::Event::Closed) window.close();
if (event.type == sf::Event::TouchBegan)
{
//do something
}
if (event.type == sf::Event::TouchEnded)
{
//do something
}
if (event.type == sf::Event::TouchMoved)
{
//do something
}
}
// clear the window with black color
window.clear(sf::Color::Black);
// draw everything here...
// end the current frame
window.display();
}
return 0;
}
With events you can use the triggers really well such as a screen touch. Using touchBegan it will record the single screen touch, even if you hold down the touch it will still be considered single touch.
Hope this helped.

C++ SFML Text flickers when drawn

I have an SFML RenderWindow, and when it closes, it'll display a confirmation message. I've run into this same problem a lot of times: the confirmation message (an sf::Text) is drawn when the Event::Closed is called, but it only stays when the event is called; I think till the click on the close button is registered (calling the close event); disappears in a flash (does that have something to do with the speed of C++?). How can I solve this? The text should be displayed after it's drawn, and shouldn't disappear, after calling the close event.
Here is the code (in main.cpp):
while (app.isOpen())
{
// Process events
sf::Event event;
while (app.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
{
app.clear();
Text close("Are you sure you want to close this?", Arial);
app.draw(close);
close.setCharacterSize(40);
close.setPosition(300, 300);
app.display();
}
}
// Clear screen
app.clear();
// Draw the sprite
app.draw(sprite);
app.draw(text);
text.setPosition(500, 500);
// Update the window
app.display();
}
The workaround gives me an error:
I made a function to do the work, but it gives me this error:
error: use of deleted function 'sf::RenderWindow::RenderWindow(const sf::RenderWindow&)'.
Here is the code. What am I doing wrong?
Keep an explicit variable with the state of the game, and change your game code based on that:
enum class GameState { Playing, Closing };
GameState phase = GameState::Playing;
while (app.isOpen()) {
// Process events
sf::Event event;
while (app.pollEvent(event)) {
// Close window : exit
if (event.type == sf::Event::Closed) {
phase = GameState::Closing;
}
}
// Clear screen
app.clear();
if (phase == GameState::Closing) {
Text close("Are you sure you want to close this?", Arial);
close.setCharacterSize(40);
close.setPosition(300, 300);
app.draw(close);
} else if (phase == GameState::Playing) {
app.draw(sprite);
app.draw(text);
text.setPosition(500, 500);
}
// Update the window
app.display();
}

SFML RenderWindow taking inconsistent time to display

I started a project a few days ago to get to grips with SFML. When I was working on it then, the main sf::RenderWindow constructor would be called instantly. Now that I've come back to the project, it's taking up to 42 seconds in Debug mode to continue beyond the sf::RenderWindow constructor function.
So whenever I run the console appears and 40 seconds later the RenderWindow will appear.
It can't be my computer specifications as I have a very high end PC.
Here's the code in my main function:
int main()
{
sf::RenderWindow window(sf::VideoMode(960, 640), "proj v0.0.1");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear(sf::Color::Black);
window.display();
}
return 0;
}
I'm honestly just very confused as to why there's such a long delay and it's making testing new features very difficult.

SFML won't open a window?

So, as the title suggests, I am trying to create a simple Window using SFML 1.6 in CodeBlocks (MinGW v.4.7.0) on Windows 7 (no, I'm not using an ATI GPU).
This is the code:
#include <SFML/Window.hpp>
int main()
{
sf::Window App(sf::VideoMode(800, 600, 16), "SFML Window");
App.Display();
return 0;
}
Whenever I try to run this code, it just says Program.exe is not responding and has to be shutdown using Close this program. The funny thing is, the first tutorial offered on the SFML tutorial website (the one utilizing sf::Clock in a console) works, so the libraries are loaded properly.
Can someone help me find the cause of the error I'm getting?
Other than the crash, I get no compiler or application errors.
The problem is that you haven't created the main loop which polls for events and handles OS messages. Append this to main() (yes, this is a snippet from the SFML documentation):
while (App.IsOpened())
{
// Process events
sf::Event Event;
while (App.GetEvent(Event))
{
// Close window : exit
if (Event.Type == sf::Event::Closed)
App.Close();
}
// Clear the screen
App.Clear();
// Put your update and rendering code here...
// Update the window
App.Display();
}
It is therefore not necessary for you to call App.Display() after you create the window.
For those who want the whole thing, this is a snippet extracted from the SFML website.
#include <SFML/Window.hpp>
int main()
{
sf::Window window(sf::VideoMode(800, 600), "SFML Window");
// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
}
return 0;
}
You will get:

Moving a sprite and handling events

I'm learning the SFML library at the moment but I'm a little lost on moving the sprite. Here's my main.cpp file:
#include <SFML/Graphics.hpp>
int main()
{
// Create the main window
sf::RenderWindow App(sf::VideoMode(800, 600), "SFML window");
// Load a sprite to display
sf::Texture Image;
if (!Image.LoadFromFile("cb.bmp"))
return EXIT_FAILURE;
sf::Sprite Sprite(Image);
// Define the spead of the sprite
float spriteSpeed = 10.f;
// Start the game loop
while (App.IsOpened())
{
// Process events
sf::Event Event;
while (App.PollEvent(Event))
{
// Close window : exit
if (Event.Type == sf::Event::Closed)
App.Close();
if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Up))
Sprite.Move(spriteSpeed * App.GetFrameTime(), 0);
}
// Clear screen
App.Clear();
// Draw the sprite
App.Draw(Sprite);
// Update the window
App.Display();
}
return EXIT_SUCCESS;
}
But I get really slow, inconsistent movements, why isn't the sprite moving steadily around the screen? Also, seeing as how I plan to use the mouse to control the character how will I use the loop to make the character move towards where the user clicks?
You shouldn't be checking if the key is held down in the event loop.
SFML only posts one event when the key is first pressed down, and then another event when the key is released. In this case, your code is only checking if the key is held when an event occurs (such as moving your mouse, clicking, or anything else).
Moving the IsKeyPressed check out of the event loop, preferably below it, should fix the issue.
Making the sprite move towards your mouse is a more complicated issue, better suited for the Game Development StackExchange.