Thursday, 8 May 2025

[SFML & C++] 6 - Displaying User Input/Simon Says // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++20

In this project, we'll make a simple app that generates a random string of keys the user needs to press. The user will have 5 seconds to input the keys in that order. Here's what the finished product will look like:

How To SFML Display Get User Input Simon Says Tutorial using C++ - Basic Beginner


Step 1 - Getting User Input

So we won't add the timing aspect in just yet. We'll start by creating some code to generate keys that the user needs to input. For simplicity, there will be 8 keys the computer can choose from: W A S D, and 8426 (the arrow keys if you have a number pad, if you don't have a number pad, choose keys that make sense to you).

The reason I'm not using the actual arrow keys is because they aren't considered text, they're key events, that's why I'm using the number pad.

First though, lets add a way to display what users type:



We do the usual things of creating a font and a text object to display our characters. Then we capture text entered and add it to a stream. We need to cast those events to chars otherwise it'll just display numbers.

Step 2 - Generating Keys To Press

Now, these keys for our "game" will never change (at least for this program, you may want to expand on it). So I'm going to push them back into a vector at the start of the program.


I won't be bothering with capitals in this program, but that's something you can add if you like.

Now we need to create a function that will generate our random combo and a function that will generate random numbers for us, as std::rand() isn't all that random.


Now let's display the combo to the user. I also moved the user input text object down the screen slightly, so the computer's combo is at the top.




With that done, we can move onto adding some logic to see if the combo is correct or not.

Step 3 - Checking For a Correct Combo

We can generate random combo moves and the user can give input, let's add a way to check if the input and the combo move matches and do something with that information.

Let's compare the strings when the user presses enter:


We check for the Key Release event as that is a one time event. Key Presses can happen over multiple frames depending on how fast you are. Because we check for a key release, we need to capture the 'key press' event of the enter key, otherwise it's character will be appended to our stream (which we don't want as that will mess up our combo check). Also, please excuse the magic number here. 13 is the unicode value for enter in SFML.


Step 4 - Adding A Time Limit

So to add some extra spice to our "game". Let's add in a time limit. The user has to correctly enter the combo in say 5 seconds. We'll start by adding a countdown timer to the screen. This is basically our Stopwatch but in reverse.




Now we need to use the clock and delta time to start the countdown.


Don't forget to reset the timer if enter is pressed as well:

And that's pretty much it!

How To SFML Display Get User Input Simon Says Tutorial using C++ - Basic Beginner

For the most part this is a fully functioning program. However our code is starting to get a bit "unmanageable" in the amount of places we need to keep track of what to update in text boxes and reset timers. We should really have win and loss scenarios now handling that in one place so the game is easier to modify and expand.

Exercise
Add a scoring system. Refactor to check for appropriate "win" or "lose" scenarios.

Tuesday, 6 May 2025

[SFML & C++] 5 - Stopwatch // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++20

In this project, we'll make a simple app that tracks time from when we push a start and stop button. We'll use knowledge gained from the real-time clock project and the mouse tracker. Here's what the finished product will look like:

How To SFML Stopwatch Timer Tutorial using C++ - Basic Beginner


Step 1 - Displaying Seconds Passed

We need to start off by creating the text object to store the time:




Now, let's make it increase every second. First we need something to store the elapsed time in.


Now we just need to update the elapsed time each frame, calculating the minutes, seconds, milliseconds, and then format them into our preferred string format. Unlike the real-time clock tutorial, I don't want this only updating every second as I want to see the milliseconds updating.


Using the elapsedTime variable, I calculate how much time has passed since the program started. asMilliseconds() returns a 4 digit int, I wanted to display it as 2 digits so I mod by 1000 and then divide by 10. The reasoning for this is, if the total time was say 1 minute, 23 seconds and 456 milliseconds
  • elapsedTime.asMilliseconds() would be 83,456
  • 83,456 % 1000 gives 456 (just the millisecond portion)
  • 456 / 10 gives 45 (showing only the first two digits)
std::setfill() and std::setw() are stream manipulations that control how data is formatted when output to a stream. They're very handy. Setfill() fills characters to whatever you specify (so here it's 0). Setw() sets the width of the field to the number of characters you specify. If a value takes up fewer characters, it will be padded with the fill character from setfill().

They're repeated because steam manipulators only affect the next output operation, they don't persist across multiple insertions to the stream.

Step 2 - Creating a Stop/Start Button

We now have a way of tracking how much time has passed since the program started. But that's not how stopwatches usually work. They start at 0 until you start them, so we need a button to make that happen.

There isn't a button class in SFML. The creators of the library leave those types of implementations up to the developer so they can create their own custom classes. In this tutorial, we'll make something simple that acts like a button using sf::RectangleShape.



The button doesn't do much right now and it doesn't have any text in it. Let's create another text object and render that with the button.




You might've noticed creating text objects is quite repetitive. Again, SFML doesn't abstract further from this though to give us developers freedom to create our own complex classes. At this point you could see how useful a RectangleButton class would be and the kind of things you'd need to do to create that...

