處理好來自用戶的事件是一個很重要的話題。php
首先咱們來認識一下什麼是事件?函數
通常來講,事件是在某些狀況下被觸發的對象。它們依賴於操做系統,可是 SFML 爲咱們提供了一個很好的對象來處理事件,它是獨立於操做系統的方式。sf::Event 類,這個類包含了各類事件。學習
建議閱讀 SFML 官方文檔去好好了解 SFML 事件的類型,地址是https://www.sfml-dev.org/tutorials/2.5/window-events.php。 注意 sf::Event 是一個聯合體(union),使用的時候要恰當的選擇咱們須要的事件類型。編碼
邏輯上,咱們能夠將事件分紅四種類型:spa
類型 | 相關成員 | 描述 |
---|---|---|
Event::Closed | None | 當操做系統檢測單用戶想要關閉窗口時觸發 |
Event::Resized | Event::size 表示新窗口的大小 | 當操做系統檢測單用戶想要改變窗口大小時觸發,或者調用Window::setSize() |
Event::LostFocus Event::GainedFocus | None | 當窗口失去/獲得焦點時觸發,失去焦點的窗口不會收到鍵盤事件 |
類型 | 相關成員 | 描述 |
---|---|---|
Event::KeyPressed Event::KeyReleased | Event::key 表示的事當前按住/鬆開的按鍵 | 在獲得焦點的窗口中,當一個按鈕被按下或者鬆開的時候觸發 |
Event::TextEntered | Event::text 表示的是一個字符的UTF-32 unicode | 任什麼時候候一個字符輸入的時候觸發 |
類型 | 相關成員 | 描述 |
---|---|---|
Event::MouseMoved | Event::mouseMove 表示鼠標新位置 | 當鼠標在窗口內移動時觸發 |
Event::MouseButtonPressed Event::MouseButtonReleased | Event::mouseButton 表示的是按下/鬆開的鼠標按鈕以及它的位置 | 當鼠標上的按鈕按下/鬆開的時候觸發。目前支持5種類型的按鈕:左、中、右、額外的按鈕1和按鈕2 |
Event::MouseWheelMoved | Event::mouseWheel 表示的是滾輪以及鼠標位置 | 當鼠標上的滾輪滾動時觸發 |
類型 | 相關成員 | 描述 |
---|---|---|
Event::JoystickConnected Event::JoystickDisconnected | Event::joystickConnect 表示的是手柄鏈接/斷開鏈接時的ID | 當手柄鏈接或者斷開鏈接時觸發 |
Event::JoystickButtonPressed Event::JoystickButtonReleased | Event::joystickButton 表示的是手柄上按鈕按下的數量以及手柄ID | 當手柄上的按鈕按下時觸發,SFML爲咱們提供了最多8個手柄,每一個手柄32個按鈕的支持 |
Event::JoystickMoved | Event::joystickMove 表示的是移動操縱桿的軸,操縱桿軸的位置以及手柄ID | 移動操縱桿的軸時會觸發此操做 |
對於窗口事件來講,咱們一般用 bool Window::pollEvent(sf::Event& event)
函數,若是有事件將要被使用的話,函數會返回 true
, event
參數會對應某個具體事件。==須要注意的是,同一時間下可能會有多個事件須要被處理,所以咱們須要確保捕獲到每個事件。==代碼以下:操作系統
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
}
// 刷新幀
// 繪製幀
}
複製代碼
運行上面這份代碼以後,咱們能夠作出移動窗口,改變窗口大小或者是最小化窗口這些操做,可是有一個問題,那就是咱們沒法關閉窗口。當咱們點擊窗口的關閉按鈕時,SFML 不會去關閉窗口,這一操做須要咱們去實現。code
經過 Window::pollEvent()
捕獲事件以後,咱們能夠經過 Event::type
檢查事件類型。事件類型是 Event::EventTyp
,它是 Event
類中的一個枚舉類型。使用方法以下對象
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::EventType::Closed) {
window.close();
}
}
複製代碼
調用 Window::close()
能夠關閉窗口。事件
若是咱們想要使用更多的事件,咱們的可使用 switch
語法。以下:unicode
sf::Event event;
while (window.pollEvent(event)) {
switch (event.type) {
case sf::Event::EventType::Closed:
window.close();
break;
case sf::Event::EventType::KeyPressed:
// 改變窗口標題當空格鍵按下的時候
if (event.key.code == sf::Keyboard::Key::Space)
window.setTitle("Space Pressed");
break;
case sf::Event::EventType::KeyReleased:
// 再次改變窗口標題當空格鍵鬆開的時候
if (event.key.code == sf::Keyboard::Key::Space)
window.setTitle("Space Released");
// 當 Esc 鍵鬆開的時候關閉窗口
else if (event.key.code == sf::Keyboard::Key::Escape)
window.close();
break;
default:
break;
}
}
複製代碼
上面這份代碼的意思很容易理解,經過空格鍵能夠改變窗口的標題,鬆開 Esc 鍵時關閉窗口。注意到 Event::key
包含了 code
成員,它是 Keyboard::Key
類型中的一個枚舉類型。用上面這種方法能夠處理其餘事件類型。
然而,Event::EventType::TextEntered
的使用有點意思。按鍵被按下/鬆開的時候能夠被檢測到且可使用一種相對簡單的方式去處理。可是當鍵入一些特殊字符的時候,事情變得有點複雜起來。例如,輸入 !
號的時候在大多數鍵盤中是使用 shift+1
的。幸虧 SFML 爲咱們提供了一個簡單的方式去處理,僅當按下表示字符的組合鍵時纔會發生事件,這意味着按下一個鍵(例如 shift
)時不會觸發事件。
下面這個例子使用了 TextEntered
事件組合了一個字符串,而後按下 Enter
鍵時這個字符串會顯示在窗口標題中。
sf::String buffer;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
switch (event.type) {
case sf::Event::EventType::Closed:
window.close();
break;
case sf::Event::EventType::TextEntered:
buffer += event.text.unicode;
break;
case sf::Event::EventType::KeyReleased:
if (event.key.code == sf::Keyboard::Key::Return) {
window.setTitle(buffer);
buffer.clear();
}
break;
default:
break;
}
}
}
複製代碼
這裏使用 sf::String
類型可以避免不一樣語言之間的字符編碼轉換。
這一節簡單介紹了 SFML 中的事件處理,下一節將會學習圖像以及精靈(sprite)的簡單使用。😃