Pygame詳解(四):event 模組
pygame.event
用於處理事件與事件佇列的 Pygame 模組。
函式
- pygame.event.pump() — 讓 Pygame 內部自動處理事件
- pygame.event.get() — 從佇列中獲取事件
- pygame.event.poll() — 從佇列中獲取一個事件
- pygame.event.wait() — 等待並從佇列中獲取一個事件
- pygame.event.peek() — 檢測某型別事件是否在佇列中
- pygame.event.clear() — 從佇列中刪除所有的事件
- pygame.event.event_name() — 通過 id 獲得該事件的字串名字
- pygame.event.set_blocked() — 控制哪些事件禁止進入佇列
- pygame.event.set_allowed() — 控制哪些事件允許進入佇列
- pygame.event.get_blocked() — 檢測某一型別的事件是否被禁止進入佇列
- pygame.event.set_grab() — 控制輸入裝置與其他應用程式的共享
- pygame.event.get_grab() — 檢測程式是否共享輸入裝置
- pygame.event.post() — 放置一個新的事件到佇列中
- pygame.event.Event() — 建立一個新的事件物件
- pygame.event.EventType — 代表 SDL 事件的 Pygame 物件
Pygame 通過事件佇列控制所有的時間訊息。該模組中的程式將幫你管理事件佇列。輸入佇列很大程度依賴於 pygame 的 display 模組。如果 display 沒有被初始化,顯示模式沒有被設定,那麼事件佇列就還沒有開始真正工作。
常規的佇列是由 pygame.event.EventType 定義的事件物件的組成,有多種方法來訪問裡邊的事件物件:從簡單的檢測事件是否存在,到直接從棧中獲取它們。
所有事件都有一個型別識別符號,這個識別符號對應的值定義在 NOEVENT 到 NUMEVENTS 之間(溫馨提示:類似於 C 語言的巨集定義,明白?)。使用者可以自行定義事件,但型別識別符號的值應該高於或等於 USEREVENT。
獲取各種輸入裝置的狀態,推薦你直接通過它們相應的模組(mouse,key 和 joystick)提供的函式訪問,而不是通過事件佇列; 如果你使用此函式,請記住,Pygame 需要通過一些方式與系統的視窗管理器和平臺的其他部分進行通訊。為了保持 Pygame 和系統同步,你需要呼叫 pygame.event.pump() 確保實時更新,你將在遊戲的每次迴圈中呼叫這個函式。
事件佇列提供了一些簡單的過濾。通過阻止某些事件進入事件佇列,可以略微提高遊戲的效能(溫馨提示:因為這樣事件佇列的尺寸就會小一些,所以說可以略微提升效能)。使用 pygame.event.set_allowed() 和 pygame.event.set_blocked() 來控制某些事件是否允許進入事件佇列。預設所有事件都會進入事件佇列。
事件子系統應該在主執行緒被呼叫。如果你希望從其他執行緒中投遞事件訊息進入事件佇列,請使用 fastevent 包。
Joysticks(遊戲手柄)只有在裝置初始化後才會傳送事件。
一個 EventType 事件物件包含一個事件型別識別符號和一組成員資料(事件物件不包含方法,只有資料)。EventType 物件從 Python 的事件佇列中獲得,你也可以使用 pygame.event.Event() 函式建立自定義的新事件。
由於 SDL 的事件佇列限制了事件數量的上限(標準的 SDL 1.2 限制為 128),所以當佇列已滿時,新的事件將會被扔掉。為了防止丟失事件訊息,尤其是代表退出的輸入事件(因為當用戶點選退出按鈕沒有反應,往往會被認為“宕機”了),你的程式必須定期檢測事件,並對其進行處理。
為了加快事件佇列的處理速度,可以使用 pygame.event.set_blocked() 函式阻止一些我們不關注的事件進入佇列中。
所有的 EventType 例項物件都擁有一個事件型別識別符號,屬性名是 type。你也可以通過事件物件的 __dict__ 屬性來完全訪問其他屬性。所有其他成員屬性的值都是通過事件物件的字典來傳遞。
在做除錯和實驗時,你可以列印事件物件以及相應的型別和成員。來自系統的事件都有一個事件型別和對應的成員屬性,下邊是每個事件型別以及對應的成員屬性列表:
事件型別 |
成員屬性 |
QUIT | none |
ACTIVEEVENT | gain, state |
KEYDOWN | unicode, key, mod |
KEYUP | key, mod |
MOUSEMOTION | pos, rel, buttons |
MOUSEBUTTONUP | pos, button |
MOUSEBUTTONDOWN | pos, button |
JOYAXISMOTION | joy, axis, value |
JOYBALLMOTION | joy, ball, rel |
JOYHATMOTION | joy, hat, value |
JOYBUTTONUP | joy, button |
JOYBUTTONDOWN | joy, button |
VIDEORESIZE | size, w, h |
VIDEOEXPOSE | none |
USEREVENT | code |
事件支援等值比較。如果兩個事件具有相同的型別和屬性值,那麼認為兩個事件是相等的。(Pygame 1.9.2 新增加的)
函式詳解
pygame.event.pump()
讓 Pygame 內部自動處理事件。
pump() -> None
對於遊戲中的每一幀,你都需要通過某種形式去呼叫事件佇列,這將確保你的程式在內部可以與作業系統的其他部分進行互動。如果你不打算使用其他事件函式,那麼你應該呼叫 pygame.event.pump(),這將允許 Pygame 內部自動處理事件。
如果你的程式始終通過其他 event 模組的函式處理佇列中的事件,那麼該函式是沒必要的。
事件佇列中的內部處理是非常重要的事情。主視窗可能需要重新繪製或對系統做出響應。如果你太長時間沒有呼叫事件佇列,系統可能會認定你的程式已鎖定(假死)。
pygame.event.get()
從佇列中獲取事件。
get() -> Eventlist
get(type) -> Eventlist
get(typelist) -> Eventlist
這將獲取並從佇列中刪除事件。如果指定一個或多個 type 引數,那麼只獲取並刪除指定型別的事件。
請注意,如果你只從佇列中獲取和刪除指定的事件,那麼久而久之,佇列可能被你不關注的事件所填滿。
pygame.event.poll()
從佇列中獲取一個事件。
poll() -> EventType instance
從佇列中返回並刪除一個事件。
如果事件佇列為空,那麼會立刻返回型別為 pygame.NOEVENT 的事件。
pygame.event.wait()
等待並從佇列中獲取一個事件。
wait() -> EventType instance
從佇列中返回並刪除一個事件。如果佇列為空,那麼該函式將持續等待直至佇列中有一個事件。當程式在等待時,它將保持睡眠狀態。這對於希望與其他應用程式共享系統來說,是非常重要的。
pygame.event.peek()
檢測某型別事件是否在佇列中。
peek(type) -> bool
peek(typelist) -> bool
如果引數指定的型別的事件存在於佇列中,返回 True。
如果引數指定多個型別的事件,則只需佇列中擁有其中的任何一個事件便返回 True。
pygame.event.clear()
從佇列中刪除所有的事件。
clear() -> None
clear(type) -> None
clear(typelist) -> None
從佇列中刪除所有的事件,如果通過引數指定事件的型別,則刪除該型別的所有事件。該函式的效果跟 pygame.event.get() 相同,只是沒有返回任何東西。當處理完關注的事件後,清空整個佇列可以提高一些效率。
pygame.event.event_name()
通過 id 獲得該事件的字串名字。
event_name(type) -> string
Pygame 通過整數 id 代表事件型別。如果你需要將這些型別的事件展示給使用者看,那麼你需要將它們轉換成字串(一堆數字誰知道你想表示啥?)。該函式將返回事件型別對應的字串名字。返回值是以單詞大寫的樣式(小甲魚溫馨提示:DanCiDaXieDe)。
pygame.event.set_blocked()
控制哪些事件禁止進入佇列。
set_blocked(type) -> None
set_blocked(typelist) -> None
set_blocked(None) -> None
引數指定的型別的事件均不允許出現在事件佇列中。預設是允許所有事件進入佇列。多次禁止同一型別的事件並不會引發什麼問題。
如果傳入 None,則表示允許所有的事件進入佇列。
pygame.event.set_allowed()
控制哪些事件允許進入佇列。
set_allowed(type) -> None
set_allowed(typelist) -> None
set_allowed(None) -> None
引數指定的型別的事件均允許出現在事件佇列中。預設是允許所有事件進入佇列。多次允許同一型別的事件並不會引發什麼問題。
如果傳入 None,則表示禁止所有的事件進入佇列。
pygame.event.get_blocked()
檢測某一型別的事件是否被禁止進入佇列。
get_blocked(type) -> bool
如果引數指定型別的事件被禁止進入佇列,則返回 True。
pygame.event.set_grab()
控制輸入裝置與其他應用程式的共享。
set_grab(bool) -> None
當你的程式執行在視窗環境中,它將與其他擁有焦點的應用程式分享滑鼠和鍵盤裝置的輸入。如果你的程式設定事件獨佔為 True,那麼你的程式將鎖定所有的輸入(小甲魚溫馨提示:不共享給其他程式了)。
最好不要經常獨佔輸入,因為這將阻止使用者在作業系統上的其他操作。
pygame.event.get_grab()
檢測程式是否共享輸入裝置。
get_grab() -> bool
當程式獨佔輸入事件時,返回 True。使用 pygame.event.set_grab() 函式控制這一狀態。
pygame.event.post()
放置一個新的事件到佇列中。
post(Event) -> None
該函式將放置一個新的事件到事件佇列的末端。這些事件將最遲被其他佇列函式獲取。
該函式通常用於放置 pygame.USEREVENT(使用者自定義事件)事件到佇列中。儘管你可以放置所有型別的事件,但你需要確保為系統事件型別相應的屬性傳遞合適的值。
如果 SDL 事件佇列已滿,將丟擲 pygame.error 異常。
pygame.event.Event()
建立一個新的事件物件。
Event(type, dict) -> EventType instance
Event(type, **attributes) -> EventType instance
根據引數給定的型別建立一個新的事件。dict 引數指定事件的屬性以及相應的值。
class pygame.event.EventType
代表 SDL 事件的 Pygame 物件。
pygame.event.EventType.type — SDL event type identifier.
pygame.event.EventType.__dict__ — vent object attribute dictionary
用於代表 SDL 事件的 Pygame 物件。通過 pygame.event.Event() 建立使用者自定義事件。EventType 型別並不是直接可以被呼叫的。EventType 例項物件支援屬性賦值和刪除。
type
SDL 事件型別識別符號。
type -> int
只讀。預定義事件識別符號是 QUIT 和 MOUSEMOTION 等。對於用於建立的事件物件,這是傳遞給 pygame.event.Event() 的 type 引數。
__dict__
事件物件的屬性字典。
__dict__ -> dict
只讀。事件型別指定的屬性。例如,KEYDOWN 事件包含 unicode,key 和 mod 屬性。
可變屬性是 Pygame 1.9.2 新增加的。