Tester la carte «Raspberry Pi Sense Hat»

Sense HAT

j’ai acheté cette carte pour me familiariser avec la programmation d’une interface avec python.

Description de la carte

Écriture des premiers jeux

Space-invader

Le jeu consiste à intercepter les objets qui tombent avec une raquette que l’on déplace avec le joystick de la carte

Pour lancer le jeu il faut maintenir le bouton central.

Il est possible d’accélérer ou ralentir la vitesse de défilement en agissant sur «Up» ou «Down».

On relance le jeu en maintenant «Down».

Code

/home/pi/trav/hat_game.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# BPh 17/08/06
# Jeu façon «Space Invader»
# Vitesse de défilement «Up» -> +, «Down» -> -
# Déplacement de la raquette «Left» -> -, «Right» -> +
# Démarrage du programme maintenir «Middle»
# Sortir du programme : maintenir «Down»
#
from sense_hat import SenseHat

from time import sleep,time
from random import randint

# Couleurs 
black = [0,0,0]
point = [200,64,64]
raket = [48,96,144]
ball = [48,48,48]
colors = [[75,180,180], [100,160,160], [125,140,140], [150,120,120], [175,100,100], [200,80,80], [225,60,60], [250,40,40]]

class Jauge():
  def __init__(self, sen):
    self.sense = sen
    self.sense.set_rotation(180)
    self.point = 0
    self.coef = 8
  def add_point(self):
    if self.point < 8 * self.coef: self.point += 1
    self.__display()
  def sub_point(self):
    if self.point > 0: self.point -= 1
    self.__display()
  def restart(self):
    self.point = 0
    self.__display()
  def win(self):
    return self.point == 8 * self.coef -1
  def __display(self):
    for i in range(8):
      if int(self.point / self.coef) > i - 1:
        self.sense.set_pixel(0,i,colors[int(self.point % self.coef)])
      else:
        self.sense.set_pixel(0,i,black)

class Raquette():
  def __init__(self, sen, size):
    self.sense = sen
    self.size = size
    self.initpos()
    self.__display()
  def left(self):
    if self.pos + self.size < 8: self.pos += 1
    self.__display()
  def right(self):
    if self.pos > 1: self.pos -= 1
    self.__display()
  def restart(self):
    self.initpos()
    self.__display()
  def initpos(self):
    self.pos = 4 - int(self.size / 2)
  def __display(self):
    for i in range(1,8):
      if (i < self.pos) | (i >= self.pos + self.size):
        self.sense.set_pixel(i,0,black)
      else:
        self.sense.set_pixel(i,0,raket)

class Pannel():
  def __init__(self, sen, jauge, wait):
    self.sense = sen
    self.jauge = jauge
    self.wait = wait
    self.time = time()
    self.play = False
 
  def update(self):
    if (time() - self.time > self.wait) & self.play :
    # Stockage du timestamp
    self.time = time()
    # Comptage des points
    for x in range(1,8):
      if self.sense.get_pixel(x, 1) != black:
        if self.sense.get_pixel(x, 0) != black:
          self.jauge.add_point()
        else:
          self.jauge.sub_point()
 
    # Déplacement du milieu de tableau
    for y in range(2,8):
      for x in range(1,8):
        self.sense.set_pixel(x, y-1, self.sense.get_pixel(x, y))
    # Ajout du nouveau point sur la première ligne
    newpoint = randint(1,7)
    for x in range(1,8):
      if x == newpoint:
        self.sense.set_pixel(x, 7, ball)
      else:
        self.sense.set_pixel(x, 7, black)
 
  def set_wait(self, delta):
    self.wait += delta
  def stop(self):
    self.play = False
  def restart(self):
    self.sense.clear()
    self.play = True

def main():
  sn = SenseHat()
  jauge = Jauge(sn)
  raquette = Raquette(sn, 1)
  pannel = Pannel(sn, jauge, 2)
 
  for i in range(64):
    jauge.add_point()
    sleep(0.025)
  for i in range(64):
    jauge.sub_point()
    sleep(0.05)
  while True:
    for event in sn.stick.get_events():
      if(event.action == 'pressed'):
        if event.direction == 'right':
          raquette.right()
        if event.direction == 'left':
          raquette.left()
        if event.direction == 'up':
          pannel.set_wait(-0.2)
        if event.direction == 'down':
          pannel.set_wait(0.2)
        if(event.action == 'held'):
          if(event.direction == 'down'):
            sn.clear()
            exit()
          if event.direction == 'middle':
            pannel.restart()
            jauge.restart()
            raquette.restart()
      pannel.update()
    pannel.update()
    if jauge.win():
      pannel.stop()
  return 0

if __name__ == '__main__':
  main()

Lancement automatique du jeu

Une fois le programme écrit, il faut le démarrer automatiquement et le relancer lors de l’arrêt.

Cette fonctionnalité est implémenté en déclarant le programme comme un service linux géré par systemd.

/etc/systemd/system/game.service

[Unit]
Description=Jeu python carte hat
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python3 /home/pi/trav/hat_game.py
Restart=always

[Install]
WantedBy=multi-user.target

Le paramètre «Restart=always» permet de déléguer la relance du programme à Systemd.

Acitvation

$ sudo systemctl daemon-reload
$ sudo systemctl enable game
$ sudo systemctl start game