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

Eriugena: Návrat domov

Táto Krátka point-and-click adventúra príbehovo líči neľahký návrat filozofa Jána Scota Eriugeny do jeho rodného Írska. Hra je urobená v C# (s frameworkom MonoGame).

Úvod

V tejto prvej časti článku predstavím hru Eriugena s podtitulom Návrat domov.

Námet a dej

Ohľadne námetu som sa nechal (veľmi voľne) inšpirovať klasickou knihou od Umberta Eca Meno ruže. Výsledkom je hra situovaná do kláštora (a čiastočne jeho okolie), v ktorej bude nejaké tajomstvo, popr. aj vyšetrovanie vraždy.

Zvolil som postavu filozofa z karolínskej renesancie, mne osobne sympatickú pre svoju unikátnu syntézu novoplatonizmu s teológiou, a to síce Jána Scota Eriugenu. Ten bol podľa niektorých historikov vo Franskej ríši ubodaný mníchmi, čo som pre potreby zmenil na pobodaný. Na to som nadviazal príbehom jeho návratu do rodného Írska. Nakoniec sa celý dej zvrtol až skoro k fantasy, ale koniec koncov som ho vymýšľal až za pochodu a nebol v tomto prípade prioritou. Tou bolo vyskúšať si vývoj adventúry.

Žáner adventúry

Hra vznikala necelé štyri dni. Ten prvý som viac-menej len vytváral rôzne miestnosti. Do miestností som potom vložil hlavnú postavu a umožnil ju medzi nimi prechádzať. Najprv, bez animácie pohybu. Vyzeralo to, ako by Eriugena jazdil po kláštore na neviditeľnom segwayi. Až potom som začal premýšľať, ako z toho urobiť point-and-click adventúru (ktoré boli tak populárne v 90. rokoch, s titulmi ako Kyrandia či [s RPG prvkami] Quest for Glory).

Vymýšľanie miestností

Miestností som vymyslel 25 (teda s indexmi 0-24). Väčšina z miestností vychádzala zo základného layoutu drevenej podlahy a kamenného múru. Len štyri vonkajšie "miestnosti" majú ako základ trávu.

Tu je pôvodný plánik. Obsahuje aj informácie, v ktorých miestnostiach sa môže vyskytovať ktorá nehráčska postava (NPC) av ktorých miestnostiach budú aké predmety (plus rozmery týchto predmetov):

Plánok - Zdrojákoviště C # .NET - XNA a MonoGame

Jazyk, framework a písanie kódu

Jazyk kódu je C# a je použitý framework MonoGame. Na kóde je vidieť, že som si koncept adventúry ešte len ohmatával za chodu. Preto by mohol byť miestami vyladenejšie a elegantnejšie.

Rád by som upozornil na jednu zásadu objektového programovania, a to síce zapuzdrenie (preto by si z tohto nikto nemal brať príklad...). Ide o miesta, kde som napr. potreboval inštanciu predmetu zmeniť stav atribútov JeVeSvete či JeVInventari.
Správnym postupom by bolo v triede Predmety urobiť metódu, ktorá by stav zmenila. Z dôvodu jednoduchosti som však namiesto toho zmenil prístupnosť prepísaním private set; na obyčajný set; pri príslušných atribútoch. Pri takto malom projekte si nemyslím, že by tým mohol vzniknúť problém, ale treba si aj tu pripomenúť, že to nie je správny návyk.

Ďalšia vec, ktorá by sa v kóde dala upraviť (a na ktorú, ak budem zase robiť adventúru, budem nabudúce myslieť), vyplýva zo zásady pomenovanej po ďalšom stredovekom mníchovi av IT veľmi dôležité, tj z Ockhamovej britvy. Inak povedané, niektoré časti kódu mám zrejme zbytočne duplicitné a bolo by možné ich riešiť metódou. Rovnako by išiel zoškrtať počet premenných.

Eriugena s opátom - Zdrojákoviště C # .NET - XNA a MonoGame

Logická stránka hry

V tejto kapitole a jej podkapitolách sa zameriam na to, čo prebieha vo frameworku MonoGame pri fáze Update(), tj na vnútornú logiku hry. Teda na všetky zmeny stavov, v ktorých sa môže nachádzať.

Vstup klávesnicou

Ako prvý som vytvoril vstup cez klávesnicu. Najprv to boli len šípky doprava a doľava, ktoré umožňovali chodiť vpravo a vľavo. K tomu som pridal zmenu miestnosti pri zaistení príliš vľavo alebo príliš vpravo na danej obrazovke.

