### snake.py ### Author: Matthew Reed ### Game of snake, uses the D-Pad ### Adapted from https://pythonspot.com/snake-with-pygame/ ### import sys import time import signal import logging import configparser from enum import Enum import math from random import randint import matrix class Snake: class Apple: def __init__(self, x, y): self.x = x self.y = y def draw(self, display): display.set_pixel(self.x, self.y, matrix.Colors.GREEN.value) class Player: class DIRECTION(Enum): NONE = 0 UP = 1 DOWN = 2 LEFT = 3 RIGHT = 4 def __init__(self, length): self.length = length self.direction = self.DIRECTION.RIGHT self.updateCountMax = 4 self.updateCount = 0 # initial positions, no collision self.x = [2,1,0] self.y = [0,0,0] for i in range(0, 61): self.x.append(-100) self.y.append(-100) def update(self): self.updateCount = self.updateCount + 1 if self.updateCount >= self.updateCountMax: # update previous positions for i in range(self.length, 0, -1): self.x[i] = self.x[i-1] self.y[i] = self.y[i-1] # update position of head of snake if self.direction == self.DIRECTION.RIGHT: self.x[0] = self.x[0] + 1 if self.direction == self.DIRECTION.LEFT: self.x[0] = self.x[0] - 1 if self.direction == self.DIRECTION.UP: self.y[0] = self.y[0] - 1 if self.direction == self.DIRECTION.DOWN: self.y[0] = self.y[0] + 1 self.updateCount = 0 def is_overlaping(self, apple): for i in range(0, self.length): if apple.x == self.x[i] and apple.y == self.y[i]: return True return False def draw(self, display): for i in range(0, self.length): #print("l: " + str(self.length) + " i: " + str(i) + " x: " + str(self.x[i]) + " y: " + str(self.y[i])) if self.x[i] > 7: self.x[i] = 7 if self.x[i] < 0: self.x[i] = 0 if self.y[i] > 7: self.y[i] = 7 if self.y[i] < 0: self.y[i] = 0 display.set_pixel(self.x[i], self.y[i], matrix.Colors.BLUE.value) def __init__(self, config, parent, matrix, controller): self.logger = logging.getLogger('snake') self.config = config self.parent = parent self.matrix = matrix self.controller = controller def reset(self): pass def splash(self): self.matrix.set_matrix(matrix.Colors.BLUE.value) self.matrix.update() def run(self): self.player = self.Player(3) self.apple = self.Apple(5,5) #start timers and counters self.start_time = time.time() last_time = time.time() delay_time = 0.2 led_iteration_count = 0 frame_count = 0 keep_going = True while keep_going: for event in self.controller.read_input(): if event.code == 313 and event.value == 1: keep_going = False elif event.code == 16: if event.value == 1: #dpad right self.player.direction = self.player.DIRECTION.RIGHT if event.value == 0: #dpad none pass if event.value == -1: #dpad left self.player.direction = self.player.DIRECTION.LEFT elif event.code == 17: if event.value == 1: #dpad down self.player.direction = self.player.DIRECTION.DOWN if event.value == 0: #dpad none pass if event.value == -1: #dpad up self.player.direction = self.player.DIRECTION.UP if time.time() > last_time + delay_time: last_time = time.time() #determine next move self.player.update() #does snake eat apple? if self.apple.x == self.player.x[0] and self.apple.y == self.player.y[0]: self.player.length = self.player.length + 1 while self.player.is_overlaping(self.apple): self.apple.x = randint(0, 7) self.apple.y = randint(0, 7) #go faster as the snake gets longer delay_time = delay_time - 0.005 #does snake collide with itself? for i in range(1, self.player.length): if self.player.x[0] == self.player.x[i] and self.player.y[0] == self.player.y[i]: print("You lose! Collision: ") print("x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")") print("x[" + str(i) + "] (" + str(self.player.x[i]) + "," + str(self.player.y[i]) + ")") keep_going = False #does snake go off the board? if self.player.x[0] < 0 or self.player.x[0] > 7 or self.player.y[0] < 0 or self.player.y[0] > 7: print("You lose! Off Board: ") print("x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")") keep_going = False #update display self.matrix.set_matrix(matrix.Colors.OFF.value) self.player.draw(self.matrix) self.apple.draw(self.matrix) self.matrix.update() led_iteration_count = (led_iteration_count + 1) % self.matrix.NUM_LEDS frame_count = frame_count + 1 time.sleep(0.01) #display score before exiting self.matrix.set_matrix(matrix.Colors.OFF.value) self.matrix.update() for i in range(0, self.player.length): self.matrix.set_pixel(i % self.matrix.WIDTH, math.floor(i / self.matrix.HEIGHT), matrix.Colors.WHITE.value) self.matrix.update() time.sleep(2)