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.
138 lines
5.2 KiB
138 lines
5.2 KiB
import pygame
|
|
import random
|
|
import sys
|
|
|
|
# Inicializace Pygame
|
|
pygame.init()
|
|
|
|
# --- Nastavení okna a základních konstant ---
|
|
SIRKA_OKNA = 800
|
|
VYSKA_OKNA = 600
|
|
VELIKOST_DILKU = 20 # Velikost jednoho čtverečku hada a jídla
|
|
FPS = 15 # Rychlost hry (počet snímků za sekundu)
|
|
|
|
# Barvy (R, G, B)
|
|
CERNA = (0, 0, 0)
|
|
BILA = (255, 255, 255)
|
|
ZELENA = (0, 255, 0)
|
|
CERVENA = (255, 0, 0)
|
|
|
|
# Vytvoření okna
|
|
okno = pygame.display.set_mode((SIRKA_OKNA, VYSKA_OKNA))
|
|
pygame.display.set_caption("Klasický Had (Snake)")
|
|
|
|
# Hodiny pro řízení rychlosti hry
|
|
hodiny = pygame.time.Clock()
|
|
font = pygame.font.SysFont("arial", 36)
|
|
|
|
def zobraz_text(text, barva, x, y):
|
|
"""Pomocná funkce pro vykreslení textu na obrazovku."""
|
|
text_plocha = font.render(text, True, barva)
|
|
okno.blit(text_plocha, (x, y))
|
|
|
|
def hlavni_smycka():
|
|
# --- Počáteční stav hry ---
|
|
# Had je reprezentován seznamem souřadnic [x, y]. První prvek je hlava.
|
|
had_telo = [
|
|
[SIRKA_OKNA // 2, VYSKA_OKNA // 2],
|
|
[SIRKA_OKNA // 2 - VELIKOST_DILKU, VYSKA_OKNA // 2],
|
|
[SIRKA_OKNA // 2 - 2 * VELIKOST_DILKU, VYSKA_OKNA // 2]
|
|
]
|
|
|
|
# Směr pohybu (změna x, změna y)
|
|
smer_x = VELIKOST_DILKU
|
|
smer_y = 0
|
|
|
|
# Jídlo - náhodná pozice zarovnaná na mřížku
|
|
jidlo_x = random.randrange(0, SIRKA_OKNA, VELIKOST_DILKU)
|
|
jidlo_y = random.randrange(0, VYSKA_OKNA, VELIKOST_DILKU)
|
|
|
|
skore = 0
|
|
konec_hry = False
|
|
|
|
# --- Hlavní herní smyčka ---
|
|
while True:
|
|
# 1. Zpracování událostí (klávesnice, křížek)
|
|
for udalost in pygame.event.get():
|
|
if udalost.type == pygame.QUIT:
|
|
pygame.quit()
|
|
sys.exit()
|
|
|
|
# Změna směru pomocí šipek
|
|
if udalost.type == pygame.KEYDOWN:
|
|
# Zabráníme otočení o 180 stupňů (had nemůže couvat do sebe)
|
|
if udalost.key == pygame.K_LEFT and smer_x == 0:
|
|
smer_x = -VELIKOST_DILKU
|
|
smer_y = 0
|
|
elif udalost.key == pygame.K_RIGHT and smer_x == 0:
|
|
smer_x = VELIKOST_DILKU
|
|
smer_y = 0
|
|
elif udalost.key == pygame.K_UP and smer_y == 0:
|
|
smer_x = 0
|
|
smer_y = -VELIKOST_DILKU
|
|
elif udalost.key == pygame.K_DOWN and smer_y == 0:
|
|
smer_x = 0
|
|
smer_y = VELIKOST_DILKU
|
|
|
|
# Pokud je hra u konce, stiskem mezerníku ji restartujeme
|
|
if udalost.key == pygame.K_SPACE and konec_hry:
|
|
return # Ukončí tuto iteraci smyčky a spustí hru znovu
|
|
|
|
if not konec_hry:
|
|
# 2. Logika hry (pohyb a kolize)
|
|
|
|
# Vypočítáme novou pozici hlavy
|
|
nova_hlava_x = had_telo[0][0] + smer_x
|
|
nova_hlava_y = had_telo[0][1] + smer_y
|
|
|
|
# Přidáme novou hlavu na začátek seznamu
|
|
had_telo.insert(0, [nova_hlava_x, nova_hlava_y])
|
|
|
|
# Kontrola kolize s jídlem
|
|
if nova_hlava_x == jidlo_x and nova_hlava_y == jidlo_y:
|
|
skore += 1
|
|
# Vygenerujeme nové jídlo jinde
|
|
jidlo_x = random.randrange(0, SIRKA_OKNA, VELIKOST_DILKU)
|
|
jidlo_y = random.randrange(0, VYSKA_OKNA, VELIKOST_DILKU)
|
|
# DŮLEŽITÉ: Pokud had sní jídlo, neodmažeme ocas. Tím had povyroste!
|
|
else:
|
|
# Pokud had jídlo nesnědl, odmažeme ocas, aby délka zůstala stejná
|
|
had_telo.pop()
|
|
|
|
# Kontrola kolize se stěnami (náraz do okraje okna)
|
|
if (nova_hlava_x < 0 or nova_hlava_x >= SIRKA_OKNA or
|
|
nova_hlava_y < 0 or nova_hlava_y >= VYSKA_OKNA):
|
|
konec_hry = True
|
|
|
|
# Kontrola kolize hada se sebou samým
|
|
# Pokud nová pozice hlavy je na stejném místě jako jakýkoli jiný dílek těla
|
|
for dilek in had_telo[1:]:
|
|
if nova_hlava_x == dilek[0] and nova_hlava_y == dilek[1]:
|
|
konec_hry = True
|
|
|
|
# 3. Vykreslování
|
|
okno.fill(CERNA) # Vymažeme obrazovku (černé pozadí)
|
|
|
|
# Vykreslíme jídlo jako červený čtverec
|
|
pygame.draw.rect(okno, CERVENA, (jidlo_x, jidlo_y, VELIKOST_DILKU, VELIKOST_DILKU))
|
|
|
|
# Vykreslíme tělo hada jako zelené čtverce
|
|
for dilek in had_telo:
|
|
pygame.draw.rect(okno, ZELENA, (dilek[0], dilek[1], VELIKOST_DILKU, VELIKOST_DILKU))
|
|
|
|
# Zobrazíme skóre
|
|
zobraz_text(f"Skóre: {skore}", BILA, 10, 10)
|
|
|
|
# Pokud hra skončila, zobrazíme text pro restart
|
|
if konec_hry:
|
|
zobraz_text("Konec hry! Stiskni MEZERNÍK pro novou hru.", CERVENA, 100, VYSKA_OKNA // 2)
|
|
|
|
pygame.display.flip() # Propíšeme změny na obrazovku
|
|
|
|
# 4. Časování - čekání, aby hra běžela na zadaný počet FPS
|
|
hodiny.tick(FPS)
|
|
|
|
# Spouštíme hru v nekonečné smyčce, aby po Game Over a mezerníku začala znovu
|
|
if __name__ == "__main__":
|
|
while True:
|
|
hlavni_smycka()
|
|
|