Výnimkou je miestnosť 24, teda mistnost-lesni-kriz.xnb, kde sa už ďalej vpravo ísť nedá.

Podobne mala pôvodne fungovať miestnosť 0 ("Študovňa na konci chodby"), ale tam som nakoniec pridal schody, ktoré vedú do miestnosti 16 mistnost-schody.xnb, pretože chodenie zľava doprava a späť sa ukázalo byť pomerne úmorným. Aj preto som cez kláves R (ako " R ýchlosť") pridal možnosť meniť rýchlosť, a tým počet obrazových bodov, ktoré Eriugena prejde daným smerom, ak má aktuálne nastavený pohyb cez klávesnicu či myš.

Rýchlosťou je celý rad a tá najpomalšia je zamýšľaná skôr ako vtip (keby však niekto v nej dohral celú hru, hoci príbehovo nie až takú dlhú, navrhoval by som mu ako životnú možnosť stať sa tibetským budhistickým lámou, lebo by predviedol naozaj neobyčajnú mieru trpez. ).
Klávesa Medzerník potom slúžila predovšetkým na zobrazenie aktuálneho príbehu (akéhosi denníčka postavy, resp. jej vnútornej reči).

Stlačenie kláves

Samozrejme pri klávesách R i Medzerník bolo potrebné ošetriť, aby jedno stlačenie nebolo vyhodnotené viackrát, pretože jeden cyklus v MonoGame trvá tridsať sekundy. Miesto prsta by teda musel hráč mať útočiacu kobru, aby stihol kláves stlačiť naozaj len raz.

Ponúka sa možnosť pamätať si posledný kláves, čím je docielené to, že sa žiadna klávesa nevyhodnotí dvakrát po sebe. To ale neprichádza do úvahy vtedy, keď chceme, aby bolo možné kláves stlačiť dvakrát po sebe.

Vtedy som ako najjednoduchšie riešenie zistil urobiť premennú, ktorá musí byť na nule, aby bolo možné kláves vyhodnotiť ako stlačený. Pri každom stlačení sa pritom nastaví premenná napríklad na tridsať. Od nenulovej premennej sa potom v každom cykle odpočíta jedna.

Tým sme vytvorili obmedzenie na jeden kláves za jednu sekundu.

Pohyb a jeho obmedzenie

Postavička sa samozrejme nemôže pohybovať všade. Preto sa pri pohybe vždy vyhodnocuje, či nenarazila na vertikálne mantinely (príp. aj horizontálne, tie však väčšinou znamenajú zmenu miestnosti). Pokročilejším riešením by bolo namapovať podlahu v každej miestnosti zvlášť, uľahčil som si však prácu tým, že sú mantinely všade rovnaké.

Vertikálny pohyb má funkciu čisto estetickú, resp. dodáva hráčovi väčší pocit slobody. Inak žiadnemu účelu v hre neslúži.

Vstup myšou

Asi ťažko by išlo o hru typu point-and-click bez myši. Preto som pridal vstup cez myš. Základná myšlienka chodenia myšou je tá, že po kliknutí sa vytvorí akýsi cieľ chôdze na zadaných súradniciach a Eriugena pôjde k tomuto cieľu, kým ho nedosiahne.

Pohyb k cieľu

Prvým problémom bol diagonálny pohyb, kedy by napr. pribúdalo/odčítalo sa na osiach X i Y zároveň. Aby bol rovnomerný, musela by sa de facto vypočítať prepona pravouhlého trojuholníka. Preto som dal dva kroky. Eriugena najprv "splní" chôdzu:
  • na osi X,
  • až potom na osi Y.

Príchod do cieľa

Ďalší problém sa týkal presného príchodu do cieľa. Ten mal dva podproblémy:
  • cieľ sa nevymedzuje presne v mieste kliknutia. To je totiž miesto, kam chceme, aby postavička došla svojimi nohami. Súradnice postavičky (a jej 2D spritu) sú ale dané ľavým horným krajom obrázku. Musíme teda prinajmenšom pripočítať na osi Y jej výšku.
  • pri rýchlosti vyššej ako 1 pixel/cyklus častokrát nedôjdeme do kliknutého bodu presne. Postavička ho bude neustále prechádzať z jednej či druhej strany, ako bude program neustále vyhodnocovať, že v cieli ešte nie sme. Preto musíme dať istú toleranciu, napr. 20 bodov. A nezabúdať pritom zase, že vyhodnocujeme miesto, kam dôjde postavička svojimi nohami.

