SDL_Event
SDL_Event
是個聯合體,是SDL中所有事件處理的核心。 SDL_Event
是SDL中使用的所有事件結構的並集。 只要知道了那個事件類型對應SDL_Event
結構的那個成員,使用它是一個簡單的事情。
下表羅列了所有SDL_Event
的所有成員和對應類型。
Uint32 | type | event type, shared with all events |
---|---|---|
SDL_CommonEvent | common | 常見事件數據 |
SDL_WindowEvent | window | |
SDL_KeyboardEvent | key | 鍵盤事件數據 |
SDL_TextEditingEvent | edit | 文本編輯事件數據 |
SDL_TextInputEvent | text | 文本輸入事件數據 |
SDL_MouseMotionEvent | motion | 鼠標運動事件數據 |
SDL_MouseButtonEvent | button | 鼠標按鈕事件數據 |
SDL_MouseWheelEvent | wheel | 鼠標滾輪事件數據 |
SDL_JoyAxisEvent | jaxis | 操縱桿軸事件數據 |
SDL_JoyBallEvent | jball | 操縱桿球事件數據 |
SDL_JoyHatEvent | jhat | 操縱桿帽子事件數據 |
SDL_JoyButtonEvent | jbutton | 操縱桿按鈕事件數據 |
SDL_JoyDeviceEvent | jdevice | 操縱桿設備事件數據 |
SDL_ControllerAxisEvent | caxis | 遊戲控制器軸事件數據 |
SDL_ControllerButtonEvent | cbutton | 遊戲控制器按鈕事件數據 |
SDL_ControllerDeviceEvent | cdevice | 遊戲控制器設備事件數據 |
SDL_AudioDeviceEvent | adevice | 音頻設備事件數據(> = SDL 2.0.4) |
SDL_QuitEvent | quit | 退出請求事件數據 |
SDL_UserEvent | user | 自定義事件數據 |
SDL_SysWMEvent | syswm | 系統相關的窗口事件數據 |
SDL_TouchFingerEvent | tfinger | 觸摸手指事件數據 |
SDL_MultiGestureEvent | mgesture | 多指手勢數據 |
SDL_DollarGestureEvent | dgesture | 多指手勢數據 |
SDL_DropEvent | drop | 拖拽事件數據 |
SDL_Event
聯合體包含了外界操作SDL的幾乎所有操作時間,所以成員稍微有點多。選了幾個簡單的聯合體成員分析一下:
/**
* \brief Fields shared by every event
*/
typedef struct SDL_CommonEvent
{
Uint32 type; // 事件類型
Uint32 timestamp; // 以毫秒爲單位,使用SDL_GetTicks()填充
} SDL_CommonEvent;
/**
* 鍵盤按鈕事件結構(event.key)
*/
typedef struct SDL_KeyboardEvent
{
Uint32 type; // 事件類型:按下按鍵,按鍵彈起(SDL_KEYDOWN or SDL_KEYUP)
Uint32 timestamp; // 以毫秒爲單位,使用SDL_GetTicks()填充
Uint32 windowID; // 具有鍵盤焦點的窗口id
Uint8 state; // SDL_PRESSED or SDL_RELEASED
Uint8 repeat; // 如果這是重複鍵,則非零
Uint8 padding2;
Uint8 padding3;
SDL_Keysym keysym; // 按下或釋放的鍵
} SDL_KeyboardEvent;
SDL的所有事件都是存儲在一個隊列中,而SDL_Event
的常規操作,就是從這個隊列中讀取事件或者寫入事件。
SDL_PollEvent
SDL_PollEvent
函數便是從事件隊列中,讀取事件的常用函數。
函數原型爲:
int SDL_PollEvent(SDL_Event * event);
函數的作用是,對當前待處理事件進行輪詢。
返回值:如果時間隊列中有待處理事件,返回1;如果沒有可處理事件,則返回0。
參數event:如果不爲NULL,則從隊列中刪除下一個事件並將其存儲在該區域中。
示例代碼
鼠標移動時間的簡單處理代碼:
SDL_Event test_event;
while (SDL_PollEvent(&test_event)) {
switch (test_event.type) {
case SDL_MOUSEMOTION:
printf("We got a motion event.\n");
printf("Current mouse position is: (%d, %d)\n", test_event.motion.x, test_event.motion.y);
break;
default:
printf("Unhandled Event!\n");
break;
}
}
printf("Event queue empty.\n");
- 首先需要申明一個
SDL_Event
變量,方便輪巡事件隊列時使用。 - 通過
SDL_PollEvent()
函數獲取指向要填充事件信息的SDL_Event
結構的指針。 我們知道,如果SDL_PollEvent()
從隊列中刪除了一個事件,那麼事件信息將放在我們的test_event結構中。 - 爲了單獨處理每個事件類型,我們使用switch語句。
- 我們通常需要知道正在尋找什麼樣的事件以及這些事件的類型。 例如,在示例代碼中,我們想要檢測用戶在我們的應用程序中移動鼠標指針的位置。 我們會查看我們的事件類型,並注意到
SDL_MOUSEMOTION
很可能是我們正在尋找的事件。 查看下錶,知道SDL_MOUSEMOTION
事件是在SDL_MouseMotionEvent
結構中處理的,然後我們就可以通過SDL_MouseMotionEvent
的結構,獲得我們想要的數據,例如鼠標移動的位置x and y。