如何获取控制器的信息和状态(按键状态,方向键状态,轴状态等)
关注 1260
本节内容不涉及控制器事件的讲解,要了解如何处理控制器事件,请查看如何处理游戏中的控制器事件一节。
如何在 Pygame 中处理连接与中断的控制器,以及获取相关信息视频演示 YouTube如何在 Pygame 中处理连接与中断的控制器,以及获取相关信息视频演示 Bilibili
如何在 Pygame 中获取控制器按键、摇杆状态视频演示 YouTube如何在 Pygame 中获取控制器按键、摇杆状态视频演示 Bilibili
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如何在 Pygame 中启动和停止控制器的震动回馈视频演示 Bilibili
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 中处理连接与中断的控制器,以及获取相关信息·YouTube如何在 Pygame 中处理连接与中断的控制器,以及获取相关信息·Bilibili
如何在 Pygame 中获取控制器按键、摇杆状态·YouTube如何在 Pygame 中获取控制器按键、摇杆状态·Bilibili
如何在 Pygame 中启动和停止控制器的震动回馈·YouTube如何在 Pygame 中启动和停止控制器的震动回馈·Bilibili