import pygame import sys import random pygame.init() SIRKA = 800 VYSKA = 600 okno = pygame.display.set_mode((SIRKA, VYSKA)) pygame.display.set_caption("Skákačka - Plná Hra") # --- Barvy --- BILA = (255, 255, 255) CERNA = (0, 0, 0) MODRA = (50, 150, 255) # Obloha ZELENA = (50, 200, 50) # Země CERVENA = (255, 0, 0) # Překážky hodiny = pygame.time.Clock() font = pygame.font.SysFont("Arial", 40) font_maly = pygame.font.SysFont("Arial", 25) # --- Stavový automat --- STAV_MENU = 0 STAV_HRA = 1 STAV_KONEC = 2 stav = STAV_MENU # --- Nastavení hráče a fyziky --- podlaha_y = VYSKA - 50 # Odkud začíná tráva (y souřadnice) hrac_sirka = 40 hrac_vyska = 40 # Gravitace v počítačové hře znamená, že rychlost pádu se KAZDÝM SNÍMKEM (FPS) zvyšuje! gravitace = 0.6 sila_skoku = -12 # Skok funguje jako nastavení nárazové záporné rychlosti (směr vzhůru) # --- Funkce pro reset --- def reset_hry(): global hrac_x, hrac_y, rychlost_y, na_zemi, prekazky, skore, rychlost_hry hrac_x = 100 hrac_y = podlaha_y - hrac_vyska rychlost_y = 0 na_zemi = True # Aby mohl hráč vyskočit, musí samozřejmě stát pevně na zemi prekazky = [] # Seznam všech aktuálních překážek v obrazovce, začíná prázdný skore = 0 rychlost_hry = 6 reset_hry() # --- Vlastní Časovač (Custom Event) --- # Tímto si vytvoříme VLASTNÍ UDÁLOST podobnou pygame.QUIT, která se automaticky spustí každých 1500 milisekund (1.5s) SPAWN_PREKAZKY = pygame.USEREVENT + 1 pygame.time.set_timer(SPAWN_PREKAZKY, 1500) bezime = True while bezime: for udalost in pygame.event.get(): if udalost.type == pygame.QUIT: bezime = False if udalost.type == pygame.KEYDOWN: if stav == STAV_MENU and udalost.key == pygame.K_SPACE: stav = STAV_HRA elif stav == STAV_KONEC and udalost.key == pygame.K_SPACE: reset_hry() stav = STAV_HRA # Jak se skáče? Jen když se stiskne šipka nahoru A ZÁROVEŇ postava stojí na zemi elif stav == STAV_HRA and udalost.key == pygame.K_UP and na_zemi: rychlost_y = sila_skoku # Dáme mu masivní impuls směrem nahoru na_zemi = False # Už není na zemi, takže nesmí znovu vyskočit (zabráníme double skokům) # Zpracování naší vlastní události pro přidání nové překážky if udalost.type == SPAWN_PREKAZKY and stav == STAV_HRA: # Přidáme nový pygame.Rect() překážky úplně na pravý konec obrazovky (SIRKA) prekazky.append(pygame.Rect(SIRKA, podlaha_y - 40, 30, 40)) rychlost_hry += 0.1 # Postupně celou hru zrychlujeme, čím déle hráč hraje if stav == STAV_HRA: # --- Fyzika postavy --- rychlost_y += gravitace # Gravitace neustále táhne rychlost do kladných hodnot (směrem dolů) hrac_y += rychlost_y # Aplikujeme tuto rychlost na aktuální Y pozici hráče # Zastavení o podlahu, aby se hráč nepropadl skrz texturu do nekonečna if hrac_y + hrac_vyska >= podlaha_y: hrac_y = podlaha_y - hrac_vyska # Srovnáme ho přesně s podlahou rychlost_y = 0 # Rychlost pádu je najednou nula na_zemi = True # Zase může skákat hrac_rect = pygame.Rect(hrac_x, hrac_y, hrac_sirka, hrac_vyska) # --- Překážky --- # Trik prekazky[:] znamená, že for-cyklus prochází přes KOPII seznamu. # To nám umožňuje během cyklu prvky ze seznamu (z toho originálního) bezpečně odstraňovat # bez toho, aby for-cyklus 'přeskočil' další prvky kvůli změně délky seznamu. for p in prekazky[:]: p.x -= int(rychlost_hry) # Překážka se hýbe směrem k hráči doleva # Pokud překážka narazí přímo do hráče if p.colliderect(hrac_rect): stav = STAV_KONEC # Pokud překážka zajela celá za levý okraj (x < -30) if p.x < -30: prekazky.remove(p) # Můžeme smazat skore += 1 # Získáme bod za úspěšné přeskočení # --- Vykreslování --- okno.fill(MODRA) # Obloha # Tráva/podlaha (nakreslí se obdélník od y = podlaha_y až úplně dolů) pygame.draw.rect(okno, ZELENA, (0, podlaha_y, SIRKA, VYSKA - podlaha_y)) if stav == STAV_MENU: text = font.render("SKÁKAČKA", True, BILA) start = font_maly.render("Stiskni MEZERNÍK. Skáče se šipkou NAHORU.", True, CERNA) okno.blit(text, (SIRKA//2 - text.get_width()//2, 200)) okno.blit(start, (SIRKA//2 - start.get_width()//2, 300)) elif stav == STAV_HRA: pygame.draw.rect(okno, CERNA, hrac_rect) # Nakreslení Hráče for p in prekazky: pygame.draw.rect(okno, CERVENA, p) # Nakreslení všech aktuálních překážek skore_text = font.render(f"Skóre: {skore}", True, CERNA) okno.blit(skore_text, (10, 10)) elif stav == STAV_KONEC: text = font.render("KONEC HRY", True, CERVENA) skore_text = font.render(f"Dosažené skóre: {skore}", True, BILA) restart = font_maly.render("Stiskni MEZERNÍK pro novou hru", True, CERNA) okno.blit(text, (SIRKA//2 - text.get_width()//2, 150)) okno.blit(skore_text, (SIRKA//2 - skore_text.get_width()//2, 220)) okno.blit(restart, (SIRKA//2 - restart.get_width()//2, 300)) pygame.display.flip() hodiny.tick(60) pygame.quit() sys.exit()