You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.3 KiB
Python

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

# Imports
import pygame
from pygame.locals import *
import random
# Font
pygame.font.init()
font = pygame.font.SysFont("Bauhaus 93", 60)
# Setup
clock = pygame.time.Clock()
fps = 60
screen_width = 864
screen_height = 936
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Flappy Bird")
# Load Images
image_background = pygame.image.load("assets/background.png")
image_ground = pygame.image.load("assets/ground.png")
image_button = pygame.image.load("assets/restart.png")
# Colors
white = (255, 255, 255)
# Game Variables
scroll = 0
scroll_speed = 3
game_over = False
flying = False
make_pipes = False
passed_pipe = False
pipe_gap = 160
pipe_frequency = 1500
last_pipe = pygame.time.get_ticks() - pipe_frequency
score = 0
# Draw Text
def draw_text(text, x, y):
image = font.render(text, True, white)
screen.blit(image, (x, y))
# Bird
class Bird(pygame.sprite.Sprite):
# Init
def __init__(self):
# Variables
pygame.sprite.Sprite.__init__(self)
self.images = []
self.index = 1
self.counter = 0
# Images
for number in range(1, 4):
image = pygame.image.load(f"assets/bird{number}.png")
self.images.append(image)
# Set Position
self.image = self.images[self.index]
self.rect = self.image.get_rect()
self.rect.center = [100, screen_height / 2]
self.vel = 0
self.clicked = False
# Update
def update(self, game_over):
# Gravity
self.vel += 0.5
if self.vel > 10:
self.vel = 10
if self.rect.bottom < 768:
self.rect.y += int(self.vel)
elif self.rect.top > 0:
self.vel = 0
# Jump
if game_over == False:
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
self.vel = - 10
elif pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
# Animation
self.counter += 1
flap_cooldown = 10
if self.counter > flap_cooldown:
self.counter = 0
self.index += 1
if self.index >= len(self.images):
self.index = 0
self.image = self.images[self.index]
# Rotate Bird
self.image = pygame.transform.rotate(self.images[self.index], self.vel * - 2)
# Pipe
class Pipe(pygame.sprite.Sprite):
# Init
def __init__(self, x, y, position):
# Variables
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("assets/pipe.png")
self.rect = self.image.get_rect()
# Create Pipe
if position == 1:
self.image = pygame.transform.flip(self.image, False, True)
self.rect.bottomleft = [x, y - int(pipe_gap / 2)]
elif position == - 1:
self.rect.topleft = [x, y + int(pipe_gap / 2)]
# Update
def update(self):
# Scroll Pipes
self.rect.x -= scroll_speed
# Delete Pipes
if self.rect.right < 0:
self.kill()
# Button
class Button():
# Init
def __init__(self):
# Variables
self.image = image_button
self.image = pygame.transform.scale(self.image, (250, 90))
self.rect = self.image.get_rect()
self.rect.topleft = (screen_width // 2 - 125, screen_height - 120)
# Draw
def draw(self):
# Mouse Position
pos = pygame.mouse.get_pos()
# Display Button
screen.blit(self.image, (self.rect.x, self.rect.y))
# When Clicked
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1:
return True
return False
# Sprite Groups
bird_group = pygame.sprite.Group()
pipe_group = pygame.sprite.Group()
# Create Bird
flappy = Bird()
bird_group.add(flappy)
# Create Restart Button
button = Button()
# Initialise Pygame
pygame.init()
# Game Loop
run = True
while run:
# Tick
clock.tick(fps)
# Display Background
screen.blit(image_background, (0, 0))
pipe_group.draw(screen)
screen.blit(image_ground, (scroll, 768))
# Check Score
if len(pipe_group) > 0:
if bird_group.sprites()[0].rect.left > pipe_group.sprites()[0].rect.left\
and bird_group.sprites()[0].rect.right < pipe_group.sprites()[0].rect.right\
and passed_pipe == False:
passed_pipe = True
if passed_pipe == True:
try:
if bird_group.sprites()[0].rect.left > pipe_group.sprites()[0].rect.right:
score += 1
passed_pipe = False
except:
pass
# Game Over
if game_over == False:
# Create Pipes
time_now = pygame.time.get_ticks()
if time_now - last_pipe > pipe_frequency and make_pipes:
pipe_height = random.randint(-180, 180)
bottom_pipe = Pipe(screen_width, int(screen_height / 2) + pipe_height, - 1)
top_pipe = Pipe(screen_width, int(screen_height / 2) + pipe_height, 1)
pipe_group.add(bottom_pipe)
pipe_group.add(top_pipe)
last_pipe = time_now
# Scroll
scroll -= scroll_speed
pipe_group.update()
if abs(scroll) > 35:
scroll = 0
else:
# Reset Game
if button.draw():
game_over = False
flying = False
make_pipes = False
score = 0
last_pipe = pygame.time.get_ticks() - pipe_frequency
bird_group.empty()
pipe_group.empty()
flappy.rect.x = 100
flappy.rect.y = int(screen_height // 2)
flappy = Bird()
bird_group.add(flappy)
# Update Bird
if pygame.sprite.groupcollide(bird_group, pipe_group, False, False) or flappy.rect.top < 0:
game_over = True
if flappy.rect.bottom >= 768:
game_over = True
flying = False
if flying:
bird_group.update(game_over)
# Display Bird
bird_group.draw(screen)
draw_text(str(score), int(screen_width / 2) - 10, 20)
# Event Handler
for event in pygame.event.get():
# QUIT
if event.type == pygame.QUIT:
run = False
# Start
if event.type == pygame.MOUSEBUTTONDOWN:
flying = True
make_pipes = True
# Update Display
pygame.display.update()
# Close Window
pygame.quit()