问题
So I got raspi 3 and simple 8x8 LED matrix. After some playing with it I decided to make a simple snake game (displaying on that matrix) with pygame's events, I have no prior experience with pygame. There is no screen/display connected besides the led matrix.
So the problem at first was "pygame.error: video system not initialized", though I think i got it fixed by setting an env variable:
os.putenv('DISPLAY', ':0.0')
Now that I got it working I run it...and nothing happens, like no keystrokes are registered. Just this "junk", I don't know how to call it The dot on LED matrix is not moving. If i alter the snake's x or y position somewhere in the loop it moves as intended.
My code:
#!/usr/bin/python2
import pygame
import max7219.led as led
from max7219.font import proportional, SINCLAIR_FONT, TINY_FONT, CP437_FONT
import numpy as nqp
import os
SIZE = (8, 8)
class Board:
def __init__(self, size, snake):
"Board object for snake game"
self.matrix = np.zeros(size, dtype=np.int8)
self.device = led.matrix()
self.snake = snake
def draw(self):
#add snake
self.matrix = np.zeros(SIZE, dtype=np.int8)
self.matrix[self.snake.x][self.snake.y] = 1
for x in range(8):
for y in range(8):
self.device.pixel(x, y, self.matrix[x][y], redraw=False)
self.device.flush()
def light(self, x, y):
"light specified pixel"
self.matrix[x][y] = 1
def dim(self, x, y):
"off specified pixel"
self.matrix[x][y] = 0
class Snake:
def __init__(self):
"Object representing an ingame snake"
self.length = 1
self.x = 3
self.y = 3
if __name__=="__main__":
os.putenv('DISPLAY', ':0.0')
pygame.init()
snake = Snake()
board = Board(SIZE, snake)
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
snake.y -= 1
elif event.key == pygame.K_DOWN:
snake.y += 1
elif event.key == pygame.K_LEFT:
snake.x -= 1
elif event.key == pygame.K_RIGHT:
snake.x += 1
board.draw()
I'm using pygame because I don't know anything else (Well I can't use pygame either but I just don't know of any alternatives). If it can be done simpler I will be happy to do it. Thank You in advance!
回答1:
You should be able to use curses. Here's a simple example:
import curses
def main(screen):
key = ''
while key != 'q':
key = screen.getkey()
screen.addstr(0, 0, 'key: {:<10}'.format(key))
if __name__ == '__main__':
curses.wrapper(main)
You'll see that your key presses are registered - they're just strings.
However, this runs in blocking mode. Assuming that your code needs to do other things, you can turn nodelay
on:
def main(screen):
screen.nodelay(True)
key = ''
while key != 'q':
try:
key = screen.getkey()
except curses.error:
pass # no keypress was ready
else:
screen.addstr(0, 0, 'key: {:<10}'.format(key))
In your scenario you probably would put this inside your game loop that's drawing out to your 8x8 display, so it would look something like this:
game = SnakeGame()
while game.not_done:
try:
key = screen.getkey()
except curses.error:
key = None
if key == 'KEY_UP':
game.turn_up()
elif key == 'KEY_DOWN':
game.turn_down()
elif key == 'KEY_LEFT':
game.turn_left()
elif key == 'KEY_RIGHT':
game.turn_right()
game.tick()
One thing to note - this approach will take 100% of your CPU, so if you don't have some other way to limit what your app is doing it can cause you some problems. You could extend this approach using threading/multiprocessing, if you find that to be something that you need.
来源:https://stackoverflow.com/questions/38907681/pygame-through-ssh-does-not-register-keystrokes-raspberry-pi-3