今天我為大家介紹一下SDL的事件處理。這里所指的事件處理就是我們通常所說的,鍵盤事件,鼠標事件,窗口事件等。
SDL對這些事件都做了封裝,提供了統一的API,下面我們就來詳細的看一下。
SDL中的事件處理
要想了解 SDL 的事件處理,我們必須要知道的一個原理是,SDL將所有事件都存放在一個隊列中。所有對事件的操作,其實就是對隊列的操作。了解了這個原理后,我們再來說SDL提供的 API 就很容易理解了。
- SDL_PollEvent: 將隊列頭中的事件拋出來。
- SDL_WaitEvent: 當隊列中有事件時,拋出事件。否則處于阻塞狀態,釋放 CPU。
- SDL_WaitEventTimeout: 與SDL_WaitEvent的區別時,當到達超時時間后,退出阻塞狀態。
- SDL_PeekEvent: 從隊列中取出事件,但該事件不從隊列中刪除。
- SDL_PushEvent: 向隊列中插入事件。
SDL只提供了這樣幾個簡單的API,下面們來介紹幾個常見的事件:
- SDL_WindowEvent : Window窗口相關的事件。
- SDL_KeyboardEvent : 鍵盤相關的事件。
- SDL_MouseMotionEvent : 鼠標移動相關的事件。
- SDL_QuitEvent : 退出事件。
- SDL_UserEvent : 用戶自定義事件。
關于事件更加詳的信息可以到 SDL Wiki 上進行查詢。現在我們來看一個使用的例子吧。
例子
在我們之前文章的例子中,大家已經發現一個問題,那就是窗口只顯示了 3 秒鐘,之后就自動消失了。
有的同學可以會通過修改代碼最后面的 SDL_Delay 函數,增加它的等待時間讓窗口多活一段時間。
但這樣的體驗實在是太糟糕了。有沒有一種好的辦法可以解決這個問題呢?能不能窗口一直顯示,直到檢測到用戶按了ctrl+c 或 使用鼠標點擊關閉按鈕后才關閉呢?
當然是可以的。我們只需要在之前的程序的末尾增加下面這段代碼即可。它會一直檢測用戶是否按下了退出按鈕。如果檢測到了,則直接退出,否則保持顯示狀態。
while(!quit){SDL_Event event;while(SDL_PollEvent(&event)){switch(event.type){case SDL_QUIT:quit = 1;break;default:SDL_Log(".");}}
}
SDL_PollEvent 與 SDL_WaitEvent
增加了上面的代碼,我們的實驗程序似乎也顯的很正規了。但有一個問題不知你發現沒有
?當我們打開任務管理器時,發現我們的程序居然占了 100% 的 CPU。My GOD!這個的結果是決對不能接受的。
是什么原因造成的呢?我們來仔細看一下我們增加的代碼吧。它由兩層 while 循環組成,最里面的while循環的意思是,當隊列中一直能取出事件,那就讓他一直做下去,直到事件隊列為空。外面的while循環的意思是,當隊列為空的時候,重新執行內部的while循環。
也就是說,這段代碼一直在工作,從不休息。所以導致cpu占到了100%。即然找到了問題的原因,我們就好處理了,只要在外層循環的最后 delay一下,讓CPU休息一下就好了。
當然,SDL還為我們提供了 SDL_WaitEvent方法,使用這個API,你的CPU就不會跑到 100%了,因為當它發現隊列為空時,它會阻塞在那里,并將CPU釋放掉。
即然有 SDL_WaitEvent了,為什么還要有SDL_PollEvent呢?這主要是由于使用的場景不同。對于游戲來說,它要求事件的實時處理; 而對于一些其它實時性不高的case來說,則可以使用 SDL_WaitEvent了。
小結
到此,本文的內容就介紹完了。在本文中主要介紹了SDL是如何處理事件的,SDL為我們提供了非常簡單的API,這大大減少了我們的開發成本。
另外,我在文章的最后,介紹了SDL_PollEvent 與 SDL_WaitEvent兩個 API的區別。這也是使用 SDL 事件處理中最容易引起困惑的地方。
粉絲福利,莬費領取Qt開發學習資料包、技術視頻,內容包括(Qt實戰項目視頻教程+代碼,C++語言基礎,C++設計模式,Qt編程入門,Qt信號與槽機制,Qt界面開發-圖像繪制,Qt網絡,Qt數據庫編程,Qt項目實戰教程,QSS,OpenCV,Quick模塊,面試題等等)↓↓↓↓↓↓見下面↓↓文章底部點擊莬費領取↓↓