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