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()