URLhttps://learnscript.net/zh-hant/pygame/joystick/
    複製連結移至說明  範例

    如何取得控製器的資訊和狀態(按鍵狀態,方向鍵狀態,軸狀態等)

    閱讀 18:57·字數 5687·發佈 
    Youtube 頻道
    訂閱 375

    本節內容不涉及控製器事件的講解,要了解如何處理控製器事件,請檢視如何處理遊戲中的控製器事件一節。

    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.py
    # 匯入模組 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模組。

    joystick.py
    # …
    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函式傳回表示控製器個數的整數。

    joystick.py
    # …
    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物件的initquit方法,可分別用於初始化和取消初始化遊戲控製器,但由於初始化和取消初始化可以自動完成,因此並沒有呼叫以上兩個方法的必要。

    init()
    quit()

    Pygame 官方稱將在 Pygame 2.1 中移除JoystickTypeinit方法,但在之後的版本中該方法似乎依然存在。

    JoystickType物件的get_init,可用於判斷遊戲控製器是否已經進行了初始化。

    get_init()

    傳回值

    如果get_init方法傳回True,那麽表示控製器已經被初始化。

    控製器事件

    關於遊戲控製的連線事件,請檢視連線和中斷連線事件一段。

    在下面的範例中,我們在遊戲開始時,取得所有已經連線的遊戲控製器,如果希望取得在遊戲過程中連線的控製器,那麽需要處理控製器連線事件。

    事實上,你應該盡可能的在控製器連線事件中取得控製器,而不是像範例中所展示的,以確保JoystickType物件的相關方法能夠發揮作用。

    create.py
    # 匯入相關內容,並建立遊戲視窗
    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_numbuttons方法,可取得遊戲控製器上的按鍵的個數。

    get_numbuttons()

    傳回值

    get_numbuttons方法傳回表示控製器按鍵個數的整數。

    JoystickType物件的get_button方法,可取得遊戲控製器按鍵的按下狀態。

    get_button(button)

    button 參數

    button參數是一個整數,對應了控製器上的某個按鍵,其值大於等於0,並小於get_numbuttons方法的傳回值。

    需要指出的是,不同型號的控製器,其類似按鍵對應的整數可能不同。

    傳回值

    如果get_button方法傳回True,那麽表示按鍵處於按下狀態。

    下面,我們在控製器連線事件中,建立了與控製器相關的JoystickType物件,並判斷每一個控製器的第一個按鍵是否被按下,如果被按下,則顯示對應角色的攻擊資訊。

    status.py
    # 匯入並初始化相關模組,建立遊戲視窗
    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)
    # 角色索引 pi = 0
    # 周遊所有的控製器 for j in js: pi += 1
    # 如果按下第一個按鍵,則視為攻擊命令 if j.get_numbuttons() > 0 and j.get_button(0): print(f'角色 {pi} 攻擊')

    取得控製器方向鍵(十字鍵)的資訊和狀態

    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)的整數元組(部分文件將其解釋為浮點數元組是不準確的)。其中,x1表示右方向鍵處於按下狀態,為-1表示左方向鍵處於按下狀態,y1表示上方向鍵處於按下狀態,為-1表示下方向鍵處於按下狀態。

    某些控製器的方向鍵被定義為按鍵

    對於一些控製器,其擁有的方向鍵被定義為了按鍵,因此,在 Pygame 中不會引發方向鍵事件,也不能通過get_hat方法取得狀態。

    下面,我們為之前的範例增加程式碼,根據方向鍵的按下狀態,顯示不同的方向資訊。

    status.py
    # …
    # 根據第一個方向鍵來移動角色
    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方法的傳回值是一個浮點數,表示了軸裝置(搖桿,扳機鍵)與中心之間的距離,一般情況下,其取值範圍從-11,等於0表示軸裝置位於中心位置,等於(或接近於)-11表示軸裝置已到達邊緣最大位置。

    對於搖桿而言,-1通常表示左邊最大位置或上邊最大位置,1通常表示右邊最大位置或下邊最大位置。對於扳機鍵而言,如果沒有被按下,那麽get_axis方法理論上傳回-1

    下面,我們為之前的範例增加程式碼,如果玩家按下右扳機鍵到一定程度,那麽顯示角色跳躍的資訊。

    status.py
    # …
    # 根據右扳機鍵判斷是否跳躍,假設 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表示垂直移動距離。

    啟動和停止控製器的震動回饋

    JoystickType物件的rumble方法,可用於啟動遊戲控製器的震動回饋。

    rumble(low_frequency, high_frequency, duration)

    low_frequency 參數

    low_frequency參數是表示控製器低頻震動強度的浮點數,取值範圍從010表示沒有震動,1表示最大強度。

    high_frequency 參數

    high_frequency參數是表示控製器高頻震動強度的浮點數,取值範圍從010表示沒有震動,1表示最大強度。

    duration 參數

    duration參數是表示震動回饋持續時間的整數,以毫秒為單位。如果設定為0,則表示震動回饋一直持續,直到呼叫stop_rumble方法,或再次呼叫rumble方法啟動新的震動回饋。

    傳回值

    如果rumble方法傳回True,則表示已成功啟動震動回饋,否則表示啟動失敗。

    JoystickType物件的stop_rumble方法,可用於停止遊戲控製器的震動回饋。

    stop_rumble()

    在下面的範例中,我們嘗試使新連線的遊戲控製器產生5秒的震動回饋(但1秒後就被停止了)。

    rumble.py
    # 匯入並初始化相關模組,建立遊戲視窗
    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 的整數。

    info.py
    # 匯入並初始化相關模組,建立遊戲視窗
    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方法傳回表示控製器名稱的字串。

    info.py
    # …
    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'

    info.py
    # …
    print(f'控製器電量:{j.get_power_level()}')

    取得控製器的 GUID

    JoystickType物件的get_guid方法,可取得遊戲控製器的 GUID(用於表示控製器的型號),他與控製器連線事件的Event物件的guid變數一致。

    get_guid()

    傳回值

    get_guid方法傳回表示控製器 GUID 的字串。

    info.py
    # …
    print(f'控製器 GUID:{j.get_guid()}')

    原始碼

    src/zh-hant/joystick·codebeatme/pygame·GitHub

    講解影片

    Pygame 處理控製器(手把)的連線與中斷,取得其執行個體 ID、名稱、電量·YouTube
    Pygame 取得控製器(手把)按鍵、方向鍵、搖桿和扳機鍵狀態·YouTube
    Pygame 控製控製器(手把)的震動回饋·YouTube