IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

6. diel - Skákačka v Pygame - Plánujeme hru

V nasledujúcom tutoriále Pygame zahájime väčší projekt. Ukážeme si postupne, ako naprogramovať prvú poriadnu hru pomocou knižnice Pygame – Skákačku. V tejto lekcii sa zameriame na zložkovú štruktúru a hernú slučku. Hra bude vyzerať takto:

Hra v Pygame – Skákačka - Pygame

Plánujeme Skákačku v Pygame

Pred každým veľkým projektom je najskôr potrebné ujasniť si naše predstavy o ňom. Najprv si teda rozoberieme, čo vlastne definuje takú „poriadnu“ hru:

  • herný engine, čo riadi celú hru,
  • grafické objekty ako múr alebo figúrka hráča, schopné detekovať kolízie s inými objektmi, či pohybovať sa,
  • rôzne ťažké levely,
  • hudba v pozadí.
Teraz skúsime prepojiť túto predstavu s tým, čo už poznáme z predchádzajúcich lekcií. Pod herným enginom si môžeme predstaviť objekt typu Game. Ten bude obsahovať hernú slučku, ktorá bude operovať s Pygame `eventy. Se zvukem jsme již také pracovali. V knihovně `Pygame s ním operuje modul pygame.mixer a jeho podtrieda pygame.mixer.Sound, ktorým musíme odovzdať zdrojový súbor zvuku. Čo pridáme nanovo, budú grafické objekty a levely.

Grafika

Grafické objekty sú v niečom podobné zvukom. V Pygame ich síce nereprezentuje samotná trieda, ale rovnako ako pri pygame.mixer.Sound je na ich operovanie potrebná tá grafická časť – obrázok v pamäti. Pretože ich budeme musieť ovládať sami, zaslúži si vlastnú triedu. Najlepšie jednu pre obrázky všeobecne a potom pre každý typ jednu podtriedu, ktorá bude dediť z triedy sebe nadradené.

Levely

Čo sa levelov týka, tie si tiež budeme musieť uložiť externe mimo kódu. Aby sa nám jednotlivé úrovne dobre vymýšľali, hodilo by sa ich mať graficky. Lenže to by sa zase veľmi zle čítalo počítaču. Zvoľme preto kompromis a spracujme ich ako text. Zavedieme kľúčové slová/znaky pre jednotlivé objekty, z ktorých sa bude skladať daná herná plocha. Na prenos tohto typu dát sa momentálne používajú tri formáty.

CSV a XML

CSV je skratka z anglického comma separated values, čiže čiarkami oddelenej hodnoty. Názov je v tomto prípade veľmi výstižný: čiarkami oddelenej hodnoty sú totiž zhruba všetko, čo v tomto formáte nájdeme. Keby sme si teda chceli uložiť náš level, vyzeralo by to napríklad takto: zeď, hráč, vzduch, vzduch, cíl.

No dobrá, ale čo keby sme chceli viacriadkové levely? A ako by sme úrovne vôbec odlíšili od seba? CSV je skvelé, keď potrebujeme prenášať obrovské množstvo dát, pretože jediné, čo obsahuje, sú dáta samotné. To sa nám ale príliš nehodí.

Naproti tomu XML toto má vyriešené pekne. Používa totiž hierarchickú štruktúru podobnú HTML. Vďaka tomu však znateľne narastá objem dát. Už len na uloženie jedného prvku by sme potrebovali tri „slová“: počiatočný tag, vlastný prvok a koncový tag. My však nebudeme potrebovať toľko hierarchických oddielov, aby sa nám XML vyplatilo. Takže čo s tým?

JSON

JSON je formát, ktorý kombinuje prednosti CSV aj XML – má dobre vyvinutú hierarchiu a nie je tak pamäťovo rozsiahly. Ponúka sa otázka, prečo sa teda nepoužíva iba JSON. Je to preto, že obe z týchto výhod robí o niečo horšie ako pôvodné formáty. Na naše účely je však JSON ideálnym kompromisom. Dáta totiž radia do štruktúr podobných slovníkom a zoznamom v Pythone. To nám výrazne uľahčí vytváranie ich alternatív v programe.

Logovanie

Formáty všetkého máme rozhodnuté, zostáva teda už len posledný krok do začiatku programovania. Púšťame sa do veľkého projektu av tých je občas zložité sa vyznať. Preto do nášho kódu zahrnieme aj knižnicu logging. Tá umožňuje programu poslať upozornenie, že nastala určitá situácia. Tá býva obvykle popísaná, pričom tento popis môže obsahovať aj hodnoty premenných. Navyše táto knižnica umožňuje zaviesť samostatný súbor, kam sa tieto správy budú ukladať, či rozlíšiť dôležitosť a úroveň hlásenia.

