1. 程式人生 > >Pygame詳解(四):event 模組

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 新增加的。