rm-hull / luma.led_matrix

Python module to drive LED Matrices & 7-segment displays (MAX7219) and RGB NeoPixels (WS2812 / APA102)
https://luma-led-matrix.readthedocs.io
MIT License
525 stars 157 forks source link

Flashing LEDs #119

Closed Nennstiel closed 7 years ago

Nennstiel commented 7 years ago

I have programmed the game snake for the pi and i'm using 3 of the max7219 to display it. My problem is that from the point where the snake collects the first member all of the following members start to flash but the base element lights up permanently. I can not find the error, why the lightning happens. The rest of the game works just fine. The game runs on a pi 3 with all libraries up to date and spi enabled

from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import max7219
from luma.core.legacy import text, show_message
from luma.core.render import canvas
import RPi.GPIO as gpio
import time
from random import randint

gpio.setmode(gpio.BCM)
taster = [14,15,18,23]
Anzahl = 3
height = 7
width = (8*Anzahl)-1

serial = spi(port=0, device=0, gpio=noop())
device = max7219(serial, cascaded=Anzahl)

def steuerung(gpio):
  global richtung
  if(gpio == 14):   #rechts
   richtung = [1,0]
  elif(gpio == 15): #oben
   richtung = [0,-1]
  elif(gpio == 18): #unten
   richtung = [0,1]
  elif(gpio == 23): #links
   richtung = [-1,0]

for i in taster:
   gpio.setup(i,gpio.IN,pull_up_down=gpio.PUD_UP)
   gpio.add_event_detect(i, gpio.FALLING, callback=steuerung)

def startSpiel():
  global snake, richtung, apfel
  snake = [[randint(2,width-4),randint(3,height-3)]]
  richtung = [0,0]
  while richtung == [0,0]:
    show_message(device, "READY", fill="white", scroll_delay=0.04)
  neuerApfel()

def neuerApfel():
  global apfel, snake
  apfelSnake = False
  while apfelSnake == False:
    apfelSnake = True
    apfel = [randint(0,width),randint(0,height)]
    for i in snake:
      if(i == apfel):
        apfelSnake = False
  print(apfel)

def endOfGame():
  for i in range(0,2):
    device.clear()
    for i in range(0,width+1):
      for j in range(0,height+1):
         time.sleep(0.001)
    time.sleep(0.01)
  show_message(device, "GAME OVER", fill="white", scroll_delay=0.04)
  punkte = len(snake)-1
  show_message(device,"EREICHTE PUNKTE: "+ str(punkte), fill="white", scroll_delay=0.04)

  startSpiel()

startSpiel()

while True:
  keinePause = False
  newSnake = [snake[0][0]+richtung[0],
              snake[0][1]+richtung[1]]
  for i in snake:
    if(i == newSnake):
      endOfGame()
      pass

  if(newSnake == apfel):
     neuerApfel()
     keinePause = True

  else:
     snake.pop()
  snake.insert(0,newSnake)

  if(snake[0][0] > width or snake [0][1] > height
    or snake[0][0] < 0 or snake[0][1] < 0 ):
    endOfGame()
    pass

  device.clear()

  for i in snake:
    with canvas(device) as draw:
       dither=True
       draw.point(apfel, fill ="white")
       draw.point(i, fill ="white")

  if(keinePause == False):
    newLength = (len(snake)-2)*0.01
    time.sleep(0.5-newLength)
  else:
    time.sleep(0.4)
rm-hull commented 7 years ago

Instead of:


  device.clear()

  for i in snake:
    with canvas(device) as draw:
       dither=True
       draw.point(apfel, fill ="white")
       draw.point(i, fill ="white")

I think the code in the main while loop should be along the lines of:

  with canvas(device) as draw:
     for i in snake:
       draw.point(apfel, fill ="white")
       draw.point(i, fill ="white")

There's no need to clear the device (the canvas will manage this for you).

Also the endOfGame can just be:

def endOfGame():
  show_message(device, "GAME OVER", fill="white", scroll_delay=0.04)
  punkte = len(snake)-1
  show_message(device,"EREICHTE PUNKTE: "+ str(punkte), fill="white", scroll_delay=0.04)