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.

146 lines
5.8 KiB

import pygame
import sys
pygame.init()
# --- Nastavení okna ---
SIRKA = 800
VYSKA = 600
okno = pygame.display.set_mode((SIRKA, VYSKA))
pygame.display.set_caption("Pong - Plná Hra")
# --- Barvy ---
BILA = (255, 255, 255)
CERNA = (0, 0, 0)
ZELENA = (0, 255, 0)
hodiny = pygame.time.Clock()
font_velky = pygame.font.SysFont("Arial", 50)
font_maly = pygame.font.SysFont("Arial", 30)
# --- Stavový automat ---
# Hra může být ve 3 různých stavech. Díky tomu víme, jaká pravidla zrovna platí a co kreslit
STAV_MENU = 0
STAV_HRA = 1
STAV_KONEC = 2
stav = STAV_MENU # Na začátku jsme v menu
# --- Proměnné hráčů (pálek) a míčku ---
palka_sirka = 15
palka_vyska = 100
rychlost_palky = 7
micek_velikost = 15
# Funkce pro resetování proměnných na začátek (použije se při nové hře)
def reset_hry():
# Pomocí klíčového slova 'global' říkáme funkci, aby upravila proměnné venku (celkové proměnné)
global hrac1_y, hrac2_y, skore1, skore2, micek_x, micek_y, micek_rychlost_x, micek_rychlost_y
hrac1_y = VYSKA // 2 - palka_vyska // 2
hrac2_y = VYSKA // 2 - palka_vyska // 2
skore1 = 0
skore2 = 0
micek_x = SIRKA // 2 - micek_velikost // 2
micek_y = VYSKA // 2 - micek_velikost // 2
micek_rychlost_x = 5
micek_rychlost_y = 5
reset_hry() # Zavoláme ihned, abychom pro začátek vůbec měli výchozí hodnoty
bezime = True
while bezime:
# 1. Zpracování událostí
for udalost in pygame.event.get():
if udalost.type == pygame.QUIT:
bezime = False
# Reakce na stisk kláves nezávisle na plynulém pohybu (např. pouhé stisknutí mezerníku)
if udalost.type == pygame.KEYDOWN:
if stav == STAV_MENU and udalost.key == pygame.K_SPACE:
stav = STAV_HRA # Z menu se posuneme rovnou do hry
elif stav == STAV_KONEC and udalost.key == pygame.K_SPACE:
reset_hry() # Z konce hry ji vyresetujeme a jdeme hrát
stav = STAV_HRA
klavesy = pygame.key.get_pressed()
# 2. Logika se provádí POUZE tehdy, když zrovna HRAJEME
if stav == STAV_HRA:
# Ovládání hráče 1 vlevo (Klávesy W a S)
if klavesy[pygame.K_w] and hrac1_y > 0:
hrac1_y -= rychlost_palky
if klavesy[pygame.K_s] and hrac1_y < VYSKA - palka_vyska:
hrac1_y += rychlost_palky
# Ovládání hráče 2 vpravo (Šipky Nahoru a Dolů)
if klavesy[pygame.K_UP] and hrac2_y > 0:
hrac2_y -= rychlost_palky
if klavesy[pygame.K_DOWN] and hrac2_y < VYSKA - palka_vyska:
hrac2_y += rychlost_palky
# Pohyb míčku (k X a Y se neustále přičítá aktuální rychlost)
micek_x += micek_rychlost_x
micek_y += micek_rychlost_y
# --- Odraz míčku od horní a dolní stěny okna ---
# Trik: Vynásobením rychlosti číslem -1 se obrátí směr pohybu na opačný!
if micek_y <= 0 or micek_y >= VYSKA - micek_velikost:
micek_rychlost_y *= -1
# --- Odraz od pálek hráčů (kolize obdélníků) ---
rect_micek = pygame.Rect(micek_x, micek_y, micek_velikost, micek_velikost)
rect_hrac1 = pygame.Rect(30, hrac1_y, palka_sirka, palka_vyska)
rect_hrac2 = pygame.Rect(SIRKA - 30 - palka_sirka, hrac2_y, palka_sirka, palka_vyska)
if rect_micek.colliderect(rect_hrac1) or rect_micek.colliderect(rect_hrac2):
micek_rychlost_x *= -1.1 # Po odrazu otočíme směr (do stran) a míček trošku zrychlíme (o 10%)
# --- Zjištění gólu (míček vyletí z obrazovky ven vpravo nebo vlevo) ---
if micek_x < 0:
skore2 += 1 # Gól pro hráče 2
micek_x, micek_y = SIRKA // 2, VYSKA // 2 # Reset na střed okna
micek_rychlost_x = 5 # Vrácení pomalejší rychlosti a míření na pravou stranu
elif micek_x > SIRKA:
skore1 += 1 # Gól pro hráče 1
micek_x, micek_y = SIRKA // 2, VYSKA // 2 # Reset na střed okna
micek_rychlost_x = -5 # Míření na levou stranu
# --- Podmínka pro vítězství ve hře ---
if skore1 >= 5 or skore2 >= 5:
stav = STAV_KONEC
# 3. Vykreslování
okno.fill(CERNA)
# Co přesně kreslíme? Záleží na tom, v jakém jsme stavu!
if stav == STAV_MENU:
nadpis = font_velky.render("PONG", True, BILA)
navod = font_maly.render("Stiskni MEZERNÍK pro start", True, ZELENA)
okno.blit(nadpis, (SIRKA//2 - nadpis.get_width()//2, 200))
okno.blit(navod, (SIRKA//2 - navod.get_width()//2, 300))
elif stav == STAV_HRA:
# Vykreslení půlící čáry uprostřed (aaline znamená anti-aliased, tedy hezky vyhlazená čára)
pygame.draw.aaline(okno, BILA, (SIRKA // 2, 0), (SIRKA // 2, VYSKA))
# Vykreslení pálek a míčku z našich Rect obdélníků
pygame.draw.rect(okno, BILA, rect_hrac1)
pygame.draw.rect(okno, BILA, rect_hrac2)
pygame.draw.ellipse(okno, BILA, rect_micek) # ellipse z obdélníku udělá kruh/ovál
# Skóre nahoře uprostřed
text_skore = font_velky.render(f"{skore1} {skore2}", True, BILA)
okno.blit(text_skore, (SIRKA // 2 - text_skore.get_width() // 2, 20))
elif stav == STAV_KONEC:
# Zjištění, kdo vyhrál pomocí tzv. zkráceného if/else (ternárního operátoru)
vitez = "Hráč 1" if skore1 >= 5 else "Hráč 2"
text_vitez = font_velky.render(f"{vitez} vyhrál!", True, ZELENA)
text_restart = font_maly.render("Stiskni MEZERNÍK pro novou hru", True, BILA)
okno.blit(text_vitez, (SIRKA//2 - text_vitez.get_width()//2, 200))
okno.blit(text_restart, (SIRKA//2 - text_restart.get_width()//2, 300))
pygame.display.flip()
hodiny.tick(60)
pygame.quit()
sys.exit()