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.
169 lines
7.3 KiB
169 lines
7.3 KiB
import pygame
|
|
import sys
|
|
import random
|
|
|
|
pygame.init()
|
|
|
|
# --- NASTAVENÍ OKNA A PROMĚNNÝCH PROSTŘEDÍ ---
|
|
SIRKA = 800
|
|
VYSKA = 600
|
|
okno = pygame.display.set_mode((SIRKA, VYSKA))
|
|
pygame.display.set_caption("Skákačka přes překážky")
|
|
|
|
# --- BARVY ---
|
|
BILA = (255, 255, 255)
|
|
CERNA = (0, 0, 0)
|
|
MODRA = (50, 150, 255) # Na modrou oblohu
|
|
ZELENA = (50, 200, 50) # Zelená pro plošinu trávy
|
|
CERVENA = (255, 0, 0) # Nebezpečné překážky v cestě
|
|
|
|
hodiny = pygame.time.Clock()
|
|
font = pygame.font.SysFont("Arial", 40)
|
|
font_maly = pygame.font.SysFont("Arial", 25)
|
|
|
|
# --- STAVOVÝ AUTOMAT HRY ---
|
|
STAV_MENU = 0
|
|
STAV_HRA = 1
|
|
STAV_KONEC = 2
|
|
stav = STAV_MENU
|
|
|
|
# --- FYZIKA A HERNÍ PROMĚNNÉ ---
|
|
podlaha_y = VYSKA - 50 # V jaké hloubce se nachází hrana země/podlahy? (od shora dolů)
|
|
hrac_sirka = 40
|
|
hrac_vyska = 40
|
|
|
|
# Fyzika
|
|
# Gravitace způsobuje trvalé ZRYCHLOVÁNÍ pádu. Ne rychlost, zrychlení!
|
|
gravitace = 0.6
|
|
# Skok není nic jiného, než extrémní rána do záporných hodnot na ose Y (odstřelení do stropu)
|
|
sila_skoku = -12
|
|
|
|
def reset_hry():
|
|
"""Funkce pro nahození proměnných do výchozího stavu pro start čisté hry"""
|
|
global hrac_x, hrac_y, rychlost_y, na_zemi, prekazky, skore, rychlost_hry
|
|
hrac_x = 100 # Hráč stojí celkem blízko levému kraji, aby měl čas reagovat
|
|
|
|
# Hráče položíme tak, aby jeho nohy (y + výška) přesně seděly na 'podlaha_y'
|
|
hrac_y = podlaha_y - hrac_vyska
|
|
rychlost_y = 0
|
|
na_zemi = True # Nyní stojí na zemi (a smí tedy zmáčknout Skok)
|
|
|
|
# Místo abychom dělali překážku po překážce, uchováme je jako seznam (List)
|
|
prekazky = []
|
|
skore = 0
|
|
rychlost_hry = 6 # Jak rychle ubíhá terén směrem k hráči doleva?
|
|
|
|
reset_hry()
|
|
|
|
# --- VLASTNÍ ČASOVAČ (Custom Event) ---
|
|
# Trik z programování: Pygame neustále běží ve smyčce a "naslouchá" událostem (jako stisk myši).
|
|
# Zde si vyrobíme událost NAŠI VLASTNÍ. Pojmenujeme ji libovolně SPAWN_PREKAZKY.
|
|
SPAWN_PREKAZKY = pygame.USEREVENT + 1
|
|
# Nastavíme pygame časovač tak, ať tuto 'neviditelnou klávesu SPAWN_PREKAZKY' pípne
|
|
# do fronty událostí přesně každých 1500 milisekund (1.5 sekundy). Úplně automaticky!
|
|
pygame.time.set_timer(SPAWN_PREKAZKY, 1500)
|
|
|
|
bezime = True
|
|
while bezime:
|
|
|
|
# 1. ZPRACOVÁNÍ UDÁLOSTÍ
|
|
for udalost in pygame.event.get():
|
|
if udalost.type == pygame.QUIT:
|
|
bezime = False
|
|
|
|
# Zkoumání stisku kláves jako POUHÁ UDÁLOST. To znamená "zmáčklo se to"
|
|
# neboli neřešíme, jestli se to zrovna drží stlačené. Ideální pro Starty a Skoky.
|
|
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 hráč skáče? Šipka nahoru! Ale MUSÍ zároveň stát na zemi (na_zemi == True),
|
|
# jinak bychom mohli skákat ve vzduchu jak pták (tzv. multi-jump)
|
|
elif stav == STAV_HRA and udalost.key == pygame.K_UP and na_zemi:
|
|
rychlost_y = sila_skoku # Tímto dáváme drtivý impulz rychlosti směrem NAHORU
|
|
na_zemi = False # Teď už jsme ve vzduchu!
|
|
|
|
# Tady čekáme na PÍPNUTÍ z našeho automatického Custom Časovače!!!
|
|
if udalost.type == SPAWN_PREKAZKY and stav == STAV_HRA:
|
|
# Objevil se signál, že uplynulo 1.5 sekundy.
|
|
# Přidáme novou překážku (čtvereček červený) na konec obrazovky (SIRKA)
|
|
# Tyto překážky ukládáme rovnou jako Rect, protože se to pak hodí u kolizí
|
|
prekazky.append(pygame.Rect(SIRKA, podlaha_y - 40, 30, 40))
|
|
|
|
# Aby to nebylo nudné, pokaždé hru o malilinký kousíček zrychlíme.
|
|
rychlost_hry += 0.1
|
|
|
|
# 2. LOGIKA
|
|
if stav == STAV_HRA:
|
|
# --- FYZIKA SKÁKÁNÍ ---
|
|
# Neúprosná gravitace v každém milisekundovém snímku přidává směrem DOLŮ!
|
|
rychlost_y += gravitace
|
|
# Změníme opravdovou Y pozici hráče o tuto aktuální rychlost.
|
|
# Výsledek? Hráč zpomaluje směrem nahoru... zastaví se... a začne opět zrychlovat dolů k zemi!
|
|
hrac_y += rychlost_y
|
|
|
|
# Musíme ale zabránit tomu, aby hráč propadl podlahou do hlubin!
|
|
if hrac_y + hrac_vyska >= podlaha_y:
|
|
# Opravíme jeho Y, posadíme ho přesně podrážkama na okraj podlahy
|
|
hrac_y = podlaha_y - hrac_vyska
|
|
rychlost_y = 0 # Rychlost dopadu zrušíme, stál by na místě
|
|
na_zemi = True # Oznámíme, že zase můžeme skákat, dotýkáme se
|
|
|
|
# Vytvoření virtuálního obalu přes našeho hráče kvůli měření kolizí
|
|
hrac_rect = pygame.Rect(hrac_x, hrac_y, hrac_sirka, hrac_vyska)
|
|
|
|
# --- LOGIKA VŠECH PŘEKÁŽEK NA TRATI ---
|
|
# For cyklus prekazky[:] zkoumá tzv. KOPII seznamu.
|
|
# Je to proto, abychom z originálu mohli prvek bezpečně vymazat a nic "nepřeskočili".
|
|
for p in prekazky[:]:
|
|
p.x -= int(rychlost_hry) # Každá jedna překážka jede nezadržitelně doleva směrem na nás
|
|
|
|
# Co když se obdélníčky Hráče a Překážky překrývají? -> BOUM!
|
|
if p.colliderect(hrac_rect):
|
|
stav = STAV_KONEC
|
|
|
|
# Pokud na nás nenarazila, zajela na levém okraji pod 0 a zmizela (p.x < -30)
|
|
if p.x < -30:
|
|
prekazky.remove(p) # Hráč ji s úspěchem přežil a překážka zajela za monitor. Smazat z RAM!
|
|
skore += 1 # Přičteme za ni bod.
|
|
|
|
# 3. KRESLENÍ (na monitor)
|
|
okno.fill(MODRA) # Obloha
|
|
# Nakreslíme zelený pruh od čáry podlahy (podlaha_y) dolů až k zemi, bude dělat vizuál trávy
|
|
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:
|
|
# Nakreslení postavičky hráče - využijeme ten Rect obal, co už jsme si spočítali
|
|
pygame.draw.rect(okno, CERNA, hrac_rect)
|
|
|
|
# Nakreslíme úplně všechny načítané nepřátelské Rect obdélníky jako červené objekty
|
|
for p in prekazky:
|
|
pygame.draw.rect(okno, CERVENA, p)
|
|
|
|
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))
|
|
|
|
# .flip() překlopí to, co jsme nakreslili v paměti na obrazovku k hráči
|
|
pygame.display.flip()
|
|
hodiny.tick(60) # Cílíme na hladkých 60 FPS (Frames Per Second)
|
|
|
|
pygame.quit()
|
|
sys.exit()
|
|
|