Štruktúra

Poďme si teda pripraviť štruktúru nášho kódu. Vytvoríme si zložku nášho projektu a pomenujeme ju Skakacka/. V nej vytvoríme súbor main.py, ktorý bude prvé, čo sa spustí. Pre ďalší kód pridáme podpriečinky engine/ a game_scr/, kde budú zdroje objektov hry, a res/ (skratka z resources), kam budeme ukladať všetky nekódové časti našej hry – obrázky, zvuky, alebo aj fonty. Podľa týchto zdrojov vytvoríme aj podzložky v res/: fonts/, imgs/, sounds/ a music/. Rozlíšime tak zároveň aj zvuky, čo sa prehrajú raz pri nejakej akcii (sounds) a hudbu, čo bude hrať v pozadí (music).

Herná slučka

Teraz už sa môžeme vrhnúť na samotné programovanie. V priečinku engine/ vytvoríme súbor game.py. Tu bude hlavná časť celého programu - trieda Game. Naimportujeme sem teda knižnicu Pygame a vytvoríme zatiaľ prázdnu triedu Game. V jej konštruktore zároveň zinicializujeme samotnú inštanciu pygame:

import pygame

class Game:
    def __init__(self):
        pygame.init()

Do konštruktora tiež pridáme parameter self._is_running, ktorý tu nastavíme na True. Pretože tento parameter by sa mal ovplyvňovať iba cez metódy triedy (keďže má podčiarknutie na začiatku názvu – v Pythone nám to síce nikto nezakáže, ale je to programátorská konvencia), zodpovedajúcu metódu musíme vytvoriť. Vzhľadom na to, že self._is_running nám hovorí, či hra beží alebo nie, našu metódu pomenujeme end(), aby bolo jasné, že našu hru ukončuje:

class Game:
    def __init__(self):
        self._running = True
        pygame.init()

    def end(self):
        self._running = False

Posledná metóda, ktorú si v tejto lekcii vytvoríme, bude run(). Ako už názov napovedá, v tejto metóde pobeží samotná hra. Bude sa tu teda nachádzať naša stará známa herná slučka. Tá ako obvykle pobeží, pokiaľ bude self._is_running rovné True a pre každý priechod slučkou načíta zoznam vygenerovaných eventov. Ak jeden z nich bude pygame.QUIT, potom zavolá self.end() a zatvorí pygame:

class Game:
    def __init__(self):
        self._running = True
        pygame.init()

    def end(self):
        self._running = False

    def run(self) -> None:
        while self._running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.end()
        pygame.quit()

Ak by sme si teraz vytvorili inštanciu Game a zavolali na nej metódu run(), dôjdeme k zaujímavému záveru: nič sa nestane:-) To preto, že knižnica pygame sa iba úspešne zinicializovala a nič iné podľa programu robiť nemala. Aby sme sa však uistili, že všetko robíme správne, vytvoríme si ešte okno, ktoré na nás po začiatku hry vyskočí. Do konštruktora triedy Game pridáme teda self.display: pygame.Surface = pygame.display.set_mode((600, 600)) a do našej slučky pod for cyklus pridáme pygame.display.flip(). Celý program teda momentálne vyzerá takto:

import pygame

class Game:
    def __init__(self):
        self._running = True
        pygame.init()
        self.display: pygame.Surface = pygame.display.set_mode((600, 600))

    def end(self):
        self._running = False

    def run(self) -> None:
        while self._running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.end()
            pygame.display.flip()
        pygame.quit()

game = Game()
game.run()

Tento program po spustení vytvorí čierne okno, ktoré budeme môcť zavrieť. Nabudúce sa v tvorbe našej hry zase posunieme o kus ďalej. Zdrojový kód vrátane adresárovej štruktúry Skákačky nájdete na konci lekcie.

V ďalšej lekcii Skákačka v Pygame - Logging zistíme, ako si udržať prehľad o priebehu projektu našej Skákačky pomocou knižnice logging.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 11x (4.7 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python

 

Predchádzajúci článok
Pygame - Pong - Logika stavov hry a dokončenie
Všetky články v sekcii
Pygame
Preskočiť článok
(neodporúčame)
Skákačka v Pygame - Logging
Článok pre vás napísala Lucie Flídrová
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje pygame a pythonu obecně.
Aktivity