3. diel - Pygame - Pong - Príprava
V minulej lekcii, Pygame - Kreslenie a pohyb , sme sa už naučili, ako kresliť obrazce a ako s nimi pohybovať. Je najvyšší čas naprogramovať si nejakú tú hru. A čo by mohlo byť lepšie, než legendárny Pong?
![Hra pong v pygame pre Python - Pygame](images/40014/snimek_z_2019-12-21_18-24-51.png)
Plánujeme hru
Začať programovať čokoľvek, než vieme, čo presne chceme, nie je úplne dobrý nápad. Preto, než začneme, bolo by dobré si chvíľu sadnúť, pripraviť si šálku kávy či čaju a premyslieť, čo je naším cieľom. Odborne sa tejto fáze procesu vývoja software hovorí analýza.
Po vysoko osviežujúcim šálke teplého nápoja a chvíľu premýšľania môžeme dôjsť k nasledujúcim požiadavkám:
- na obrazovke budú naľavo a napravo obdĺžniky, ktoré reprezentujú hráča
- hráči sa môžu pohybovať hore a dole
- medzi nimi bude lietať štvorec, predstavujúce lopta
- lopta bude postupom času zrýchľovať
- ak lopta narazí do vrchnej či spodnej časti obrazovky alebo hráča, odrazí sa
- ak lopta narazí do ľavej alebo pravej časti obrazovky, pripočíta bod protiľahlému hráči
- skóre sa zobrazuje hore uprostred obrazovky
- (Nastaviteľné) druhý hráč môže byť ovládaný počítačom
Stavy hry
Keď teda už zhruba tušíme, ako bude naša hra vyzerať, pravdepodobne sme došli k záveru, že naša hra bude mať celkovo tri stavy:
- Začiatok hry, výber, či chceme hrať s druhým hráčom, alebo proti počítaču
- Začiatok kola, hra je pozastavená, aby sa mali hráči čas nachystať
- Samotná hra, ktorá je ukončená až chybou jedného z hráčov
Zároveň by tiež nebolo zlé, keby naša hra bežala zakaždým s rovnakým pomerom strán, nezávisle na veľkosti obrazovky používateľa.
Čo je pre nás nové?
Určite ste si všimli, že pár vecí sme sa ešte neučili. Jedná sa prevažne o tieto témy.
Kreslenie textu
Pokiaľ si chceme na obrazovku vykresliť text, musíme si najskôr vytvoriť písmo.
Systémové písmo
Ak chceme použiť systémové písmo, použijeme:
font = pygame.font.SysFont(font_name, size)
, Kde font_name
je meno nainštalovaného písma a
size
je potom veľkosť v pixeloch.
Zoznam všetkých dostupných systémových písiem získame pomocou
pygame.font.get_fonts()
.
Vlastné písmo
Ak nechceme použiť nejaké už nainštalované písmo, ale namiesto toho radšej nejaké vlastné písmo, ktoré sami pribalíme k nášmu programu, nahráme ho pomocou:
font = pygame.font.Font(path, size)
Parameter size
zostáva rovnaký, ale namiesto mena
systémového písma teraz vkladáme cestu k .ttf
súboru s naším
písmom. Ak ako path
vložíme None
, použije sa
predvolené písmo.
Vykreslenie písma
Akonáhle máme takto vytvorené písmo, vyrenderuje ho pomocou:
text = font.render(txt, True, color)
, Kde txt
je string, ktorý chceme vyrenderovať;
True
je parameter pre antialiasing, ktorý zaoblí rohy písma
(čo je všeobecne žiaduce) a color
je farba písma.
Teraz by sme mali v premennej text
uložený povrch, ktorý nám
ešte zostáva vykresliť na obrazovku. Takže ak by sme chceli vykresliť
červený text na pozíciu (10, 10)
, mohol by náš kód vyzerať
nejako takto:
font = pygame.font.Font('myfont.ttf', 30) # nahraje písmo uložené v souboru myfont.ttf text = font.render("Cerveny text", True, (255, 0, 0)) screen.blit(text, (10, 10))
Zachovanie veľkosti pri ľubovoľnej veľkosti obrazovky
Doteraz sme si vždy vytvorili premennú
screen = pygame.display.set_mode(...)
. Takto sme museli nastaviť
pevné rozmery, alebo zisťovať rozmery pri vykreslenie na celú obrazovku.
Oveľa jednoduchší prístup by ale bol, ak by sme mohli vykresľovať len pre
jedno rozlíšenie a potom celú obrazovku automaticky previesť na iné. Tento
efekt môžeme dosiahnuť nasledovne:
# povrch screen bude mít rozlišení, na které cílíme screen = pygame.Surface((1920, 1080)) # displej bude mít libovolné rozlišení (např. fullscreen) display = pygame.display.set_mode((0, 0)) # klasicky kreslíme vše na screen pygame.draw.rect(screen, (255, 255, 255), pygame.Rect((10, 10), (100, 100))) # ale v závěru kreslící funkce převedeme celý screen na velikost displeje pygame.transform.scale(screen, display.get_size(), display) # a zobrazíme provedené změny na monitoru pygame.display.flip()
Pohybovanie obdĺžniky
Pre kreslenie obdĺžnikov sme zadali súradnice x
a
y
, čím sme v každom cykle vytvorili nový obdĺžnik na novej
pozícii. Samotný obdĺžnik v pygame je ale
oveľa mocnejší. Pre začiatok nám bude stačiť poznať funkciu
rect.move_ip(dx, dy)
, ktorá posunie obdĺžnikom o dx
pixelov doprava ao dy
pixelov dole. Existuje aj funkcia
rect.move(dx, dy)
, ktorá ale namiesto posunutiu pôvodného
obdĺžnika vráti nový obdĺžnik s posunutím.
Kolízie obdĺžnikov
Obdĺžniky v pygame sa za nás tiež postarajú o zistenie kolízií, teda či sa stretávajú s nejakým iným objektom. Hlavné funkcie, ktoré by nás mohli zaujímať, sú:
rect.collidepoint((x, y))
- vraciaTrue
, ak sa bod(x, y)
nachádza vnútri obdĺžnikarect.colliderect(rect2)
- vraciaTrue
, ak majú dva obdĺžniky prienikrect.collidelist(lst)
- vraciaTrue
, ak aspoň jeden z obdĺžnikov vnútri zoznamu má prienik s hlavnýmrect.collidelistall(lst)
- vraciaTrue
, ak všetky z obdĺžnikov vnútri zozname majú prienik s hlavným
Matematika
Veľká časť herného vývoja sa bez použitia matematiky nezaobíde. Zoberme si napríklad balón. Ten v našej hre lieta pod určitým uhlom a môže sa odrážať, pričom uhol odrazu sa rovná uhlu dopadu. Aby sme boli schopní niečo také vytvoriť, potrebujeme poznať aspoň základné goniometrické funkcie, jednotkovou kružnicu a mať povedomie o prevode medzi jednotkami stupňov a radiány.
Zatiaľ všetko
Ako vidíme, vždy je najskôr nutné sa pozrieť, čo budeme v našom plánovanom programe potrebovať. Ak vám táto lekcia pripadala trochu suchšie, tak sa nebojte, budúci lekcie, Pygame - Pong - Prostredie a herné objekty , bude naopak iba praktická a skončí s hotovou hrou.