Hope Game
Logo Glusoft
Glusoft
Become a Patron! Buy me a coffee!

First program

First program SFML

In this tutorial we will do something more elaborate than a Hello World program.


For that we want the program to be able to move an image across the window, diplay a text and play some music !
The image will not be an animation, this is a first simple program not a procedurally generated MMORPG game ;).

Assets

You will need to have some assets for the program, a music and a sprite:

Initilization

The window

We can start by creating the window for the program :

sf::RenderWindow window(sf::VideoMode(400, 150), "First Program");

The Texture

Then we can load the texture earthworm-jim.png, it's very easy.
If the texture is not found we return -1 and exit the program.

sf::Texture tex;
if (!tex.loadFromFile("earthworm-jim.png"))
	return -1;

We cannot display the texture on the screen, we need to create a sprite with the texture, for that:

sf::Sprite spr;
spr.setTexture(tex);
spr.setPosition(0, -45);

As you can see we can specify the position of the sprite on the screen, the screen coordinate start at (0, 0) the top left and the max point is (400, 150) at the bottom right.

Window coordinate SFML

The music

For the music you only need to load and play !

sf::Music music;
if (!music.openFromFile("earthworm-jim-music-new-junk-city.ogg"))
	return -1; // error

music.play();

Main program

In the main program we want to display the sprite but moving, for that we need to update the position of the sprite in the main loop, but not every frame, the player will be too fast. For that we need to count the number of frames and maybe every 10 frames update the position.


What if the sprite exit the screen, meaning the x position is greater than 400, well in this case we will not see the sprite so we need to reset the position.

int counter = 0;

	while (window.isOpen()) {
		sf::Event ev;
		while (window.pollEvent(ev)) {
			if (ev.type == sf::Event::Closed)
				window.close();
		}

		window.clear();

		if (counter >= 10) {
			float newPosX = spr.getPosition().x + 1;
			if (newPosX >= 400)
				newPosX = -(float)spr.getTexture()->getSize().x;

			spr.setPosition(newPosX, spr.getPosition().y);
			counter = counter - 10;
		}
		
		window.draw(spr);
		window.display();
		counter++;
	}

In this code there is a small part to handle event such as exiting the windows when we click on the red cross:

sf::Event ev;
while (window.pollEvent(ev)) {
	if (ev.type == sf::Event::Closed)
		window.close();
}

The main loop will always looks something like this :

window.clear();	
window.draw(spr);
window.display();

In this case it's a little bit more complicated because we count the number of frame with counter and then update the position:

if (counter >= 10) {
	float newPosX = spr.getPosition().x + 1;
	if (newPosX >= 400)
		newPosX = -(float)spr.getTexture()->getSize().x;

	spr.setPosition(newPosX, spr.getPosition().y);
	counter = counter - 10;
}

Why not reset the x position at 0 but -(float)spr.getTexture()->getSize().x
Because the texture cooordinate start at the top left corner, if this is confusing, try using newPosX = 0; and see what happen !
It's always more clear with an example!

Full source code


If you don't care about the explanations here is the full source code:

#include "SFML/Graphics.hpp"
#include "SFML/Audio.hpp"

int main() {
	sf::RenderWindow window(sf::VideoMode(400, 150), "First Program");

	sf::Texture tex;
	if (!tex.loadFromFile("earthworm-jim.png"))
		return -1;

	sf::Sprite spr;
	spr.setTexture(tex);
	spr.setPosition(0, -45);

	sf::Music music;
	if (!music.openFromFile("earthworm-jim-music-new-junk-city.ogg"))
		return -1; // error

	music.play();
	int counter = 0;

	while (window.isOpen()) {
		sf::Event ev;
		while (window.pollEvent(ev)) {
			if (ev.type == sf::Event::Closed)
				window.close();
		}

		window.clear();

		if (counter >= 10) {
			float newPosX = spr.getPosition().x + 1;
			if (newPosX >= 400)
				newPosX = -(float)spr.getTexture()->getSize().x;

			spr.setPosition(newPosX, spr.getPosition().y);
			counter = counter - 10;
		}
		
		window.draw(spr);
		window.display();
		counter++;
	}

	return 0;
}
Dark theme