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

172 lines
7.0 KiB

import pygame
import random
import sys
# Inicializace Pygame
pygame.init()
# --- Nastavení okna a základních konstant ---
SIRKA_OKNA = 400
VYSKA_OKNA = 600
FPS = 60 # Vyšší FPS pro plynulejší pád
# Barvy (R, G, B)
CERNA = (0, 0, 0)
BILA = (255, 255, 255)
MODRA_OBLOHA = (135, 206, 235)
ZELENA = (34, 139, 34)
ZLUTYP_PTAK = (255, 215, 0)
CERVENA = (255, 0, 0)
# Vytvoření okna
okno = pygame.display.set_mode((SIRKA_OKNA, VYSKA_OKNA))
pygame.display.set_caption("Flappy Bird")
# Hodiny pro řízení rychlosti hry
hodiny = pygame.time.Clock()
# Písma pro texty
font_velky = pygame.font.SysFont("arial", 48, bold=True)
font_maly = pygame.font.SysFont("arial", 24)
def zobraz_text(text, font, barva, x, y, zarovnat_stred=False):
"""Pomocná funkce pro text. Umí vycentrovat text podle zadané pozice x, y."""
plocha = font.render(text, True, barva)
if zarovnat_stred:
rect = plocha.get_rect(center=(x, y))
okno.blit(plocha, rect)
else:
okno.blit(plocha, (x, y))
def hlavni_smycka():
# --- Proměnné Ptáka ---
ptak_x = 50
ptak_y = VYSKA_OKNA // 2
ptak_sirka = 30
ptak_vyska = 30
rychlost_padu = 0 # Aktuální vertikální rychlost
gravitace = 0.5 # Jak moc ptáka přitahuje zem v každém snímku
sila_skoku = -8 # Negativní hodnota posouvá ptáka nahoru
# --- Proměnné Překážek (Trubek) ---
trubka_sirka = 60
mezera_mezi_trubkami = 160 # Výšková mezera kudy pták prolétá
rychlost_posunu = 3 # Rychlost, kterou jedou trubky doleva
# Seznam překážek. Budeme ukládat slovníky se souřadnicemi.
# Např: {"x": 400, "y_stred": 300} -> 'y_stred' určuje, kde je střed mezery pro průlet.
trubky = []
# Funkce, která náhodně vymyslí, kde bude mezera, a přidá trubku do seznamu
def pridej_trubku(x_pozice):
# Střed mezery nebude příliš blízko u okraje (150 pixelů od okrajů)
stred_mezery = random.randint(150, VYSKA_OKNA - 150)
trubky.append({"x": x_pozice, "y_stred": stred_mezery})
# Přidáme první dvě překážky na začátek (úplně mimo obrazovku vpravo)
pridej_trubku(SIRKA_OKNA + 100)
pridej_trubku(SIRKA_OKNA + 400) # Druhá trubka bude o 300 pixelů dále
skore = 0
# Stavy hry jsou výborné pro pochopení "Stavových automatů" (State Machines)
stav_hry = "START" # Stavy: "START", "HRA", "KONEC"
# --- Hlavní herní smyčka ---
while True:
# 1. Zpracování událostí (klávesnice)
for udalost in pygame.event.get():
if udalost.type == pygame.QUIT:
pygame.quit()
sys.exit()
if udalost.type == pygame.KEYDOWN:
if udalost.key == pygame.K_SPACE:
# Co dělá mezerník záleží na tom, v jakém stavu je hra
if stav_hry == "START":
stav_hry = "HRA" # Zapneme hru a ihned skočíme
rychlost_padu = sila_skoku
elif stav_hry == "HRA":
rychlost_padu = sila_skoku # Skok nahoru
elif stav_hry == "KONEC":
return # Vyskočíme z této funkce, aby vnější smyčka spustila hru od znova
# 2. Logika a pohyb
if stav_hry == "HRA":
# Pták padá vlivem gravitace
rychlost_padu += gravitace
ptak_y += rychlost_padu
# Posouváme všechny trubky doleva
for t in trubky:
t["x"] -= rychlost_posunu
# Odstranění trubky, která celá zmizela za levým okrajem obrazovky
if trubky[0]["x"] < -trubka_sirka:
trubky.pop(0) # Smaže první trubku v seznamu
# Spočítáme pozici X té poslední trubky v seznamu a novou dáme za ni
posledni_trubka_x = trubky[-1]["x"]
pridej_trubku(posledni_trubka_x + 300)
# Pokud zmizí trubka (pták ji přeletěl), získáme bod!
skore += 1
# --- Detekce kolizí (nárazů) ---
# Vytvoříme 'Neviditelný obdélník' (Rect) kolem ptáka pro snadnější zjišťování kolizí
ptak_rect = pygame.Rect(ptak_x, ptak_y, ptak_sirka, ptak_vyska)
# Náraz do stropu nebo podlahy okna
if ptak_y < 0 or ptak_y + ptak_vyska > VYSKA_OKNA:
stav_hry = "KONEC"
# Náraz do trubek
for t in trubky:
# Rect pro horní zelenou trubku
horni_vyska = t["y_stred"] - (mezera_mezi_trubkami // 2)
horni_rect = pygame.Rect(t["x"], 0, trubka_sirka, horni_vyska)
# Rect pro dolní zelenou trubku
dolni_y = t["y_stred"] + (mezera_mezi_trubkami // 2)
dolni_rect = pygame.Rect(t["x"], dolni_y, trubka_sirka, VYSKA_OKNA - dolni_y)
# Pokud se náš obdélník ptáka překrývá s horní nebo dolní trubkou, je konec!
if ptak_rect.colliderect(horni_rect) or ptak_rect.colliderect(dolni_rect):
stav_hry = "KONEC"
# 3. Vykreslování
okno.fill(MODRA_OBLOHA)
# Vykreslení trubek
for t in trubky:
# Horní trubka
horni_vyska = t["y_stred"] - (mezera_mezi_trubkami // 2)
pygame.draw.rect(okno, ZELENA, (t["x"], 0, trubka_sirka, horni_vyska))
# Dolní trubka
dolni_y = t["y_stred"] + (mezera_mezi_trubkami // 2)
pygame.draw.rect(okno, ZELENA, (t["x"], dolni_y, trubka_sirka, VYSKA_OKNA - dolni_y))
# Vykreslení ptáka (žlutý čtvereček)
pygame.draw.rect(okno, ZLUTYP_PTAK, (ptak_x, int(ptak_y), ptak_sirka, ptak_vyska))
# Texty přes obrazovku podle toho, v jakém stavu hra je
if stav_hry == "START":
zobraz_text("Stiskni MEZERNÍK", font_maly, BILA, SIRKA_OKNA//2, VYSKA_OKNA//2 - 50, zarovnat_stred=True)
zobraz_text("pro začátek létání", font_maly, BILA, SIRKA_OKNA//2, VYSKA_OKNA//2, zarovnat_stred=True)
elif stav_hry == "HRA":
# Skóre nahoře
zobraz_text(str(skore), font_velky, BILA, SIRKA_OKNA//2, 50, zarovnat_stred=True)
elif stav_hry == "KONEC":
# Konec hry - tisk statistik uprostřed
zobraz_text("GAME OVER", font_velky, CERVENA, SIRKA_OKNA//2, VYSKA_OKNA//2 - 50, zarovnat_stred=True)
zobraz_text(f"Skóre: {skore}", font_maly, BILA, SIRKA_OKNA//2, VYSKA_OKNA//2 + 10, zarovnat_stred=True)
zobraz_text("Stiskni MEZERNÍK pro restart", font_maly, CERNA, SIRKA_OKNA//2, VYSKA_OKNA//2 + 50, zarovnat_stred=True)
pygame.display.flip() # Prohození bufferu na obrazovku
hodiny.tick(FPS) # Udržuje hru na správné rychlosti snímků
# Takzvaný "Entry point" - zde program skutečně začne vykonávat kód
if __name__ == "__main__":
while True:
hlavni_smycka()