from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import utime
import random
# OLED setup
i2c = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)
# Button
button = Pin(18, Pin.IN, Pin.PULL_UP)
# Reset game
def reset_game():
return {
"bird_y": 32,
"velocity": 0,
"pipe_x": 128,
"gap_y": random.randint(15, 45),
"score": 0
}
game = reset_game()
gap_size = 20
# Draw screen
def draw():
oled.fill(0)
# Bird
oled.framebuf.fill_rect(20, int(game["bird_y"]), 6, 6, 1)
# Pipe atas
oled.framebuf.fill_rect(game["pipe_x"], 0, 10, game["gap_y"], 1)
# Pipe bawah
oled.framebuf.fill_rect(game["pipe_x"], game["gap_y"] + gap_size, 10, 64, 1)
# Score
oled.text("S:" + str(game["score"]), 0, 0)
oled.show()
# Collision detect
def collision():
y = game["bird_y"]
px = game["pipe_x"]
if y <= 0 or y >= 58:
return True
if 18 < px < 28:
if y < game["gap_y"] or y > game["gap_y"] + gap_size:
return True
return False
# Game over screen
def game_over():
oled.fill(0)
oled.text("GAME OVER", 20, 20)
oled.text("Score:" + str(game["score"]), 20, 35)
oled.text("Press Btn", 20, 50)
oled.show()
# Tunggu tekan untuk restart
while button.value() == 1:
utime.sleep(0.05)
utime.sleep(0.3) # debounce
# MAIN LOOP
while True:
# Gravity
game["velocity"] += 0.3
game["bird_y"] += game["velocity"]
# Flap
if button.value() == 0:
game["velocity"] = -2.5
# Move pipe
game["pipe_x"] -= 2
# Reset pipe
if game["pipe_x"] < -10:
game["pipe_x"] = 128
game["gap_y"] = random.randint(15, 45)
game["score"] += 1
# Collision
if collision():
game_over()
game = reset_game()
continue
draw()
utime.sleep(0.03)