如何获取控制器的信息和状态(按键状态,方向键状态,轴状态等)
关注 1800
本节内容不涉及控制器事件的讲解,要了解如何处理控制器事件,请查看如何处理游戏中的控制器事件一节。
如何在 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