如何取得控製器的資訊和狀態(按鍵狀態,方向鍵狀態,軸狀態等)
訂閱 480
本節內容不涉及控製器事件的講解,要了解如何處理控製器事件,請檢視如何處理遊戲中的控製器事件一節。
Pygame 處理控製器(手把)的連線與中斷,取得其執行個體 ID、名稱、電量影片示範 YouTube
Pygame 取得控製器(手把)按鍵、方向鍵、搖桿和扳機鍵狀態影片示範 YouTube
Pygame 中的 joystick 模組
Pygame 套件的joystick模組,包含了與遊戲控製器相關的函式,以及表示控製器的JoystickType類別。
初始化 joystick 模組
與pygame模組一樣,joystick模組擁有用於初始化的函式init,該函式會在pygame模組的init函式中被呼叫,這意味著一旦使用pygame模組進行初始化,呼叫joystick模組的init函式將是沒有必要的。
在joystick模組尚未初始化之前,呼叫與遊戲控製器相關的函式可能不會產生實際效果,與控製器相關的事件也不會被引發。
init()
請確保 joystick 模組在 display 模組之後初始化
如果單獨初始化 Pygame 中的模組,那麽請確保在display模組初始化之後,再呼叫joystick模組的init函式。
可以重複呼叫 init 函式
你可以反覆呼叫init函式,這沒有任何問題,即便在呼叫quit函式之後。
# 匯入模組 joystick
from pygame import joystick
# 初始化
joystick.init()判斷 joystick 模組是否已經初始化
與pygame模組一樣,joystick模組擁有判斷joystick模組是否已經初始化的函式get_init。
get_init()
- 傳回值
如果
get_init函式傳回True,那麽表示joystick模組已經進行了初始化。
在呼叫 quit 函式之後,get_init 函式將傳回 False
在呼叫quit函式之後,get_init函式將傳回False,這表示再次呼叫init函式將產生實際效果,他會重新初始化joystick模組。
# …
print(f'joystick 已經初始化?{joystick.get_init()}')joystick 已經初始化?True取消初始化 joystick 模組
與pygame模組一樣,joystick模組擁有用於取消初始化的函式quit,該函式會在pygame模組的quit函式中被呼叫,這意味著一旦使用pygame模組取消了初始化,呼叫joystick模組的quit函式將是沒有必要的。
quit()
可以重複呼叫 quit 函式
和init函式一樣,你可以反覆呼叫quit函式,這沒有任何的問題。
取得控製器的個數
joystick模組的get_count函式,可用於取得已經連線的遊戲控製器的個數。
get_count()
- 傳回值
get_count函式傳回表示控製器個數的整數。
# …
print(f'控製器個數:{joystick.get_count()}')Pygame 中的 JoystickType 物件
joystick模組擁有一個名稱為Joystick的函式,通過該函式可以建立表示具體遊戲控製器的JoystickType物件。
Joystick(id)
- id 參數
id參數是一個整數,該整數需要大於等於0,並小於get_count函式的傳回值。在控製器的連線事件中,你可以將
Event物件的device_index變數作為id參數的值,來建立表示新連線控製器的JoystickType物件。但在連線事件之外,device_index變數所對應的整數可能會失去準確性,當有其他控製器連線或中斷連線時。
請盡量在控製器連線事件中建立 JoystickType 物件
雖然,Pygame 並不限製建立JoystickType物件的時間點,但如果是在遊戲開始時,而非控製器連線事件中,建立控製器物件,那麽這些物件的某些方法可能會失效,比如,你可能無法通過get_button方法取得按鍵的按下狀態(雖然,按下狀態依然可通過控製器的按鍵按下事件獲得)。
當被建立時,JoystickType物件會自動完成初始化,當被終結時,JoystickType物件會自動取消初始化。因此,在建立控製器對應的JoystickType物件之後,你應該保持該物件(至少保持一個該控製器對應的JoystickType物件),否則,相應的控製器事件不會被引發。
JoystickType物件的init和quit方法,可分別用於初始化和取消初始化遊戲控製器,但由於初始化和取消初始化可以自動完成,因此並沒有呼叫以上兩個方法的必要。
init()
quit()
Pygame 官方稱將在 Pygame 2.1 中移除JoystickType的init方法,但在之後的版本中該方法似乎依然存在。
JoystickType物件的get_init,可用於判斷遊戲控製器是否已經進行了初始化。
get_init()
- 傳回值
如果
get_init方法傳回True,那麽表示控製器已經被初始化。
控製器事件
關於遊戲控製的連線事件,請檢視連線和中斷連線事件一段。
在下面的範例中,我們在遊戲開始時,取得所有已經連線的遊戲控製器,如果希望取得在遊戲過程中連線的控製器,那麽需要處理控製器連線事件。
事實上,你應該盡可能的在控製器連線事件中取得控製器,而不是像範例中所展示的,以確保JoystickType物件的相關方法能夠發揮作用。
# 匯入相關內容,並建立遊戲視窗
from pygame import joystick, display, event, QUIT, JOYBUTTONDOWN
display.set_mode([800, 600])
# 初始化 joystick 模組
joystick.init()
js = []
# 取得所有已經連線的控製器
for i in range(joystick.get_count()):
j = joystick.Joystick(i)
js.append(j)
print(f'控製器 {i} 已經初始化?{j.get_init()}')
# 處理結束事件,控製器按鍵的按下事件
running = True
while running:
for e in event.get():
if e.type == QUIT:
running = False
elif e.type == JOYBUTTONDOWN:
print(e)取得控製器方向鍵(十字鍵)的資訊和狀態
JoystickType物件的get_numhats方法,可取得遊戲控製器上的方向鍵的個數,大部分情況下,控製器只擁有一個方向鍵。
get_numhats()
- 傳回值
get_numhats方法傳回表示控製器方向鍵個數的整數。
JoystickType物件的get_hat方法,可取得遊戲控製器方向鍵的按下狀態。
get_hat(hat_number)
- hat_number 參數
hat_number參數是一個整數,對應了控製器上的某個方向鍵,其值大於等於0,並小於get_numhats方法的傳回值。需要指出的是,不同型號的控製器,其類似方向鍵對應的整數可能不同。
- 傳回值
get_hat方法傳回形式為(x,y)的整數元組(部分文件將其解釋為浮點數元組是不準確的)。其中,x為1表示右方向鍵處於按下狀態,為-1表示左方向鍵處於按下狀態,y為1表示上方向鍵處於按下狀態,為-1表示下方向鍵處於按下狀態。
某些控製器的方向鍵被定義為按鍵
對於一些控製器,其擁有的方向鍵被定義為了按鍵,因此,在 Pygame 中不會引發方向鍵事件,也不能通過get_hat方法取得狀態。
下面,我們為之前的範例增加程式碼,根據方向鍵的按下狀態,顯示不同的方向資訊。
# …
# 根據第一個方向鍵來移動角色
if j.get_numhats() > 0:
(x, y) = j.get_hat(0)
if x == -1:
print(f'角色 {pi} 向左')
elif x == 1:
print(f'角色 {pi} 向右')
if y == -1:
print(f'角色 {pi} 向下')
elif y == 1:
print(f'角色 {pi} 向上')取得控製器軸(搖桿,扳機鍵)的資訊和狀態
JoystickType物件的get_numaxes方法,可取得遊戲控製器上的軸裝置的個數,比如,搖桿,扳機鍵。
get_numaxes()
- 傳回值
get_numaxes方法傳回表示控製器軸裝置個數的整數。
JoystickType物件的get_axis方法,可取得遊戲控製器軸裝置(搖桿,扳機鍵)與中心之間的距離。
get_axis(axis_number)
- axis_number 參數
axis_number參數是一個整數,對應了控製器上的某個軸裝置,其值大於等於0,並小於get_numaxes方法的傳回值。對於搖桿而言,0通常指左搖桿的水平軸,2通常指右搖桿的水平軸,1通常指左搖桿的垂直軸,3通常指右搖桿的垂直軸,4通常指左扳機鍵,5通常指右扳機鍵。需要指出的是,不同型號的控製器,其類似軸裝置對應的整數可能不同。
- 傳回值
get_axis方法的傳回值是一個浮點數,表示了軸裝置(搖桿,扳機鍵)與中心之間的距離,一般情況下,其取值範圍從-1至1,等於0表示軸裝置位於中心位置,等於(或接近於)-1或1表示軸裝置已到達邊緣最大位置。對於搖桿而言,
-1通常表示左邊最大位置或上邊最大位置,1通常表示右邊最大位置或下邊最大位置。對於扳機鍵而言,如果沒有被按下,那麽get_axis方法理論上傳回-1。
下面,我們為之前的範例增加程式碼,如果玩家按下右扳機鍵到一定程度,那麽顯示角色跳躍的資訊。
# …
# 根據右扳機鍵判斷是否跳躍,假設 5 對應了右扳機鍵
if j.get_numaxes() > 5 and j.get_axis(5) > 0.2:
print(f'角色 {pi} 跳躍')取得控製器軌跡球的資訊和狀態
JoystickType物件的get_numballs方法,可取得遊戲控製器上的軌跡球的個數。
get_numballs()
- 傳回值
get_numballs方法傳回表示控製器軌跡球個數的整數。
JoystickType物件的get_ball方法,可取得遊戲控製器軌跡球的移動距離。
get_ball(ball_number)
- ball_number 參數
ball_number參數是一個整數,對應了控製器上的某個軌跡球,其值大於等於0,並小於get_numballs方法的傳回值。需要指出的是,不同型號的控製器,其類似軌跡球對應的整數可能不同。
- 傳回值
get_ball方法的傳回值是一個形式類似於(x,y)的整數元組(部分文件將其解釋為浮點數元組是不準確的),表示與上一次事件相比,軌跡球的移動距離,其中x表示水平移動距離,y表示垂直移動距離。
啟動和停止控製器的震動回饋
Pygame 控製控製器(手把)的震動回饋影片示範 YouTube
JoystickType物件的rumble方法,可用於啟動遊戲控製器的震動回饋。
rumble(low_frequency, high_frequency, duration)
- low_frequency 參數
low_frequency參數是表示控製器低頻震動強度的浮點數,取值範圍從0至1,0表示沒有震動,1表示最大強度。- high_frequency 參數
high_frequency參數是表示控製器高頻震動強度的浮點數,取值範圍從0至1,0表示沒有震動,1表示最大強度。- duration 參數
duration參數是表示震動回饋持續時間的整數,以毫秒為單位。如果設定為0,則表示震動回饋一直持續,直到呼叫stop_rumble方法,或再次呼叫rumble方法啟動新的震動回饋。- 傳回值
如果
rumble方法傳回True,則表示已成功啟動震動回饋,否則表示啟動失敗。
JoystickType物件的stop_rumble方法,可用於停止遊戲控製器的震動回饋。
stop_rumble()
在下面的範例中,我們嘗試使新連線的遊戲控製器產生5秒的震動回饋(但1秒後就被停止了)。
# 匯入並初始化相關模組,建立遊戲視窗
from pygame import joystick, display, event, JOYDEVICEADDED, QUIT
import time
display.set_mode((800, 600))
joystick.init()
# 儲存控製器物件的串列
js = []
running = True
while running:
# 處理控製器連線事件,結束事件
for e in event.get():
if e.type == QUIT:
running = False
elif e.type == JOYDEVICEADDED:
j = joystick.Joystick(e.device_index)
js.append(j)
# 嘗試在連線控製器後,啟動其震動回饋
print('成功啟動震動回饋?', j, j.rumble(0.1, 0.9, 5000))
time.sleep(1)
j.stop_rumble()
print('停止震動回饋', j)取得控製器的執行個體 ID
JoystickType物件的get_instance_id方法,可取得遊戲控製器的執行個體 ID(用於唯一識別控製器),他與控製器事件的Event物件的instance_id變數一致。
get_instance_id()
- 傳回值
get_instance_id方法傳回表示控製器執行個體 ID 的整數。
# 匯入並初始化相關模組,建立遊戲視窗
from pygame import joystick, display, event, JOYDEVICEADDED, QUIT
display.set_mode((800, 600))
joystick.init()
# 儲存控製器物件的串列
js = []
running = True
while running:
for e in event.get():
if e.type == QUIT:
running = False
elif e.type == JOYDEVICEADDED:
# 控製器連線事件
j = joystick.Joystick(e.device_index)
js.append(j)
print(f'控製器執行個體 ID:{j.get_instance_id()}')取得控製器的名稱
JoystickType物件的get_name方法,可取得遊戲控製器在作業系統中的名稱。
get_name()
- 傳回值
get_name方法傳回表示控製器名稱的字串。
# …
print(f'控製器名稱:{j.get_name()}')取得控製器的剩余電量
JoystickType物件的get_power_level方法,可取得遊戲控製器的目前電量。
get_power_level()
- 傳回值
get_power_level方法傳回表示控製器目前電量的字串,根據電量的不同,其值可能是'empty','low','medium','full','wired','max'。如果無法得知電量或控製器沒有電池,則get_power_level方法理論上應傳回'unknown'。
# …
print(f'控製器電量:{j.get_power_level()}')取得控製器的 GUID
JoystickType物件的get_guid方法,可取得遊戲控製器的 GUID(用於表示控製器的型號),他與控製器連線事件的Event物件的guid變數一致。
get_guid()
- 傳回值
get_guid方法傳回表示控製器 GUID 的字串。
# …
print(f'控製器 GUID:{j.get_guid()}')原始碼
講解影片
Pygame 處理控製器(手把)的連線與中斷,取得其執行個體 ID、名稱、電量·YouTube
Pygame 取得控製器(手把)按鍵、方向鍵、搖桿和扳機鍵狀態·YouTube
Pygame 控製控製器(手把)的震動回饋·YouTube