今天,我们将描述内置操纵杆的使用——继续我们的Sense HAT系列!
该系列之前的文章如下所示,您可以随时查阅:
用于Raspberry Pi的Sense HAT扩展板——操作LED显示屏
用于Raspberry Pi的Sense HAT扩展板——六种传感器
Sense HAT专为Astro Pi任务而设计,内置操纵杆是其中一个输入设备。
该操纵杆位于Sense HAT上的Raspberry Pi标志旁边,如上图所示。操纵杆手柄有点小(尤其是您的手很大时),但是,手柄控制非常容易。它就像游戏机控制器上的其他操纵杆一样(但很小)。
这次我们将展示如何通过Python语言接收这个操纵杆的输入。我们还会使用LED显示屏设计相关游戏。
操纵杆的输入值
Sense HAT操纵杆映射到四个键盘光标键,操纵杆中键单击映射为Return(返回)键。这意味着移动操纵杆与按下对应键的效果完全相同。请记住,下向是指HDMI端口朝下的方向。
操纵杆的方向如下图所示。HDMI端口朝下。
除了四个方向(即向上、向下、向左和向右)之外,您还可以直接向下按下操纵杆,因此可以说总共有5个按键。
好了,我们启动IDEL,然后运行第一个示例代码。
/home/pi/nas/keyboad_mapping.py
import pygame
from pygame.locals import *
from sense_hat import SenseHat
pygame.init()
pygame.display.set_mode((640, 480))
sense = SenseHat()
sense.clear()
running = True
while running:
for event in pygame.event.get():
print(event)
if event.type == QUIT:
running = False
print("BYE")
代码执行时,系统会启动一个名为“pygame window”的黑屏。这是我们程序6-7行调用的pygame库窗口。
Pygame是一个由多个Python模块组成的跨平台套件,专为视频游戏编写而设计。它包括计算机图形库和声音库,旨在与Python编程语言一起使用。
这会获取所有消息并将其从队列中删除。如果给定类型或类型序列,那么系统只会从队列中删除这些类型的消息。
程序第14行中的“pygame.event.get()”会检查该事件,第15行负责打印事件内容。
如果将鼠标移到“pygame窗口”上或按键盘上的键,“事件”内容将显示在控制台屏幕上。这同样可以检测来自Sense HAT操纵杆的输入事件。
我按照顺时针方向进行操作,并且在操纵杆和键盘之间交替操作(比如操纵杆-向上、键盘-向上、操纵杆-向右、键盘-向右等)。您可以看到两种输入方法显示相同的事件内容(图3)。
操纵杆不仅可以向4个方向倾斜,还可以竖直按下,就像键盘上的“Enter”键一样。
此外,每个输入操作都会生成两种类型的事件“KYEDOWN”和“KEYUP”。很简单,按下操纵杆一段时间,您就会理解事件发生的时序。
在keyboad_mapping.py中,pygame自身窗口无法关闭,因为根据编程,该窗口要显示“BYE”并在窗口关闭时终止处理(第16到18行)。如果要退出,关闭IDLE控制台屏幕即可。
操纵杆和LED显示器
现在我们连接LED矩阵显示器,以显示操纵杆的动作!
我们将编写一个程序,使得操纵杆移动时只点亮特定的矩阵。
具体过程大致分为两部分:
- 关闭点亮的LED
- 点亮目标LED
如果同时执行这两个过程,那么就可以根据操纵杆的移动将光线掠过LED矩阵。
要单独控制LED,请参阅用于Raspberry Pi的Sense HAT扩展板——操作LED显示屏介绍的“set_pixel”功能。
将指定XY坐标处的单个LED矩阵像素设置为指定的颜色。
第一个参数是X坐标(0-7),第二个参数是Y坐标(0-7),而第三个参数可以指定颜色。您可以使用以下代码打开/关闭矩阵:
#Lights up (white)
sense.set_pixel(0, 0, 255, 255, 255)
#Lights off (black)
sense.set_pixel(0, 0, 0, 0, 0)
LED显示屏的坐标起始于左上角——此处的坐标为0,如图5所示。操纵杆的动作以及X坐标和Y坐标的变化如下图所示。
操纵杆动作 | 坐标变化 |
向上 | y-1 |
向下 | y+1 |
向左 | x-1 |
向右 | x+1 |
坐标值必须分别设置在0和7之间。如果设置了无效坐标,那么会出现以下错误。
ValueError: Y position must be between 0 and 7
以下示例代码解决了这个错误,因此可以避免该错误。
import pygame
from pygame.locals import *
from sense_hat import SenseHat
pygame.init()
pygame.display.set_mode((640, 480))
sense = SenseHat()
sense.clear()
running = True
x = 0
y = 0
sense.set_pixel(x, y, 255, 255, 255)
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
sense.set_pixel(x, y, 0, 0, 0) # Black 0,0,0 means OFF
if event.key == K_DOWN and y < 7:
y = y + 1
elif event.key == K_UP and y > 0:
y = y - 1
elif event.key == K_RIGHT and x < 7:
x = x + 1
elif event.key == K_LEFT and x > 0:
x = x - 1
sense.set_pixel(x, y, 255, 255, 255)
if event.type == QUIT:
running = False
print("BYE")
第16行是初始过程。首先点亮左上方的LED(X坐标0,Y坐标0)。
当发生输入时,程序首先关闭当前位置的LED,如第21行所示。然后程序会决定坐标是否处于有效范围内(从0到7),第32行负责点亮目标LED(第23到30行)。如果设置了无效值(比如,尝试从矩阵右端进一步向右移动),看起来没有移动,其实系统只是关闭并打开相同的LED。
我们来制作一个游戏!
Sense HAT Pong | Raspberry Pi 学习资源
工作表 – Sense HAT Pong | Raspberry Pi 学习资源
Pong是一款老式的复古游戏。在该游戏中,玩家用一个球拍/条块杆击打移动的球。
游戏可以使用传统的键盘操作,但我想自定义一个程序,以便可以用操纵杆玩游戏。
我们首先启动游戏,然后再进行定制。完成的源程序请参见第8%E