上一篇文章:树莓派和手柄-蓝牙连接 ,我们已经完成手柄的蓝牙连接;这篇文章我们将继续实验,尝试如何获取手柄的各个按钮、摇杆的操作数据,然后通过这些数据,方便后续的其他实验。
实验前需要先安装Pygame,(Pygame是一个免费的开源python编程语言库,用于制作游戏等多媒体应用程序。)我们这次会用到Pygame的joystick模块,从joystick的中文含义(操纵杆)可知,它是用于与操纵杆、游戏手柄和轨迹球交互的Pygame模块。
按键区域名称设定
由上图我们先设定了一些名称,方便跟代码对应;其中摇杆分左右两个;按钮除了右边圈内的四个,还包含share键,options键,ps键以及L1、L2和R1、R2;方向键为左边圈内上下左右四按键。
#程序执行(程序文档可参考:https://www.pygame.org/docs/ref/joystick.html )
由于在多次尝试ssh登录情况下,效果无法达到预期,所以这次直接通过vnc在树莓派桌面执行程序(预估是权限问题)。vnc相关可参考文章:树莓派安装vnc 。
#程序代码:
#coding:utf-8
import pygame
import time
#定义显示颜色
BLACK = pygame.Color('black')
WHITE = pygame.Color('white')
#信息输出类
class TextPrint():
def __init__(self):
self.reset()
self.font = pygame.font.Font(None, 20)
def tprint(self, screen, textString):
textBitmap = self.font.render(textString, True, BLACK)
screen.blit(textBitmap, (self.x, self.y))
self.y += self.line_height
def reset(self):
self.x = 10
self.y = 10
self.line_height = 15
def indent(self):
self.x += 10
def unindent(self):
self.x -= 10
pygame.init()
screen = pygame.display.set_mode((500, 700))
pygame.display.set_caption("My Game")
done = False
clock = pygame.time.Clock()
#初始化joystick
pygame.joystick.init()
textPrint = TextPrint()
#主程序
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True #停止
elif event.type == pygame.JOYBUTTONDOWN:
print('joystick button pressed!')
elif event.type == pygame.JOYBUTTONUP:
print('joystick button released!')
#绘图
screen.fill(WHITE)
textPrint.reset()
#获取摇杆数量
joystick_count = pygame.joystick.get_count()
#数量信息输出
textPrint.tprint(screen, "number of joysticks: {}".format(joystick_count))
textPrint.indent()
#逐个遍历按钮和摇杆
for i in range(joystick_count):
joystick = pygame.joystick.Joystick(i) #创建对象
joystick.init()
try:
jid = joystick.get_instance_id()
except AttributeError:
jid = joystick.get_id
textPrint.tprint(screen, "Joystick {}".format(jid))
textPrint.indent()
#获取名称
name = joystick.get_name()
textPrint.tprint(screen, "Joystick name: {}".format(name))
try:
guid = joystick.get_guid()
except AttributeError:
pass
else:
textPrint.tprint(screen, "GUID: {}".format(guid))
#获取操作杆轴数
axes = joystick.get_numaxes()
textPrint.tprint(screen, "Number of axes:{}".format(axes))
#获取每个轴的数值
for i in range(axes):
axis = joystick.get_axis(i) #获取每个轴当前的位置 数字表示 取件-1到1之间 0表示居中
textPrint.tprint(screen, "Axis {} value is:{:>6.3f}".format(i, axis))
textPrint.unindent()
#获取手柄按钮数据
buttons = joystick.get_numbuttons()
textPrint.tprint(screen, "Number of buttons:{}".format(buttons))
textPrint.indent()
#获取每个按钮状态
for i in range(buttons):
button = joystick.get_button(i) #获取当前按钮状态 按压True 否False
textPrint.tprint(screen, "button {:>2} value {}".format(i, button))
textPrint.unindent()
#获取方向键状态
hats = joystick.get_numhats() #获取数量
textPrint.tprint(screen, "Number of hats:{}".format(hats))
textPrint.indent()
#获取每个按键的值
for i in range(hats):
hat = joystick.get_hat(i)
textPrint.tprint(screen, "Hat {} value: {}".format(i, str(hat)))
textPrint.unindent()
textPrint.unindent()
pygame.display.flip()
clock.tick(20)
pygame.quit()
#执行效果
图片可能不清晰,也可以看如下图表,是对应的按钮和摇杆以及方向键的操作类型和值范围;
按键类型 控制器类型 值范围 左摇杆(上、下) Axis1 上-1到下1 左摇杆(左、右) Axis0 左-1到右1 右摇杆(上、下) Axis5 上-1到下1 右摇杆(左、右) Axis2 左-1到右1 按钮 △ button2 按压1,非按压0 按钮 ◻︎ button3 按压1,非按压0 按钮 O button1 按压1,非按压0 按钮 X button0 按压1,非按压0 options button9 按压1,非按压0 share button8 按压1,非按压0 ps键 button10 按压1,非按压0 L1 button4 按压1,非按压0 L2 button6、Axis3 按压1,非按压0,其中Axis3显示力度(-1到1,-1为非按压) R1 button5 按压1,非按压0 R2 button7、Axis4 按压1,非按压0,其中Axis4显示力度(-1到1,-1为非按压) 方向键-上 hat(A,B)的B为1 返回值为(0,1) 方向键-下 hat(A,B)的B为-1 返回值为(0,-1) 方向键-左 hat(A,B)的A为-1 返回值为(-1, 0) 方向键-右 hat(A,B)的A为1 返回值为(1, 0)