Takto nastavíme cieľ chôdze:

Mys_Cil_X = Ovladani_Mysi.X;
Mys_Cil_Y = Ovladani_Mysi.Y - 350;

A takto, či sme do neho došli:

if (((Mys_Cil_X + 20) > Eriugena_PoziceX && (Mys_Cil_X - 20) < Eriugena_PoziceX)
       && ((Mys_Cil_Y + 20) > Eriugena_PoziceY && (Mys_Cil_Y - 20) < Eriugena_PoziceY))
Eriugena v skriptóriu - Zdrojákoviště C # .NET - XNA a MonoGame

Klikanie na NPC a predmety

Pri kliknutí myšou na NPC sa spustím režim dialógu (podobný režimu príbehu), objaví sa textúra pergamenu a príslušný text. Pri kliknutí na predmet umiestnený v danej miestnosti (na daných súradniciach) sa mu atribút JeVeSvete zmení na false a atribút JeVInventari na true. Pre hru to znamená, že ho prestane vykresľovať vo svete a začne v inventári. A ďalej ho môžeme použiť v rámci deja (pri čom sa môže aj "spotrebovať", teda obaja pred chvíľou spomínané atribúty potom budú false).

Ak sme klikli napr. na predmet sa vyhodnocuje nasledovne:

foreach (Predmety i in Predmety_List)
{
    if (i.Mistnost == Eriugena_Mistnost
         && Ovladani_Mysi.X > i.PoziceX && Ovladani_Mysi.X < (i.PoziceX + i.Sirka)
          && Ovladani_Mysi.Y > i.PoziceY && Ovladani_Mysi.Y < (i.PoziceY + i.Vyska))
    {
        i.JeVeSvete = false;
        i.JeVInventari = true;
    }
}

Mimochodom, práve tu vidíme porušenie zásady zapuzdrenia. Správne sa mali atribúty meniť metódou v triede, napr.: i.Seber(), ktorá by potom vo vnútri triedy Predmety menila hodnoty oných dvoch atribútov. Viedla ma k tomu pohodlnosť, ktorá sa pri takom malom projekte najskôr nevymstí. Je dobré si to však pripomínať.

Nie všetky predmety sú hneď na začiatku ukázané v miestnostiach. Niektoré sa objavia až v priebehu hry, aby nebolo možné ich vyzbierať hneď na začiatku. Keby sa to tak robilo s každým predmetom, stratila by sa možnosť si len tak sysliť niečo do inventára.

Postup v príbehu

Postup v príbehu riešim cez fázy. Tá je jednoducho vyjadrená číslom typu int, ktoré si potom vyhodnotím pomocou konštrukcie switch. Keby som chcel dať fázam mena, ponúkal by sa aj enum, ale takto to bolo jednoduchšie.

Pri väčšom projekte by naopak bolo dobré priamo z názvu vidieť, čo sa pod tým ukrýva. Pri číslach by si človek musel viesť akýsi katalóg).

Fáza

Použil som fázy dvojakého typu. Fáza príbehu a fáza postavy.
Fáza príbehu
Fáza príbehu reprezentuje najmä vnútorný monológ Eriugeny, ktorý si môžeme vyvolať klávesom Medzerník. Je to vlastne taký quest log, resp. pripomenutie, čo má hráč vlastne robiť.
Fáza postavy
Postavy majú svoje jednotlivé fázy. Keď teda napr. porozprávam s jednou postavou, môže to posunúť fázu dialógu pri inej postave. Niekedy si postava svoju fázu posunie aj sama (napríklad, keď po nás chce predmet, ktorý už ale máme v inventári). V takom prípade je text posúvajúci fáza de facto preskočený (na čo treba myslieť pri písaní textov, aby sa hráč v rozprávaní nestratil).
Dialóg v hre - Zdrojákoviště C # .NET - XNA a MonoGame

Vizuálna stránka hry

Tu popíšem to, čo sa v závislosti na logike hry objavuje na obrazovke, teda obsah metódy Draw().

Falošný pixel-art

