如何處理遊戲中的控製器事件
訂閱 480
雖然本節所提到的內容與事件有關,但擷取事件的方法,請參考如何擷取處理遊戲事件?以及建立和引發自訂事件等問題一節。除了通過事件,你也可以使用joystick模組來實作與控製器相關的功能,具體請檢視如何取得控製器的資訊和狀態(按鍵狀態,方向鍵狀態,軸狀態等)一節。
初始化 joystick 模組
要在 Pygame 中處理與控製器相關的事件,你需要首先對joystick模組進行初始化,否則相關程式碼可能不會執行。此外,類似於按鍵按下和釋放,軸和軌跡球移動等事件,還需要建立和保持與控製器相關的JoystickType物件。
控製器
關於初始化joystick模組,你可以檢視初始化 joystick 模組一段。
連線和中斷連線事件
Pygame 處理控製器(手把)的連線和中斷連線事件影片示範 YouTube
pygame模組擁有變數JOYDEVICEADDED,表示遊戲控製器的連線事件,該事件可能在遊戲中接入新的控製器時引發,也可能在遊戲啟動時引發(如果已經在啟動前連線了控製器),其對應的Event物件擁有以下變數。
- device_index 變數
device_index變數是一個整數,其含義為控製器的裝置索引,通常用於建立JoystickType物件。裝置索引可被理解為控製器的順序,同一個控製器的裝置索引可能會發生改變,當連線了新的控製器或原有控製器中斷連線時。因此,device_index變數僅在控製器連線事件中保證其準確性。- guid 變數
guid變數是一個 GUID 字串,用於識別某種控製器型號。由於該字串只是針對型號,因此,他不能用於識別每一個遊戲控製器,當你連結同一品牌的同種型號的兩個控製器時,他們將擁有相同的 GUID。
pygame模組擁有變數JOYDEVICEREMOVED,表示遊戲控製器的中斷連線事件,此事件對應的Event物件擁有以下變數。
- instance_id 變數
instance_id變數是一個表示執行個體 ID 的整數,執行個體 ID 可用於唯一的識別控製器。
遊戲控製器的執行個體 ID 與建立 JoystickType 物件無關
對於每一個新連線的控製器,Pygame 都會為其分配一個執行個體 ID,該執行個體 ID 與是否建立JoystickType物件或建立多少個JoystickType物件無關。這意味著,對於同一個控製器,建立與其相關的多個JoystickType物件,並不會改變該控製器的執行個體 ID。
重新連線遊戲控製器,其執行個體 ID 可能會發生變化
對於同一個控製器,如果在中斷連線後重新連線,那麽其對應的執行個體 ID 可能會發生變化。
在下面的範例中,我們通過一個串列來保持通過裝置索引建立的JoystickType物件,並根據執行個體 ID 將無用的JoystickType物件從串列中移除。
# 匯入相關內容,建立遊戲視窗,初始化模組
from pygame import display, event, joystick, QUIT
display.set_mode((800, 600))
joystick.init()
# 匯入與控製器事件相關的變數
from pygame import JOYDEVICEADDED, JOYDEVICEREMOVED
# 儲存 JoystickType 物件的串列
jss = []
running = True
while running:
for e in event.get():
if e.type == QUIT:
running = False
elif e.type == JOYDEVICEADDED:
# 根據裝置索引建立 JoystickType 物件,並新增至 jss
js = joystick.Joystick(e.device_index)
jss.append(js)
print('新增控製器', e.device_index)
elif e.type == JOYDEVICEREMOVED:
# 根據執行個體 ID,將 JoystickType 物件從 jss 移除
for js in jss:
if js.get_instance_id() == e.instance_id:
jss.remove(js)
print('移除控製器', e.instance_id)
break按鍵的按下和釋放事件
Pygame 處理控製器(手把)按鍵的按下和釋放事件影片示範 YouTube
pygame模組擁有變數JOYBUTTONDOWN和JOYBUTTONUP,他們分別表示控製器按鍵被按下和釋放的事件,事件所對應Event物件擁有以下變數。
- instance_id 變數
instance_id變數是表示控製器執行個體 ID 的整數,他將指示引發事件的具體控製器。- button 變數
button變數是一個整數,用於表示控製器上被按下或釋放的按鍵。
控製器按鍵被按下的事件不會被持續引發
一般情況下,控製器按鍵被按下的事件不會被持續引發,即便將某個控製器按鍵保持按下狀態,按鍵按下的事件也僅會引發一次。不過,某些型號的控製器可能會擁有自動連擊功能,如果開啟此功能並保持按鍵的按下狀態,那麽按鍵的按下事件和釋放事件會被持續引發。
方向鍵(十字鍵)事件
Pygame 處理控製器(手把)的方向鍵(十字鍵)事件影片示範 YouTube
pygame模組擁有變數JOYHATMOTION,他表示控製器方向鍵(十字鍵)被操作的事件(按下和釋放均會引發),該事件所對應Event物件擁有以下變數。
- instance_id 變數
instance_id變數是表示控製器執行個體 ID 的整數,他將指示引發事件的具體控製器。- hat 變數
hat變數是表示方向鍵 ID 的整數,可用於指示引發事件的具體方向鍵,大部分情況下該變數為0(擁有多個方向鍵的控製器非常罕見)。- value 變數
value變數是一個形式為(x,y)的整數元組。如果x為1,則表示右方向鍵被按下,為-1,則表示左方向鍵被按下。如果y為1,則表示上方向鍵被按下,為-1,則表示下方向鍵被按下。
控製器的方向鍵事件不會被持續引發
一般情況下,控製器的方向鍵事件不會被持續引發,即便將方向鍵保持按下狀態,因按下而引發的事件也僅會出現一次。
某些控製器的方向鍵不會引發方向鍵事件
並非所有控製器的方向鍵均會引發方向鍵事件,某些控製器的方向鍵會引發按鍵按下和按鍵釋放事件(JOYBUTTONDOWN和JOYBUTTONUP)。
在下面的範例中,我們根據事件物件的value變數,取得方向鍵的按下狀態,以決定遊戲角色向哪個方向移動。
# 匯入並初始化相關模組,建立遊戲視窗
from pygame import display, event, joystick, JOYDEVICEADDED, QUIT
display.set_mode((800, 600))
joystick.init()
# 匯入與控製器事件相關的變數
from pygame import JOYHATMOTION
# 儲存 JoystickType 物件的串列
jss = []
# 表示水平和垂直的移動方向
h = 0
v = 0
running = True
while running:
for e in event.get():
if e.type == QUIT:
running = False
elif e.type == JOYDEVICEADDED:
jss.append(joystick.Joystick(e.device_index))
elif e.type == JOYHATMOTION:
# 取得十字鍵的按下狀態
(x, y) = e.value
# 根據十字鍵的按下狀態,設定遊戲角色的移動方向
if x == 1:
h = 1
print('開始向右移動')
elif x == -1:
h = -1
print('開始向左移動')
elif h != 0:
h = 0
print('取消水平移動')
if y == 1:
v = 1
print('開始向上移動')
elif y == -1:
v = -1
print('開始向下移動')
elif v != 0:
v = 0
print('取消垂直移動')軸(搖桿,扳機鍵)移動事件
Pygame 處理控製器(手把)的軸(搖桿、扳機鍵)移動事件影片示範 YouTube
遊戲控製器一般擁有一些軸裝置,最為常見的是搖桿和扳機鍵。pygame模組的變數JOYAXISMOTION,可用於表示軸的移動事件,該事件所對應Event物件擁有以下變數。
- instance_id 變數
instance_id變數是表示控製器執行個體 ID 的整數,他將指示引發事件的具體控製器。- axis 變數
axis變數是表示軸 ID 的整數,可用於指示引發事件的具體軸。大部分的遊戲控製器均擁有左右兩個搖桿和左右兩個扳機鍵,當
axis為0或2時,事件通常由左搖桿或右搖桿在水平方向上的移動引發,當axis為1或3時,事件通常由左搖桿或右搖桿在垂直方向上的移動引發,當axis為4或5時,事件通常由左扳機鍵或右扳機鍵引發。需要指出的是,不同型號的控製器,其類似的軸裝置的 ID 可能會不同,
axis為3並不表示事件一定由右搖桿在垂直方向上的移動引發。- value 變數
value變數是一個浮點數,表示了軸(搖桿,扳機鍵)與中心之間的距離,其取值範圍從-1至1,等於0表示軸(搖桿,扳機鍵)位於中心位置,等於(或接近於)-1或1表示軸(搖桿,扳機鍵)已到達邊緣最大位置。當axis為0或2時,value通常表示搖桿與中心之間的水平距離(-1為左邊最大位置,1為右邊最大位置)。當axis為1或3時,value通常表示搖桿與中心之間的垂直距離(-1為上邊最大位置,1為下邊最大位置)。對於搖桿而言,
value變數的預設值理論上為0,對於扳機鍵而言,value變數的預設值理論上為-1。
# 匯入並初始化相關模組,建立遊戲視窗
from pygame import display, event, joystick, JOYDEVICEADDED, QUIT
display.set_mode((800, 600))
joystick.init()
# 匯入與控製器事件相關的變數
from pygame import JOYAXISMOTION
# 儲存 JoystickType 物件的串列
jss = []
running = True
while running:
for e in event.get():
if e.type == QUIT:
running = False
elif e.type == JOYDEVICEADDED:
jss.append(joystick.Joystick(e.device_index))
elif e.type == JOYAXISMOTION:
# 判斷觸發事件的軸裝置是否為右扳機鍵
if e.axis == 5:
# 判斷右扳機鍵的移動程度,是否足以發動攻擊
if e.value > -0.3:
print('攻擊')
else:
print('停止攻擊')軌跡球捲動事件
針對射擊遊戲,一些遊戲控製器可能會設計軌跡球,其操作效果類似於滑鼠。pygame模組的變數JOYBALLMOTION,可用於表示軌跡球的捲動事件,該事件所對應Event物件擁有以下變數。
- instance_id 變數
instance_id變數是表示控製器執行個體 ID 的整數,他將指示引發事件的具體控製器。- ball 變數
ball變數是表示軌跡球 ID 的整數,可用於指示引發事件的具體軌跡球。- rel 變數
rel變數是一個形式類似於(x,y)的 Python 整數元組,表示與上一次事件相比,軌跡球的移動距離,其中x表示水平移動距離,y表示垂直移動距離。
原始碼
講解影片
Pygame 處理控製器(手把)的連線和中斷連線事件·YouTube
Pygame 處理控製器(手把)按鍵的按下和釋放事件·YouTube
Pygame 處理控製器(手把)的方向鍵(十字鍵)事件·YouTube
Pygame 處理控製器(手把)的軸(搖桿、扳機鍵)移動事件·YouTube