An incomplete Snake implementation using a Raspberry Pi 3, an adafruit st7735 screen and Python
:)
| import time | |
| import random | |
| import digitalio | |
| import board | |
| import busio | |
| from adafruit_rgb_display import rgb, st7735 | |
| import RPi.GPIO as GPIO | |
| from PIL import Image, ImageFont, ImageDraw | |
| # NES colors :) | |
| # colors are in BGR (not RGB) | |
| colors = [ | |
| rgb.color565(252, 0, 0), | |
| rgb.color565(188, 0, 0), | |
| rgb.color565(188, 40, 68), | |
| rgb.color565(132, 0, 148), | |
| rgb.color565(32, 0, 168), | |
| rgb.color565(0, 16, 168), | |
| rgb.color565(0, 20, 136), | |
| rgb.color565(0, 48, 80), | |
| rgb.color565(0, 120, 0), | |
| rgb.color565(0, 104, 0), | |
| rgb.color565(0, 88, 0), | |
| rgb.color565(88, 64, 0), | |
| rgb.color565(248, 120, 0), | |
| rgb.color565(248, 88, 0), | |
| rgb.color565(252, 68, 104), | |
| rgb.color565(204, 0, 216), | |
| rgb.color565(88, 0, 228), | |
| rgb.color565(0, 56, 248), | |
| rgb.color565(16, 92, 228), | |
| rgb.color565(0, 124, 172), | |
| rgb.color565(0, 184, 0), | |
| rgb.color565(0, 168, 0), | |
| rgb.color565(68, 168, 0), | |
| rgb.color565(136, 136, 0), | |
| rgb.color565(248, 248, 248), | |
| rgb.color565(252, 188, 60), | |
| rgb.color565(252, 136, 104), | |
| rgb.color565(248, 120, 152), | |
| rgb.color565(248, 120, 248), | |
| rgb.color565(152, 88, 248), | |
| rgb.color565(88, 120, 248), | |
| rgb.color565(68, 160, 252), | |
| rgb.color565(0, 184, 248), | |
| rgb.color565(24, 248, 184), | |
| rgb.color565(84, 216, 88), | |
| rgb.color565(152, 248, 88), | |
| rgb.color565(216, 232, 0), | |
| rgb.color565(120, 120, 120), | |
| rgb.color565(252, 252, 252), | |
| rgb.color565(252, 228, 164), | |
| rgb.color565(248, 184, 184), | |
| rgb.color565(248, 184, 216), | |
| rgb.color565(248, 184, 248), | |
| rgb.color565(192, 164, 248), | |
| rgb.color565(176, 208, 240), | |
| rgb.color565(168, 224, 252), | |
| rgb.color565(120, 216, 248), | |
| rgb.color565(120, 248, 216), | |
| rgb.color565(184, 248, 184), | |
| rgb.color565(216, 248, 184), | |
| rgb.color565(252, 252, 0), | |
| rgb.color565(216, 216, 216) | |
| ] | |
| def rand_col(): | |
| return random.choice(colors) | |
| class Dot: | |
| def __init__(self, x, y, color): | |
| self.x = x | |
| self.y = y | |
| self.color = color | |
| def __repr__(self): | |
| return "({},{},{})".format(self.x, self.y, self.color) | |
| def rand_apple(width, height, dot_size, snake_body): | |
| apple = Dot(random.randrange(0, width, dot_size), random.randrange(0, height, dot_size), rand_col()) | |
| # checks that the apple is not in a position overlapping with the snake's body | |
| for dot in snake_body: | |
| if (dot.x == apple.x and dot.y == apple.y): | |
| return rand_apple(width, height, dot_size, snake_body) | |
| return apple | |
| def draw_score_image(score, width): | |
| image = Image.new('RGB', (width, 10), color = 'red') | |
| draw = ImageDraw.Draw(image) | |
| font = ImageFont.truetype("FreeMono.ttf", 10) | |
| draw.text((10, 0), "score: {}".format(score), font=font) | |
| return image | |
| cs_pin = digitalio.DigitalInOut(board.CE0) | |
| dc_pin = digitalio.DigitalInOut(board.D25) | |
| reset_pin = digitalio.DigitalInOut(board.D24) | |
| btn_right = digitalio.DigitalInOut(board.D17) | |
| btn_right.direction = digitalio.Direction.INPUT | |
| btn_left = digitalio.DigitalInOut(board.D22) | |
| btn_left.direction = digitalio.Direction.INPUT | |
| btn_up = digitalio.DigitalInOut(board.D27) | |
| btn_up.direction = digitalio.Direction.INPUT | |
| btn_down = digitalio.DigitalInOut(board.D23) | |
| btn_down.direction = digitalio.Direction.INPUT | |
| BAUDRATE = 24000000 | |
| spi = board.SPI() | |
| disp = st7735.ST7735R( | |
| spi, | |
| rotation=90, | |
| cs=cs_pin, | |
| dc=dc_pin, | |
| rst=reset_pin, | |
| baudrate=BAUDRATE, | |
| ) | |
| height = disp.height | |
| width = disp.width | |
| border_size = 10 | |
| dot_size = 10 | |
| background_color = rgb.color565(0, 0, 0) | |
| border_color = rgb.color565(100,100,100) | |
| step = 10 | |
| score_per_apple = 10 | |
| body = [Dot(0, 30, rand_col()), Dot(0, 20, rand_col()), Dot(0, 10, rand_col()), Dot(0, 0, rand_col())] | |
| apple = rand_apple(width - (border_size*3), height - (border_size*3), dot_size, body) | |
| disp.fill_rectangle(0, 0, width, height, border_color) | |
| disp.fill_rectangle(border_size, border_size, width - (border_size*2), height - (border_size*2), background_color) | |
| score = 0 | |
| score_image = draw_score_image(score, width) | |
| while True: | |
| head_x = body[0].x | |
| head_y = body[0].y | |
| new_head_x = head_x | |
| new_head_y = head_y | |
| if btn_up.value: | |
| new_head_y = min(max(0, head_y - step), height - (border_size*3)) | |
| if btn_right.value: | |
| new_head_x = min(max(0, head_x + step), width - (border_size*3)) | |
| if btn_down.value: | |
| new_head_y = min(max(0, head_y + step), height - (border_size*3)) | |
| if btn_left.value: | |
| new_head_x = min(max(0, head_x - step), width - (border_size*3)) | |
| if (new_head_x != head_x or new_head_y != head_y ): | |
| if new_head_x == apple.x and new_head_y == apple.y: | |
| # eat an apple | |
| score = score + score_per_apple | |
| score_image = draw_score_image(score, width) | |
| body.insert(0, Dot(new_head_x, new_head_y, apple.color)) | |
| apple = rand_apple(width - (border_size*3), height - (border_size*3), dot_size, body) | |
| else: | |
| # shifts all colors | |
| head_color = body[0].color | |
| for i in range(0, len(body) - 1): | |
| body[i].color = body[i+1].color | |
| removed_dot = body.pop() | |
| body.insert(0, Dot(new_head_x, new_head_y, head_color)) | |
| # clean up removed body dot | |
| disp.fill_rectangle(border_size + removed_dot.x, border_size + removed_dot.y, dot_size, dot_size, background_color) | |
| for dot in body: | |
| disp.fill_rectangle(border_size + dot.x, border_size + dot.y, dot_size, dot_size, dot.color) | |
| disp.fill_rectangle(border_size + apple.x, border_size + apple.y, dot_size, dot_size, apple.color) | |
| disp.image(score_image, rotation=0) | |
| time.sleep(1/60) |