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()