Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SFML Game Development.pdf
Скачиваний:
205
Добавлен:
28.03.2016
Размер:
4.19 Mб
Скачать

Command and Control – Input Handling

Polling events

Generally speaking, events are objects that are triggered when something happens; mostly related to the user input. Events are a construct in the underlying operating system. On top of them, SFML provides a nice abstraction layer that is easier to use and cross-platform. SFML goes with a polling design to have you work with events. When an input occurs, the operating system reports it to the application. SFML processes this input, converts it into the corresponding SFML event type, and puts it into a queue of waiting events. In your actual application code, you extract events from this queue using the sf::Window::pollEvent() function (note that sf::Window is the base class of sf::RenderWindow, without the rendering functionality). The pollEvent() function signature is a bit interesting:

bool sf::Window::pollEvent(sf::Event& event);

Now this is a bit special and might not be self-explanatory. The problem with pollEvent() is that we want to receive two different values. We want to receive the actual event and a value affirming that we got it from the list. If the second value is false, we will not receive anything.

SFML uses a common approach to a polling system, which allows us to retrieve one event instance at a time by continuously calling pollEvent() until the function returns a false value, which means there are no more events to poll. In the meanwhile, for every positive return value, we know that our sf::Event variable has been filled with important event information.

That is why in all our examples up to now, we have received events in this following fashion:

sf::Event event;

while (window.pollEvent(event))

{

// Handle the event

}

Here we poll events from the window until its internal list becomes empty. There is a waitEvent() function as well, that waits until it receives an event, but that is pretty redundant for our case, so we will not dig into that.

[ 86 ]

www.it-ebooks.info

Chapter 4

The event structure we have used so much already is built up of an enum and a union of different event structures. As a short reminder, a union is similar to struct, with the main difference that all the member variables occupy the same memory location. Therefore, only one member can be actively used at a time. Applied to sf::Event, the very nature of union grants that an event will never be two things at the same time. Depending on the value of the sf::Event::type member variable, a different union member is filled with useful data. When we receive an event, we first check the type of it, and depending on it we access the specific data. We have to be careful to access the correct union members, otherwise we risk undefined behavior.

We can group the different events to four different categories: window, joystick, keyboard, and mouse. We will try to cover each and every one of the events, but it will be near to impossible to go into too much detail, otherwise this chapter would be huge. I urge you to check out SFML's documentation for more information, in case anything is unclear on the events.

Window events

In this section, we have the window-based events which are the events that concern windows directly. I have listed them as follows, with their intended purposes and the conditions under which they are generated:

sf::Event::Closed: This event occurs when the users somehow request that they want the window closed. Mostly, this amounts to pressing the [X] button in the window, or a shortcut such as Alt + F4 on Windows. This event does not have any data associated with itself. We have already used it plenty and your application should always handle this event.

sf::Event::Resized: This event is triggered when the window is resized. Most often this is when the user drags on the edges of the window to manually resize it. The data type associated with this is sf::Event::SizeEvent and can be accessed through the member event.size. Of course, resizing the window is only possible if you have enabled it to be resized.

sf::Event::LostFocus and sf::Event::GainedFocus: These events come from the window when it gains or loses focus. Focus here means that this window is the one that the user has chosen right now and it will receive the user input. No data apart from the event type is associated with these events. These events are of interest when you want to pause the game if the user clicks outside the window or switches to another application.

[ 87 ]

www.it-ebooks.info

Command and Control – Input Handling

Joystick events

Now we have to cover the joystick-based events. These events are fired whenever a connected joystick or gamepad changes its state. Every joystick event has a data structure associated with it. A common member they all have is the ID number for the joystick. The ID is required in order to keep track of which joystick generated the event, since there can be more than one joystick. We have the following joystick events that can be generated:

Joysticks have buttons, for button-related events we have the event types sf::Event::JoystickButtonPressed and

sf::Event::JoystickButtonReleased. These are triggered when a button on the joystick is pressed or released. The data structure associated with this is sf::Event::JoystickButtonEvent with the member event. joystickButton. You should keep in mind that the buttons can be of a variable amount.

The sf::Event::JoystickMoved event is generated when the analog stick or digital cross moves; it has the structure sf::Event::JoystickMoveEvent for its data. It is accessible through the member event.joystickMove. A thing to note here is that joysticks work in axes, so the movement is measured in an axis as well. It is not guaranteed that the joysticks support all axes.

Last we have the event of when a joystick is connected or disconnected, allowing you to handle hot-plugging joysticks. The event types are sf::Event::JoystickConnected and sf::Event::JoystickDisconnected. The data type is sf::Event::JoystickConnectEvent and is accessible through the member event.joystickConnect.

Keyboard events

Now the defining feature of a PC, the keyboard. The keyboard generates events as the primary input device available to computers:

For the event when the user presses down a key, we have the event type sf::Event::KeyPressed. The data structure for this event is

sf::Event::KeyEvent, which is accessed through event.key. It holds all the data of the current state of the keyboard associated with that key press. The member variable event.key.code contains the actual key, while other members such as event.key.control are Booleans that state whether a modifier is pressed. If you hold a key for a while, multiple KeyPressed events will be triggered. This key repetition option can be deactivated using sf::Window::setKeyRepeatEnabled().

[ 88 ]

www.it-ebooks.info

Chapter 4

The event sf::Event::KeyReleased is the counterpart to KeyPressed; it is triggered when you release a key. To retrieve information about the key release, you can also access the structure sf::Event::KeyEvent via event. key—just like when a key was pressed.

Last, we have a little special event that SFML creates for your convenience. It is called sf::Event::TextEntered and is designed for receiving formatted text from the user. Using the normal key event for this is a very tedious task, so this event helps out a lot. The data structure is sf::Event::TextEvent and it is accessible through event.text.

Mouse events

Last, but not the least, we have the mouse-based events. These are generated when the state of the cursor, the mouse buttons or the mouse wheel changes:

First we have the sf::Event::MouseEntered and sf::Event:: MouseLeft events. These are triggered when the mouse cursor enters or leaves the window.

Next we consider when the cursor moves inside the window. The type for this is sf::Event::MouseMoved and its associated structure is

sf::MouseMoveEvent. You can access the data from the event.mouseMove member. The coordinates in the data structure are measured in window pixels and they are unaffected by scaling or any other transformation from your window's current view. Please notice how the Y coordinate increases as we go down. The origin of the window is always at the top-left corner and then grows up to the size of the window:

(0,0)

X

Y

 

[ 89 ]

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]