手柄 API
概述
通过 HID 手柄接口可以让设备模拟标准 USB 游戏控制器,提供 按钮控制、模拟摇杆、方向键和扳机功能。这样设备就能作为手柄用于游戏和其他支持控制器的软件。
Python HID 手柄 API 实现位于 Applications/Python/PikaPython/MatrixOS_HID_Gamepad.py,类型提示位于 Applications/Python/PikaPython/_MatrixOS_HID_Gamepad.pyi。
MatrixOS.HID.Gamepad.Press
def Press(button_id: int) -> None
按下手柄按钮。
参数:
button_id(int):按钮标识符(标准手柄按钮为 0-15)
示例:
# 按下按钮 0(通常是 "A" 或 "X")
MatrixOS.HID.Gamepad.Press(0)
# 按下按钮 1(通常是 "B" 或 "○")
MatrixOS.HID.Gamepad.Press(1)
MatrixOS.HID.Gamepad.Release
def Release(button_id: int) -> None
松开手柄按钮。
参数:
button_id(int):要松开的按钮标识符
示例:
# 松开按钮 0
MatrixOS.HID.Gamepad.Release(0)
MatrixOS.HID.Gamepad.ReleaseAll
def ReleaseAll() -> None
松开当前按下的所有手柄按钮。
示例:
# 确保没有按钮卡住
MatrixOS.HID.Gamepad.ReleaseAll()
MatrixOS.HID.Gamepad.Button
def Button(button_id: int, state: bool) -> None
设置特定按钮的状态。
参数:
button_id(int):按钮标识符state(bool):True 表示按下,False 表示松开
示例:
# 按下按钮 2
MatrixOS.HID.Gamepad.Button(2, True)
# 松开按钮 2
MatrixOS.HID.Gamepad.Button(2, False)
MatrixOS.HID.Gamepad.Buttons
def Buttons(button_mask: int) -> None
使用位掩码设置多个按钮状态。
参数:
button_mask(int):位掩码,每一位代表一个按钮状态
示例:
# 按下按钮 0 和 2(第 0 位和第 2 位设置为 1)
MatrixOS.HID.Gamepad.Buttons(0b00000101) # 二进制:按钮 0 和 2
# 不按任何按钮
MatrixOS.HID.Gamepad.Buttons(0)
模拟摇杆函数
MatrixOS.HID.Gamepad.XAxis
def XAxis(value: int) -> None
设置左摇杆 X 轴位置。
参数:
value(int):模拟值(通常 -32767 到 32767,0 = 中心)
示例:
# 中心位置
MatrixOS.HID.Gamepad.XAxis(0)
# 完全向右
MatrixOS.HID.Gamepad.XAxis(32767)
# 完全向左
MatrixOS.HID.Gamepad.XAxis(-32767)
MatrixOS.HID.Gamepad.YAxis
def YAxis(value: int) -> None
设置左摇杆 Y 轴位置。
参数:
value(int):模拟值(通常 -32767 到 32767,0 = 中心)
示例:
# 中心位置
MatrixOS.HID.Gamepad.YAxis(0)
# 完全向上
MatrixOS.HID.Gamepad.YAxis(-32767)
# 完全向下
MatrixOS.HID.Gamepad.YAxis(32767)
MatrixOS.HID.Gamepad.ZAxis
def ZAxis(value: int) -> None
设置 Z 轴(通常用于左扳机)。
参数:
value(int):模拟值
MatrixOS.HID.Gamepad.RXAxis
def RXAxis(value: int) -> None
设置右摇杆 X 轴位置。
参数:
value(int):模拟值(通常 -32767 到 32767,0 = 中心)
MatrixOS.HID.Gamepad.RYAxis
def RYAxis(value: int) -> None
设置右摇杆 Y 轴位置。
参数:
value(int):模拟值(通常 -32767 到 32767,0 = 中心)
MatrixOS.HID.Gamepad.RZAxis
def RZAxis(value: int) -> None
设置 RZ 轴(通常用于右扳机)。
参数:
value(int):模拟值
方向键函数
MatrixOS.HID.Gamepad.DPad
def DPad(direction: GamepadDPadDirection) -> None
设置方向键(D-pad)方向。
参数:
direction(GamepadDPadDirection):D-pad 方向
示例:
# 设置 D-pad 为向上
MatrixOS.HID.Gamepad.DPad(GamepadDPadDirection.UP)
# 设置 D-pad 为中性
MatrixOS.HID.Gamepad.DPad(GamepadDPadDirection.NEUTRAL)
手柄使用示例
基本按钮控制器
def button_controller():
"""用网格按键作为手柄按钮"""
button_map = {
0: 0, # A 按钮
1: 1, # B 按钮
2: 2, # X 按钮
3: 3, # Y 按钮
8: 4, # 左肩键
9: 5, # 右肩键
16: 6, # 左扳机按钮
17: 7, # 右扳机按钮
24: 8, # Back/Select
25: 9, # Start
}
def update_display():
"""在 LED 网格上显示按钮映射"""
MatrixOS.LED.Fill(Color(0, 0, 0), 0)
for key_id, button_id in button_map.items():
xy = MatrixOS.KeyPad.ID2XY(key_id)
# 用颜色区分不同按钮类型
if button_id < 4: # 面键
color = Color(0, 255, 0)
elif button_id < 6: # 肩键
color = Color(255, 255, 0)
elif button_id < 8: # 扳机
color = Color(255, 0, 0)
else: # Start/Select
color = Color(0, 0, 255)
MatrixOS.LED.SetColor(xy, color, 100)
MatrixOS.LED.Update(255)
print("手柄按钮控制器")
print("绿色:面键 (A,B,X,Y)")
print("黄色:肩键")
print("红色:扳机按钮")
print("蓝色:Start/Select")
update_display()
while True:
if not MatrixOS.HID.Ready():
print("HID 未准备好,重新尝试...")
MatrixOS.SYS.DelayMs(1000)
continue
key_event = MatrixOS.KeyPad.Get(100)
if key_event is not None:
key_id = key_event.ID()
key_info = key_event.KeyInfo()
if key_id in button_map:
button_id = button_map[key_id]
if key_info.Active():
MatrixOS.HID.Gamepad.Press(button_id)
print(f"按下手柄按钮 {button_id}")
# 点亮被按下的按钮
xy = MatrixOS.KeyPad.ID2XY(key_id)
MatrixOS.LED.SetColor(xy, Color(255, 255, 255), 255)
MatrixOS.LED.Update(255)
else:
MatrixOS.HID.Gamepad.Release(button_id)
print(f"松开手柄按钮 {button_id}")
# 恢复原色
update_display()
button_controller()
模拟摇杆控制器
def analog_stick_controller():
"""用网格区域作为模拟摇杆控制"""
def map_to_analog(x, y, center_x, center_y, max_range):
"""将网格位置映射到模拟摇杆值"""
dx = x - center_x
dy = y - center_y
# 缩放到模拟范围
analog_x = int((dx / max_range) * 32767)
analog_y = int((dy / max_range) * 32767)
# 限制数值
analog_x = max(-32767, min(32767, analog_x))
analog_y = max(-32767, min(32767, analog_y))
return analog_x, analog_y
def update_display():
"""