How to Handle User Interactions with SFML

You can access the full course here: Discover SFML for C++ Game Development

Handling User Interactions

There are many ways in which a user can interact with your program from pressing buttons, to opening and closing windows, and even simple events like moving a mouse. Each of these interactions triggers an event which we capture within the run loop and can either choose to handle or ignore. We could spend hours covering just events but we are only really interested in three for now: closing the window, clicking a mouse button, and pressing a keyboard key, specifically, the space bar.

To handle any event, we first need to create an sf::Event object and call the function window.pollEvent(). This gathers all of the events associated with a specific window (as you can have multiple windows open at once) and will continue to return true while there are events ongoing. For example, we are already handling the window close event with this code:

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

This is only searching an event of type sf::Event::Closed, triggered when the user exits out of the current window. However, we also want to monitor mouse clicks and spacebar presses. Let’s start with mouse clicks. We can provide an else if case like this:

else if (event.type == sf::Event::MouseButtonPressed) {
  std::cout << "Mouse button pressed" << std::endl;
}

While this isn’t doing anything more than printing out “Mouse button pressed” whenever the user clicks the mouse somewhere in the window, we can see how easy it is to handle simple user events. To handle spacebar presses, we first need to detect for a KeyPressed event and then find out whether or not the key pressed was the spacebar like this:

else if (event.type == sf::Event::KeyPressed) {
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
    std::cout << "Space bar pressed" << std::endl;
  }
}

The isKeyPressed() function will return true if the key we are looking for is the one that was pressed and false otherwise. If you try pressing anything other than the spacebar, nothing will happen but the spacebar will print the message “Space bar pressed”. We can put it all together like this;

sf::Event event;
while (window.pollEvent(event)) {
  if (event.type == sf::Event::Closed) {
    window.close();
  } else if (event.type == sf::Event::MouseButtonPressed) {
    std::cout << "Mouse button pressed" << std::endl;
  } else if (event.type == sf::Event::KeyPressed) {
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) {
      std::cout << "Space bar pressed" << std::endl;
    }
  }
}

Note how all of this occurs within the run loop but before drawing anything. Typically, the first thing we do in a run loop is process and handle interactions as they may affect the state and thus the items that are drawn to the window.

Transcript

Hey everyone, welcome to a tutorial on handling user interactions. Here, we’re just going to explore a couple of the user interactions that we’ll be using in our game, how to detect them, and how to respond to them. So tasks are gonna be to first learn about how to monitor events, then we will respond to quit events, we’ve actually already took a quick look at that, then will respond to mouse clicks, and finally, to button presses. So let’s head to the code and get started.

All right, so like I said, we’ve actually already kind of covered one of the events and that is going to be the window.close. But we haven’t really covered events much in general. So we’re not gonna be creating anything outside of here for now. So in your while loop here, your main game loop, there will be a series of events that take place there could be multiple events happening at once.

For example, if the user is holding down a key and pressing their mouse, there could be lots of things happening okay? So what we do is that’s why we have a while loop because there could be multiple events, if we only do an if statement, that’s just gonna check one of them, which is not what we want. So by using the window.pollEvent, this is going to check to see if there are any events happening that are related to this particular window.

Technically, you can have multiple windows with SFML. Again, that’s a bit beyond the scope of this course. But for each new window, you want to pull events within that one.

Again, we just have the one window to work with. So that should be fine here. So you create an SF event object, and you pass it into the poll events that way we have access to it within the while loop. So here, we want to be checking to see what events are occurring, we only really need to check the ones that we’re interested in.

For example, if we’re just handling mouse clicks, we don’t need to do anything else. But at the very least, you should have this one that’s polling for the event closed, okay? Otherwise, you can run into issues with your game just continually running.

Okay, so events will have many possible types associated with it. In this case, this is the event.type SF event closed, and we’re just closing the window. Okay, we’ll also want to respond to mouse clicks. So when you click on the animate, we want to decrease some energy, and also will respond to key presses. So at the very end, when you want to restart the game, you press the space bar, and it will restart everything.

So let’s first work on the mouse clicks. What we’ll do is we’ll do an elifevent.type. I’ll actually you know what that should be an else if, and we need these. Okay, getting kind of confused with some Python code. Okay, so we’ll do this okay, and then we’ll say else if events.type is going to be equal to and here’s where we want to listen for a mouse button press. So we’ll pull the event SF event mouse button pressed.

Okay, we’re not gonna worry about the release or anything like that. We just want to check to see if the mouse button is pressed. Okay, so if the mouse button is pressed, we can pretty much do whatever we want. We’re not gonna check for collision detection or anything yet. We’ll cover that much later on in this course we will be covering it eventually though.

And for now what we can just do is print something else will stay Standard C out. We’ll say mouse button pressed, okay. And then we will do a new line, I guess. Okay, well, we can do we could actually just do the end L. So it should actually be standard endl okay.

So, if we’re checking to see if the mouse buttons pressed and we’re printing out, that’s good. We also you know, actually let’s go ahead and run this and demonstrate this. So we go to terminal clear will recompile it./main. Okay, you can see that I’m clicking on the screen, and we’re detecting the mouse button pressed is being printed out there every time.

Note how, if I’m clicking outside of the screen, nothing is registering. Now I’m kind of clicking all over the terminal right now. Nothing’s happening okay? That’s because we’re only detecting mouse clicks within this particular window. That is the desired behavior, at least for our game.

Okay, cool stuff, so we know how to detect mouse clicks. Again, we’ll get into the exact collision detection later to check to see if we’re clicking on an object, but we’ll also want to monitor keyboard presses. So we’ll do else if the event.type is gonna be equal to SF event key pressed.

Okay so we actually don’t launch immediately right into checking to see if the space bar key was pressed. What we should be checking see is if the events was a key press in general, okay, then we can go into that further and see if the key that was pressed was a space bar. And we may as well implement that logic here. We’re gonna need it later on anyway.

So we’ll say something like if SF keyboard is key pressed, and we’ll do SF, keyboard space. Okay, so just make sure that you can see the whole thing. So this might seem a little roundabout, we have to see if the keyboard is key pressed is called. And with this will take in a key to check to see if it’s pressed. Specifically, we’re just checking to see if the space bar is pressed. Okay, that key space equal to true, we’ll just print out something like space bar pressed. Space bar pressed, okay, and then we’ll end the line.

All right, so you can also check for other keys. For example, if you’re doing like a movement game where you press the arrow keys to move around, you’ll probably want to check for up arrow down, arrow left and right and so on and so forth. In case we’re only interested in if the space key is pressed, okay, so if this returns true, that means the space key is pressed, we can print out the statement.

Okay, so we’ll go again back to terminal. Let’s recompile, let’s rerun. Okay, and I’m pressing some other keys, nothing’s happening. Soon as I press space bar, then you can see that space bar is pressed. It’s also still detecting mouse clicks, and of course, it’s detecting close events as well.

All right, so that’s actually pretty much as complex as the user interaction handling is gonna go in our game. Like I said, you can make this really complex if you want, but we’re only really gonna be listening for these two commands, three if you include the window close. All right, so feel free to check out some of the other keys. See if you can implement like a little kind of movement thing if you want if you’re feeling adventurous. Otherwise, we’re gonna end the section here. When we come back, we’re going to be talking about how to monitor time is that’s going to be an important feature of our game. So stay tuned for that, thanks for watching. See you guys in the next one.

Interested in continuing? Check out the full Discover SFML for C++ Game Development course, which is part of our C++ Programming Bundle.