Who wants to play a worse-than-Atari version of flappy bird on your Librem with green bar pipes, a blue background, and a red dot for bird. Bang away at the touch screen to 'flap", edit the python to fix speed or pipe sizes.
import pygame
import sys
import random
from enum import Enum
class GameState(Enum):
MENU = 1
PLAYING = 2
GAME_OVER = 3
class FlappyBird:
def __init__(self):
pygame.init()
# Screen dimensions
self.WIDTH = 400
self.HEIGHT = 600
self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT))
pygame.display.set_caption("Flappy Bird")
# Colors
self.WHITE = (255, 255, 255)
self.BLACK = (0, 0, 0)
self.GREEN = (0, 200, 0)
self.RED = (255, 0, 0)
self.BLUE = (100, 149, 237)
# Clock for FPS
self.clock = pygame.time.Clock()
self.fps = 60
# Game state
self.state = GameState.MENU
self.score = 0
self.high_score = 0
# Initialize game objects
self.init_game()
def init_game(self):
"""Initialize or reset game objects"""
# Bird properties
self.bird_x = self.WIDTH // 4
self.bird_y = self.HEIGHT // 2
self.bird_width = 30
self.bird_height = 30
self.bird_velocity = 0
self.gravity = 0.6
self.flap_strength = -12
# Pipes
self.pipe_width = 50
self.pipe_gap = 120
self.pipe_velocity = -5
self.pipes = []
self.spawn_pipe()
self.score = 0
def spawn_pipe(self):
"""Create a new pipe pair"""
min_height = 50
max_height = self.HEIGHT - self.pipe_gap - 50
pipe_height = random.randint(min_height, max_height)
self.pipes.append({
'x': self.WIDTH,
'top_height': pipe_height,
'bottom_y': pipe_height + self.pipe_gap,
'scored': False
})
def handle_input(self):
"""Handle user input"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
# Detect any touch/click to flap
if event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.KEYDOWN:
if self.state == GameState.MENU:
self.state = GameState.PLAYING
elif self.state == GameState.PLAYING:
self.bird_velocity = self.flap_strength
elif self.state == GameState.GAME_OVER:
self.state = GameState.MENU
self.init_game()
return True
def update(self):
"""Update game logic"""
if self.state != GameState.PLAYING:
return
# Apply gravity
self.bird_velocity += self.gravity
self.bird_y += self.bird_velocity
# Update pipes
for pipe in self.pipes:
pipe['x'] += self.pipe_velocity
# Check if bird passed the pipe
if not pipe['scored'] and pipe['x'] + self.pipe_width < self.bird_x:
pipe['scored'] = True
self.score += 1
# Remove pipes that are off-screen
self.pipes = [p for p in self.pipes if p['x'] + self.pipe_width > 0]
# Spawn new pipe when needed
if len(self.pipes) == 0 or self.pipes[-1]['x'] < self.WIDTH - 200:
self.spawn_pipe()
# Check collisions
if self.check_collision():
self.state = GameState.GAME_OVER
if self.score > self.high_score:
self.high_score = self.score
def check_collision(self):
"""Check if bird collided with pipes or boundaries"""
# Ground and ceiling collision
if self.bird_y + self.bird_height > self.HEIGHT or self.bird_y < 0:
return True
# Pipe collision
bird_rect = pygame.Rect(self.bird_x, self.bird_y, self.bird_width, self.bird_height)
for pipe in self.pipes:
# Top pipe
top_pipe_rect = pygame.Rect(pipe['x'], 0, self.pipe_width, pipe['top_height'])
if bird_rect.colliderect(top_pipe_rect):
return True
# Bottom pipe
bottom_pipe_rect = pygame.Rect(pipe['x'], pipe['bottom_y'], self.pipe_width, self.HEIGHT - pipe['bottom_y'])
if bird_rect.colliderect(bottom_pipe_rect):
return True
return False
def draw(self):
"""Draw game elements"""
self.screen.fill(self.BLUE)
# Draw pipes
for pipe in self.pipes:
# Top pipe
pygame.draw.rect(self.screen, self.GREEN, (pipe['x'], 0, self.pipe_width, pipe['top_height']))
# Bottom pipe
pygame.draw.rect(self.screen, self.GREEN, (pipe['x'], pipe['bottom_y'], self.pipe_width, self.HEIGHT - pipe['bottom_y']))
# Draw bird
pygame.draw.rect(self.screen, self.RED, (self.bird_x, self.bird_y, self.bird_width, self.bird_height))
# Draw UI
font = pygame.font.Font(None, 36)
score_text = font.render(f"Score: {self.score}", True, self.WHITE)
self.screen.blit(score_text, (10, 10))
# Draw game state text
if self.state == GameState.MENU:
menu_font = pygame.font.Font(None, 48)
title = menu_font.render("Flappy Bird", True, self.WHITE)
instruction = font.render("Tap/Click to Start", True, self.WHITE)
self.screen.blit(title, (self.WIDTH // 2 - title.get_width() // 2, self.HEIGHT // 3))
self.screen.blit(instruction, (self.WIDTH // 2 - instruction.get_width() // 2, self.HEIGHT // 2))
elif self.state == GameState.GAME_OVER:
gameover_font = pygame.font.Font(None, 48)
gameover_text = gameover_font.render("Game Over", True, self.WHITE)
high_score_text = font.render(f"High Score: {self.high_score}", True, self.WHITE)
restart_text = font.render("Tap/Click to Restart", True, self.WHITE)
self.screen.blit(gameover_text, (self.WIDTH // 2 - gameover_text.get_width() // 2, self.HEIGHT // 3))
self.screen.blit(high_score_text, (self.WIDTH // 2 - high_score_text.get_width() // 2, self.HEIGHT // 2 - 40))
self.screen.blit(restart_text, (self.WIDTH // 2 - restart_text.get_width() // 2, self.HEIGHT // 2 + 40))
pygame.display.flip()
def run(self):
"""Main game loop"""
running = True
while running:
running = self.handle_input()
self.update()
self.draw()
self.clock.tick(self.fps)
pygame.quit()
sys.exit()
if __name__ == "__main__":
game = FlappyBird()
game.run()
I made a .deb for myself if that is desired