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.
141 lines
5.6 KiB
141 lines
5.6 KiB
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()
|
|
|