Dnes vzniká mnoho hier a mnoho z nich je nesmierne graficky podmanivých. Napriek tomu sa domnievam, že isté vizuálne kúzlo, ktoré mali ručne maľované hry z napr. 90. rokov, sa už nevrátia (česť výnimkám, napr. Heroine's Quest). Snáď práve preto, že boli ručne maľované. A možno aj preto, že nepresnosť daná menším rozlíšením viac podnecovala fantáziu hráča. A tiež preto, že sme vtedy mnohí z nás boli mladší a nostalgia nasadzuje všetkému ružové okuliare... Ale to je iný príbeh.

Podstatné je, že ja nie som práve výtvarník, ani som k tomu žiadneho nemal (nehľadiac na to, že som hru chcel urobiť rýchlo). Preto som urobil akýsi falošný pixel-art tým, že som jednoducho skombinoval, upravil a rozpixeloval obrázky z netu. Do určitej miery som sa tým vyhol aj právnej stránke (napriek tomu som sa snažil, ak bola tá možnosť, aby boli s licenciou Creative Commons).

Trochu bizarné samozrejme je, že rôzne prvky, ktoré sú naraz na obrazovke, majú rôzne rozlíšenie. Takúto možnosť samozrejme hry v 90. rokoch nemali. Musel som k tomu však siahnuť, pretože keby napr. niektoré postavy alebo malé predmety mali rozlíšenie ako napríklad steny za nimi, nebolo by prakticky nič rozpoznať. To isté platí napr. o niektorých nápisoch. Občas som pridal akýsi "svetelný" efekt, ktorý spočíva v zásade len v maske výberu, v ktorej sú ľahko pozmenené farby.

Vykreslenie pozadia, postáv a vecí

Pri vykreslení pozadia, postáv, vecí a Eriugeny nie je príliš veľa čo rozoberať. Vykresľovali sa v tom poradí, aké je uvedené pred chvíľou, aby boli v správnych vrstvách. Napr. Eriugena je vždy pred NPC, NPC sú vždy pred pozadím a pod. Úplne navrchu sú potom samozrejme elementy UI: tj popisky, inventár, príbehový pergamen a pod.
Eriugena so smädným mníchom - Zdrojákoviště C # .NET - XNA a MonoGame

Natočenie a prešľapovanie Eriugeny

Zatiaľ čo na ostatné NPC stačí vždy jeden sprite (síce sa premiestňujú medzi svojimi miestnosťami, ale len v neprítomnosti Eriugeny, inak stoja na mieste), tak na hlavnú postavu ich je užitých rovno šesť:
  1. Státie rovno
  2. Došliapnutie na ľavú nohu
  3. Došliapnutie na pravú nohu

To celé dvakrát s ohľadom na varianty natočenia vľavo/vpravo.

Tri varianty sa v rámci jedného natočenia striedajú pri chôdzi. To vyvoláva síce trochu dojem tučniaka, pôsobí to ale o niečo menej strnulo ako vyššie už spomínaný neviditeľný segway.

Ďalej, pre oživenie postavy, som pridal metódy, ktoré otáčajú Eriugenou na strany a nútia ho prešľapovať v náhodných intervaloch aj vtedy, keď sa práve nehýbe. Je to jednoducho zvedavý neposedník:-) .

Popisky v používateľskom rozhraní

Na hernej obrazovke je aj niekoľko popisov. Tie jediné nie sú rozpixelované, ale ide o normálne vykreslenie fontu pomocou _spriteBatch.DrawString(). Bol to ústupok tomu, aby sa dali dobre čítať a rovnako to takto bolo jednoduchšie. Inak by každý jediný riadok textu v hre musel byť obrázkom.

Každá postava má zadanú v hre svoju farbu na rozlíšenie v dialógoch. Rozprávač má farbu Color.Silver a herné tipy cez rôzne iné farby. Farby UI sa menia v závislosti na tom, či je hráč v režime chodenia, alebo príbehu.

Eriugena v temnom lese - Zdrojákoviště C # .NET - XNA a MonoGame

Záver

Pre dokreslenie atmosféry som použil v hre jednu royalty free skladbu z YouTube. V tejto hre som si žáner adventúry skôr len ohmatával a možno v budúcnosti ešte niečo také vytvorím.

Prikladám na stiahnutie release zložky aj s EXE súborom, tu sú potom odkazy na kompletné zdrojové kódy:


Galéria


 

Stiahnuť

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

Stiahnuté 6x (52.29 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Všetky články v sekcii
Zdrojákoviště C # .NET - XNA a MonoGame
Článok pre vás napísal Jakub Raida
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor má rád literaturu, dějiny, filmy, počítačové hry, paleontologii, vesmír a programování.
Aktivity