Showing posts with label timer. Show all posts
Showing posts with label timer. Show all posts

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, 19 November 2021

C++ & SFML // Simple Event Queue System with Timings

In a previous post (C++ & SFML // Simple Timer), I showed how you can create a simple timing system in SFML to display messages on the screen.

In this one I created a very simple "Messaging Dispatcher" that receives messages and displays them. I followed along with the Ring Buffer design by Robert Nystrom in "Game Programming Patterns" to create this little demonstration.

C++ & SFML // Simple Event Queue System with Timings

Here, when E is released, it fires a message to the dispatcher. Each message has a random time to display between 1 and 4 seconds.

The code can be found here:

There are a few caveats with this simple system:
  • The queue is a fixed size so it will reject messages when full,
  • The queue doesn't create an empty slot until the top message has finished displaying; if this was set to display for 5 minutes and all the other messages in the queue only want to display for 1 second, the queue will be held up waiting for the top message to finish.
  • The dispatcher shouldn't really be handling the time.
  • Everything is passed by value.
All these things are fixable with some brain power but getting the first implementation out of the way is key to figuring the fixes out. For the next step, it would make sense to create a class that handles the updating and displaying of the messages that it receives from the dispatcher. This way the dispatcher only has to worry about getting the messages to the right place each update.

As the class is static, you could have anything send messages to the dispatcher. it could also be modified to display sprites or play sounds (although I would define a set of events as enums instead of sending the sprite/sound itself).

The code may look a little odd in the dispatcher but the above link to the chapter in Robert's book explains what it's doing far better than I will be able to.

Thursday, 18 November 2021

C++ & SFML // Simple Timer

So I'm currently working my way through making a clone of Space Invaders using SFML and I got to the point where I needed to do something after X amount of seconds. Usually I use FLTK and that would've been simple using it's callback system however SFML is event based and as such doesn't really supply a "timer system" out of the bag like fltk.

Therefore I googled and eventually found pieces of what I was looking for and managed to put this simple demonstration together for those who just want to figure out how to get seconds displayed on the screen. This is what the "tutorial" will give you:

C++ & SFML // Simple Timer displaying seconds passed

The program does 2 things:
1) Display the number of seconds since the program started
2) Every second it chooses a random message (from 4) to display.

Very exciting. Let's begin.

Here is the full code:

Have a look, it's all in main for simplicity. 

There is a clock that is restarted at the beginning of the main loop and assigned to DeltaTime.
SFML have handily provided a way to get the DeltaTime as seconds. All you have to do then is += that to a variable defined outside the loop and you have your seconds since the program started.

For the text, I just made a variable that holds the max time we want to show the text for (maxDelay) and another variable to hold the elapsedTime. Getting the elapsed time is the same as getting the seconds above only when updating which message to display, there is a check to see if the elapsed time has gone above the max delay. If so, it changes the message and resets the elapsed time back to zero.

The concepts here can be used for many other things like displaying a sprite for a given amount of time as well creating more complicated things, like an event queue system that dispatches events based on the elapsed time (much more useful for larger projects than above).

for an example on how this can be put together.

Monday, 14 September 2020

Chapter 16 // Exercise 7 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 7

Using the techniques developed in the previous, make an image of an airplane "fly around" in a window. Have a "Start" and a "Stop" button.

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%207


As I learnt in the last exercise; FLTK does not directly support rotating images (it is something that you need to implement yourself and well... I can't be bothered). So, this is a very "basic" implementation of just moving a png image round the window.

FLTK does support image mirroring however it's when using its Direct Draw functions which we're not using. So, I have two images and the images are switched out when at certain angles for added "realism". Disgustingly hacky but there you go. Stopping and starting the plane is quite simple. I just moved adding the timeout to start and then removing it on stop.

Chapter 16 // Exercise 7 - Principles & Practice Using C++


I used an ellipse for the "track" as it has the useful functions getPointDirection() and getPointOnEllipse(). Ellipse could easily be switched out for a super ellipse though and given random values for the plane to follow random tracks. 

I take all the captures using the windows game bar, it seems to add blips for some reason. The program runs smoothly though.


Sunday, 13 September 2020

Chapter 16 // Exercise 6 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and modified versions of the graphics files used throughout the chapters. You can find those versions through the link below.

Chapter 16 // Exercise 6

Make an "analog clock," that is, a clock with hands that move. You get the time of day from the operating system through a library call. A major part of this exercise is to find the functions that give you the time of day and a way of waiting for a short period of time(e.g., a second for a clock tick) and learn to use them based on the documentation you found. Hint: clock(), sleep().

Github: https://github.com/l-paz91/principles-practice/tree/master/Chapter%2016/Exercise%206


The most annoying thing about this exercise was learning that FLTK doesn't support rotating images. There is a way to implement it yourself but it involves getting all the pixel data and shifting it yourself to the new location and I can't be bothered. So I ended up just using some arrows which don't look great but they do the job.

Next I implemented the clock moving. It has three hands; one for hours, minutes and seconds. They use the C struct tm* which handily contains the current date in nice formats. AnimatedClock is its own shape and pretty much handles itself. ClockWindow has a member variable of type AnimatedClock and then ticks every second. In the gif, my PC clock was at 13:38 when I started the recording:



Originally I was trying to use Sleep(), which is a function specific to Windows that pauses the program for a given amout of milliseconds. This did not work how I wanted it to. FLTK has it's own built in timer system called Fl::Wait, we've already used it a few times before. I had a look at the documentation to see if there was a version of wait that takes in a "time value" and there is:
https://www.fltk.org/doc-1.4/classFl.html#af49654e35a0b636aa751dce5ff88a7f5

Here it mentions idle callbacks (i.e our button presses) and elapsed timeouts. I had another look round the documentation for what this meant and  found this:
https://www.fltk.org/doc-1.3/classFl.html#a23e63eb7cec3a27fa360e66c6e2b2e52

The two functions we are interested in are Fl::add_timeout and Fl::repeat_timeout. Using these are somewhat similar to registering tick functions in UE4 (the concept is essentially the same).

Fl::add_timeout requires 3 arguments; a time in seconds, a callback function and a reference to the object. So first, we register the new timeout in the constructor of our window:
(void*)this is very important otherwise on the next tick, fltk will not know what object you are referring to and you will most likely get a runtime error saying you are trying to access a nullptr.

We now create the call back function:
As standard we cast the given address to our window type and call the function we want calling when our timer elapses. The next line calls Fl::repeat_timeout, this is because Fl::add_timout is a oneshot and as such it will only be called once so we tell fltk to repeat the timeout every given time. This is useful because you might want it initially to go off for 1 second but then check every 10. We give it the callback function and use addr to specify our object. addr contains the address of this (our window) which we passed in in the constructor.