# main.py
from machine import Pin, I2C, PWM
from time import sleep_ms
import neopixel
from pico_i2c_lcd import I2cLcd
print("Starting Dino Game...")
# Hardware setup
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# Button setup - Change to proper pull-up configuration
jump_btn = Pin(14, Pin.IN, Pin.PULL_UP) # Changed to PULL_UP
duck_btn = Pin(15, Pin.IN, Pin.PULL_UP) # Changed to PULL_UP
buzzer = PWM(Pin(13))
buzzer.duty_u16(0)
np = neopixel.NeoPixel(Pin(12), 8)
# Custom characters
DINO = [
0b00000,
0b00111,
0b00111,
0b10110,
0b11111,
0b01010,
0b01010,
0b00000
]
CACTUS = [
0b00100,
0b00101,
0b10101,
0b10110,
0b01100,
0b00100,
0b00100,
0b00000
]
class DinoCharacter:
def __init__(self):
self.position = 1
self.isJumping = False
self.isDucking = False
self.jump_counter = 0
def jump(self):
if not self.isJumping and not self.isDucking:
print("Jump!")
self.isJumping = True
self.jump_counter = 3
def duck(self):
if not self.isJumping:
print("Duck!")
self.isDucking = True
def update(self):
if self.isJumping:
self.position = 0
self.jump_counter -= 1
if self.jump_counter <= 0:
self.isJumping = False
self.position = 1
else:
self.isDucking = False
self.position = 1
class ObstacleManager:
def __init__(self):
self.obstacles = []
def spawn_obstacle(self):
if len(self.obstacles) == 0:
self.obstacles.append(15)
def update_obstacles(self):
new_obstacles = []
for pos in self.obstacles:
new_pos = pos - 1
if new_pos >= 0:
new_obstacles.append(new_pos)
self.obstacles = new_obstacles
def check_collisions(self, dino):
for pos in self.obstacles:
if pos == 1 and dino.position == 1 and not dino.isDucking:
return True
return False
class GameController:
def __init__(self):
self.dino = DinoCharacter()
self.obstacles = ObstacleManager()
self.score = 0
self.game_speed = 200
self.is_game_over = False
# Initialize custom characters
lcd.custom_char(0, DINO)
lcd.custom_char(1, CACTUS)
def play_sound(self, frequency, duration):
buzzer.freq(frequency)
buzzer.duty_u16(32768)
sleep_ms(duration)
buzzer.duty_u16(0)
def update_lights(self):
for i in range(8):
if self.is_game_over:
np[i] = (255, 0, 0)
else:
np[i] = (0, 255, 0)
np.write()
def check_buttons(self):
# Modified button check - buttons are now active LOW with pull-up
if not jump_btn.value(): # Changed to check for 0 (button pressed)
print("Jump button pressed!")
self.dino.jump()
self.play_sound(1000, 50)
if not duck_btn.value(): # Changed to check for 0 (button pressed)
print("Duck button pressed!")
self.dino.duck()
self.play_sound(500, 50)
def run(self):
print("Game starting...")
lcd.clear()
self.is_game_over = False
self.score = 0
while not self.is_game_over:
# Check button inputs with new method
self.check_buttons()
# Update game state
self.dino.update()
self.obstacles.update_obstacles()
if len(self.obstacles.obstacles) == 0:
self.obstacles.spawn_obstacle()
# Check collisions
if self.obstacles.check_collisions(self.dino):
print(f"Game Over! Score: {self.score}")
self.is_game_over = True
self.play_sound(200, 500)
continue
# Update display
lcd.clear()
# Display dino
lcd.move_to(1, self.dino.position)
lcd.putchar(chr(0))
# Display obstacles
for pos in self.obstacles.obstacles:
lcd.move_to(pos, 1)
lcd.putchar(chr(1))
# Display score
lcd.move_to(10, 0)
lcd.putstr(f"Score:{self.score}")
self.score += 1
self.update_lights()
sleep_ms(self.game_speed)
# Game over screen
lcd.clear()
lcd.move_to(3, 0)
lcd.putstr("Game Over!")
lcd.move_to(2, 1)
lcd.putstr(f"Score: {self.score}")
print("Press jump button to restart...")
# Modified restart button check
while True:
if not jump_btn.value(): # Changed to check for 0 (button pressed)
sleep_ms(300)
break
# Continuous testing of button states
def test_buttons():
print("Testing buttons - press any button")
while True:
if not jump_btn.value():
print("Jump button pressed!")
if not duck_btn.value():
print("Duck button pressed!")
sleep_ms(100)
# Uncomment the following line to test buttons
# test_buttons()
# Main game loop
print("Game initialized. Press buttons to play!")
print("Jump button on GPIO 14")
print("Duck button on GPIO 15")
game = GameController()
while True:
game.run()