I'm attempting to get a picture to display by using SFML (just a test run). The program can find the picture, and open a new window, but when it opens the window it only pops up for half a second then returns with 1. Here is the code (which is just their example that I tweaked):
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
sf::Texture Texture;
sf::Sprite Sprite;
if(!Texture.loadFromFile("resources/pepe.png"));
return 1;
Sprite.setTexture(Texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(Sprite);
window.display();
}
return 0;
}
I am assuming the error is coming from the return 1; after the loading, but I don't see what is wrong. Can someone post something that worked for them or give me tips on what may be going wrong?
Your code works just fine, except for the ; after the texture loading from a file, making your program always return 1, whatever was happening before.
It's a good idea to add error messages to know what's going wrong.
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
sf::Texture Texture;
sf::Sprite Sprite;
if(!Texture.loadFromFile("resources/pepe.png")){ // there was a ; here.
// making the code below always run.
std::cerr << "Error loading my texture" << std::endl;
return 1;
}
Sprite.setTexture(Texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed){
window.close();
}
// you only get here when there is at least one event.
}
// but you always want to display to the screen.
window.clear();
window.draw(Sprite);
window.display();
}
return 0;
}
My rule of thumb is to always enclose code blocks with curly braces so you never make these kind of mistakes (or someone else changing your code is less prone to make that mistake).
Related
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
}
}
I am feeling really frustrated with draw() not working in my SFML project. My compiler gives off no errors, my eyes doesn't catch a thing that's off (as a reference I am using official tutorial). The problem is that when window load it doesn't draw a thing. It just stays a white window without any text in it.
Where could be the problem?
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(800,600), "Trying to make a game");
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
//error
}
sf::Text text;
text.setFont(font);
text.setString("Hello, World!");
text.setCharacterSize(50);
text.setColor(sf::Color::Red);
text.setPosition(10, 50);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
}
window.clear();
window.draw(text);
window.display();
return 0;
}
You're closing the window before drawing the text...
#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;
}
This is directly from the tutorial's page, and I've checked and rechecked, so I know this is not a syntax or linker error.
When I run this program, I get a window whose contents are the same as whatever the place it is located in. Yet, if I remove the window.draw(shape) command, I see a black window, like I should.
I'm compiling on Windows 7 (32 bit) using mingw32-g++.exe (4.7.1). Oh, and it's the same if I compile debug or release and static or dynamic, so that's not the problem either.
Your code is correct, but to me it looks like you need to set the position of your circle. I maybe wrong here but the position could be any value and that is why it isn't displaying.
Could you try updating your code to this please.
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
shape.setPosition(50f, 50f);
shape.setScale(2,2); // You can remove this line if you want to, I just put it there for debugging
while (window.isOpen())
{
...
Here is the SFML documentation for setPosition (http://www.sfml-dev.org/documentation/2.0/classsf_1_1Transformable.php#a4dbfb1a7c80688b0b4c477d706550208)
Here is the SFML documentation for setScale (http://www.sfml-dev.org/documentation/2.0/classsf_1_1Transformable.php#aaec50b46b3f41b054763304d1e727471)
Let me know if that fixes your problem.
so today I started looking into SFML and I found it quite interesting so decided to learn how to play with it, but I am already hitting some problems, I am trying to use textEntered event, but it is not working properly, it shows complete nonsense and text writes itself even without me pressing any key. Heres link
Code
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(400, 400), "SFML works!");
std::string display;
sf::Font font;
font.loadFromFile("arial.ttf");
sf::Text text;
text.setFont(font);
text.setCharacterSize(30);
text.setStyle(sf::Text::Bold);
text.setColor(sf::Color::Red);
text.setPosition(50, 50);
while (window.isOpen())
{
sf::Event Revent;
while (window.pollEvent(Revent))
{
if (sf::Event::TextEntered)
{
std::cout << static_cast<char>(Revent.text.unicode);
//text.setString(display);
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
window.close();
}
window.clear();
//window.draw(text);
window.display();
}
return 0;
}
You wrote if (sf::Event::TextEntered), which evaluates to true (since it's not equal to 0).
You probably meant
if (Revent.type == sf::Event::TextEntered).
Using Revent.text is undefined behavior in this case (when you're not sure what type of event Revent contains) because sf::Event is an union, so only one of its members is usable at a time. You can read more about SFML events here.
I'm trying to create a loop to draw 10 blocks on the screen, but nothing is showing. I got no error, so I think that the vector is not storing the sprites. I'm new to SFML, so I don't really know what I'm doing wrong.
sf::Texture bTexture;
sf::Texture bloqueTexture;
sf::Sprite bloqueSprite;
//create vector of blocks
std::vector<sf::Sprite> bricks(10, sf::Sprite(bloqueTexture));
fondo.setTexture(img_mgr.getImage("fondo.jpg"));
personaje.setTexture(img_mgr.getImage("jumper.png"));
personaje.setPosition(100,POSICION_TERRENO_Y);
bloqueSprite.setTexture(img_mgr.getImage("bloque.png"));
bloqueTexture.loadFromFile("Recursos/imagenes/bloque.png");
//Fill the vector with the texture
for (int i = 0; i < bricks.size(); i++)
{
bricks[i].setTexture(bloqueTexture);
bricks[i].setPosition(100 + (i * 45) , 320);
window.draw(bricks[i]);
}
2nd edit with final answer : if you want to display png files with SFML, save them 8bit.
Edit: I had some bad copy/paste in the second code, I fixed it
As SFML is made for multi media applications (mostly games), you need to refresh and draw to screen many times by second (that's frames). That being said, the basic approach is to have a main loop doing 3 things : handling inputs, updating your game logic and then drawing.
See the classic example from SFML's 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;
}
Your texture loading and filling the vector have to be done before the main loop, and then between window.clear() and window.display you need to draw everything you want to display (your blocks).
You may end up with something like this :
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::Texture bTexture;
sf::Texture bloqueTexture;
sf::Sprite bloqueSprite;
//create vector of blocks
std::vector<sf::Sprite> bricks(10, sf::Sprite(bloqueTexture));
fondo.setTexture(img_mgr.getImage("fondo.jpg"));
personaje.setTexture(img_mgr.getImage("jumper.png"));
personaje.setPosition(100,POSICION_TERRENO_Y);
bloqueSprite.setTexture(img_mgr.getImage("bloque.png"));
bloqueTexture.loadFromFile("Recursos/imagenes/bloque.png");
for (int i = 0; i < bricks.size(); i++)
{
bricks[i].setTexture(bloqueTexture);
bricks[i].setPosition(100 + (i * 45) , 320);
}
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
for (int i = 0; i < bricks.size(); i++)
{
window.draw(bricks[i];
}
// Consider doing this :
// for(const auto& brick : bricks)
// window.draw(brick);
window.display();
}
return 0;
}
I think problem is with loading textures, try to check is loadFromFile function returning true.