Render order is also important in any 3D application. The first object you draw will be the first item that's drawn, allowing you to "draw on top" of other items. This is often referred to as the "z order".


Step 3 - Adding the Stop/Start Logic

Now we've got a button, let's do something when we press it. We know from our Mouse Tracker project that we can get the co-ordinates of the mouse, what if those co-ordinates just so happened to be where our button is and we press the left mouse button? This is basically how we check for our button presses.

Let's add a check for if LMB is pressed:

With this done, let's have a think about the logic. The app should start with a zeroed timer and only start when we press the button. If the button is pressed again, the timer stops. Press it again, it starts and continues from where it left off. This sounds like we'll need a bool to keep track of whether or not the stopwatch is running.



If you run the app now, nothing happens. Good. So let's flip that bool if LMB is pressed:


If you run the program now:
How To SFML Stopwatch Timer Tutorial using C++ - Basic Beginner

And that's pretty much a stopwatch at this point. It would be nice if it had a reset button though.

Exercise
Implement a reset button.

If you get stuck: Exercise Solutions. There are many ways to do this; this is just one way of doing it.

Friday, 2 May 2025

[SFML & C++] 4 - Mouse Tracker // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++20

In this project, we'll make a simple app that tracks the mouse movement on the screen and prints the X and Y coordinates. Here's what the finished product will look like:

How To SFML Mouse Tracking (Checking inside window) Tutorial using C++ - Basic Beginner


Step 1 - Displaying Text

So first, we need to display some text to the screen. We can do that using SF::Text.

In SFML, you need to create a font as well that you can pass to the text object, otherwise you won't be able to display anything. So let's do that as well:




Step 2 - Getting The Mouse Coordinates

Next we need to get the mouse coordinates. This is something we can do in our update section.


If you run the program now, the coordinates will update depending on where the mouse is, relative to the top left-hand corner of the window.

Your mouse can go outside of the window though and it will still report where it is on the screen. Depending on the type of app you're building, you may want to allow the mouse to go outside the screen, or you may want the window to have full focus of the mouse.

As I'm a games developer, usually the mouse should stay inside the window, so I'm going to do that.



Here I used a function on the main window itself to "lock" the mouse inside the window, whilst the window has focus. I find this to be quite annoying as I like to use most things in windowed mode, but to each their own. Grabbing the mouse may cause some issues if you have a 3D camera as the mouse may need to "go outside" the window in order to rotate the camera properly.

In the update section, I modified the code slightly to check if the window has focus, so we only display the coordinates when it does. 

Another slightly different way to do this is use some events:



Here I created a bool to track if the mouse was in the window. I then used the events sent by the library to set that bool and used that instead of checking if the window has focus. This is an approach I prefer, however it really depends on the application. Sometimes you really don't want the mouse leaving the window.

You can read more about these classes here:

Monday, 28 April 2025

[SFML & C++] 3 - Real Time Clock // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++20

In this project we'll be creating a simple app that displays the current time on your system. Here's what the finished product will look like:

How To SFML Display Real Time Clock Tutorial using C++ - Basic Beginner


Step 1 - Displaying Text

So first, we need to display some text to the screen. We can do that using SF::Text.

In SFML, you need to create a font as well that you can pass to the text object, otherwise you won't be able to display anything. So let's do that as well:




Step 2 - Getting The System Time

Go to your project settings. Make sure your C++ standard is set to 20 as we'll be using some functions from the new chrono library.


First we'll need some new header files:

Then, inside our game loop, we need to get the current time:

Now, I'm normally not a fan of using auto ( I generally just don't like type obfuscation), however, std::chrono can return some absolutely disgusting looking type names so in that case, I allow it.

So we have the current system time but it's not in any format we can display that makes sense to humans. Let's do that:


Here, I'm using C++20's std::chrono::system_clock::now() to get the current time, which is much nicer than the old C-style time functions. The localtime_s function converts our raw time value into a structured tm format that breaks down the time into hours, minutes, seconds, and other components. This is a safer version of the older localtime function. I then use a stringstream with std::put_time to format this structured time into the desired HH:MM:SS string format, which I feel is much cleaner that manually building strings.

I'm a big fan of stringstreams and you'll see me use them a lot in my code examples. Pretty much anytime I need to do string manipulation, I use stringstreams.

Compile and done!

How To SFML Display Real Time Clock Tutorial using C++ - Basic Beginner

Exercise 
As a game engine programmer, I'm all about optimisation. 

Since std::chrono::system_clock::now() always returns the current time, we always have the correct clock display regardless of the framerate. But, we're getting the time and updating the text object/doing text manipulation every frame when really we don't need to (for the purposes of this exercise anyway).

Change this program to only do the time calculations and string formatting once per second.

Hint - You can use code from my previous tutorial (Displaying the Framerate) or use SFML built in types like sf::Time.

If you get stuck: Exercise Solutions. There are many ways to do this; this is just one way of doing it.