from machine import Pin, ADC, I2C
from ssd1306 import SSD1306_I2C
import random
import time
# Configuración de la pantalla OLED
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = SSD1306_I2C(128, 64, i2c)
# Pines del joystick y potenciómetro
joystick_x = ADC(Pin(34)) # Eje X del joystick
joystick_y = ADC(Pin(35)) # Eje Y del joystick
potentiometer = ADC(Pin(32)) # Potenciómetro para la velocidad
joystick_x.atten(ADC.ATTN_11DB) # Configurar el rango de lectura para joystick y potenciómetro
joystick_y.atten(ADC.ATTN_11DB)
potentiometer.atten(ADC.ATTN_11DB)
# Configuración inicial del juego
snake = [(64, 32), (62, 32), (60, 32)] # Coordenadas iniciales de la serpiente
direction = 1 # Dirección inicial (0: Arriba, 1: Derecha, 2: Abajo, 3: Izquierda)
food = (random.randint(0, 63) * 2, random.randint(0, 31) * 2) # Comida en una posición aleatoria
score = 0
# Función para dibujar un rectángulo lleno
def fill_rect(x, y, width, height, color):
for i in range(width):
for j in range(height):
oled.pixel(x + i, y + j, color)
# Función para dibujar la serpiente y la comida
def draw_game():
oled.fill(0)
# Dibujar la serpiente
for segment in snake:
fill_rect(segment[0], segment[1], 2, 2, 1)
# Dibujar la comida
fill_rect(food[0], food[1], 2, 2, 1)
# Mostrar el puntaje
oled.text('Score: {}'.format(score), 0, 0)
oled.show()
# Función para mover la serpiente
def move_snake():
global food, score
# Mover el cuerpo de la serpiente
for i in range(len(snake) - 1, 0, -1):
snake[i] = snake[i - 1]
# Mover la cabeza de la serpiente en función de la dirección
head_x, head_y = snake[0]
if direction == 0: # Arriba
head_y += 2
elif direction == 1: # Derecha
head_x -= 2
elif direction == 2: # Abajo
head_y -= 2
elif direction == 3: # Izquierda
head_x += 2
snake[0] = (head_x, head_y)
# Comprobar si la serpiente come la comida
if snake[0] == food:
snake.append(snake[-1]) # Alargar la serpiente
score += 1
food = (random.randint(0, 63) * 2, random.randint(0, 31) * 2) # Nueva comida
# Función para verificar colisiones
def check_collision():
head_x, head_y = snake[0]
# Colisiones con los bordes de la pantalla
if head_x < 0 or head_x >= 128 or head_y < 0 or head_y >= 64:
return True
# Colisiones con el propio cuerpo de la serpiente
if snake[0] in snake[1:]:
return True
return False
# Función para leer el joystick y actualizar la dirección
def read_joystick():
global direction
x_value = joystick_x.read()
y_value = joystick_y.read()
if y_value < 1000 and direction != 2:
direction = 0 # Arriba
elif y_value > 3000 and direction != 0:
direction = 2 # Abajo
elif x_value > 3000 and direction != 3:
direction = 1 # Derecha
elif x_value < 1000 and direction != 1:
direction = 3 # Izquierda
# Función para leer el potenciómetro y ajustar la velocidad
def read_potentiometer():
pot_value = potentiometer.read()
speed = 0.05 + (pot_value / 4095) * 0.2 # Ajustar velocidad entre 0.05 y 0.25 segundos
return speed
# Función principal del juego
def game_loop():
global snake, score, direction, food
while True:
read_joystick() # Leer el estado del joystick
move_snake() # Mover la serpiente
if check_collision(): # Verificar colisiones
oled.fill(0)
oled.text('Game Over', 32, 24)
oled.text('Score: {}'.format(score), 32, 40)
oled.show()
time.sleep(3)
# Reiniciar el juego
snake = [(64, 32), (62, 32), (60, 32)]
direction = 3
score = 0
food = (random.randint(0, 63) * 2, random.randint(0, 31) * 2)
draw_game() # Dibujar el estado del juego
# Ajustar la velocidad en función del potenciómetro
time.sleep(read_potentiometer())
# Iniciar el juego
game_loop()