from machine import Pin, SPI, PWM, ADC
from utime import sleep
import framebuf
import random
# Настройки джойстика и переключателя
joy_x = ADC(Pin(27))
joy_y = ADC(Pin(26))
joy_btn = Pin(28, Pin.IN, Pin.PULL_UP)
switch = Pin(8, Pin.IN, Pin.PULL_UP) # Slide Switch
# Границы для определения направления движения
THRESHOLD_LOW = 10000
THRESHOLD_HIGH = 55000
def read_joystick():
x = joy_x.read_u16()
y = joy_y.read_u16()
btn = not joy_btn.value()
if x < THRESHOLD_LOW:
return "LEFT"
elif x > THRESHOLD_HIGH:
return "RIGHT"
elif y < THRESHOLD_LOW:
return "UP"
elif y > THRESHOLD_HIGH:
return "DOWN"
elif btn:
return "SELECT"
return None
# === ДИСПЛЕЙ NOKIA 5110 ===
class Nokia5110:
def __init__(self, sck, mosi, dc, cs, rst, bl):
self.rst = Pin(rst, Pin.OUT)
self.cs = Pin(cs, Pin.OUT)
self.dc = Pin(dc, Pin.OUT)
self.bl = PWM(Pin(bl))
self.bl.freq(1000)
self.bl.duty_u16(0) # Экран выключен
self.spi = SPI(0, baudrate=4000000, polarity=0, phase=0, sck=Pin(sck), mosi=Pin(mosi))
self.buffer = bytearray(504)
self.fb = framebuf.FrameBuffer(self.buffer, 84, 48, framebuf.MONO_VLSB)
self.power = False # Добавил это!
self.init_display()
def init_display(self):
self.rst.off()
sleep(0.05)
self.rst.on()
for cmd in [0x21, 0xB0, 0x04, 0x14, 0x20, 0x0C]:
self.command(cmd)
self.clear()
def command(self, cmd):
self.dc.off()
self.cs.off()
self.spi.write(bytearray([cmd]))
self.cs.on()
def clear(self):
self.fb.fill(0)
self.show()
def show(self):
if not self.power:
return
for i in range(6):
self.command(0x40 | i)
self.command(0x80)
self.cs.off()
self.dc.on()
self.spi.write(self.buffer[i * 84:(i + 1) * 84])
self.cs.on()
def text(self, txt, x, y):
self.fb.text(txt, x, y, 1)
self.show()
def power_on(self):
self.bl.duty_u16(32768)
self.power = True
self.clear()
self.text("Snake", 30, 20)
def power_off(self):
self.bl.duty_u16(0)
self.power = False
# === ГЛАВНОЕ МЕНЮ ===
def show_menu(display):
display.clear()
display.text("Snake", 30, 20)
def menu_loop(display):
while True:
if not switch.value(): # Выключение при отключенном переключателе
display.power_off()
else:
if not display.power:
display.power_on()
key = read_joystick()
if key == "SELECT":
return # Начинаем игру
# === ИГРА ЗМЕЙКА ===
class SnakeGame:
def __init__(self, display):
self.display = display
self.reset_game()
def reset_game(self):
self.snake = [(42, 24)]
self.food = (random.randint(0, 83), random.randint(0, 47))
self.direction = "UP"
self.speed = 0.3
self.score = 0
self.running = True
def update(self):
if not self.running:
return
head_x, head_y = self.snake[0]
if self.direction == "UP":
head_y -= 1
elif self.direction == "DOWN":
head_y += 1
elif self.direction == "LEFT":
head_x -= 1
elif self.direction == "RIGHT":
head_x += 1
head_x %= 84 # Проход сквозь стены
head_y %= 48
new_head = (head_x, head_y)
if new_head in self.snake:
self.game_over()
return
self.snake.insert(0, new_head)
if new_head == self.food:
self.score += 1
self.food = (random.randint(0, 83), random.randint(0, 47))
if self.score % 10 == 0:
self.speed = max(0.1, self.speed - 0.05)
else:
self.snake.pop()
def render(self):
self.display.clear()
for segment in self.snake:
self.display.fb.pixel(segment[0], segment[1], 1)
self.display.fb.pixel(self.food[0], self.food[1], 1)
self.display.show()
def game_over(self):
self.running = False
self.display.clear()
self.display.text("Game Over", 15, 20)
self.display.show()
sleep(2)
menu_loop(self.display) # Возвращаемся в меню
# === ОСНОВНОЙ КОД ===
display = Nokia5110(sck=6, mosi=7, dc=2, cs=1, rst=0, bl=5)
while True:
menu_loop(display)
game = SnakeGame(display)
while game.running:
key = read_joystick()
if key in ["UP", "DOWN", "LEFT", "RIGHT"]:
if (key == "UP" and game.direction != "DOWN") or \
(key == "DOWN" and game.direction != "UP") or \
(key == "LEFT" and game.direction != "RIGHT") or \
(key == "RIGHT" and game.direction != "LEFT"):
game.direction = key
game.update()
game.render()
sleep(game.speed)