如何取得控製器的資訊和狀態(按鍵狀態,方向鍵狀態,軸狀態等)
訂閱 375
本節內容不涉及控製器事件的講解,要了解如何處理控製器事件,請檢視如何處理遊戲中的控製器事件一節。
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