Programování pro hračičky/Andělé/Lekce 3: Porovnání verzí

m
Robot: Náhrada zastaralého tagu
m (aktualizace ročníku)
m (Robot: Náhrada zastaralého tagu)
Protože Prahy se odehrávají v češtině, budeme při vytváření objektů muset dbát též na správné skloňování jejich jmen. K tomu potřebujeme někde v úvodu souboru mít vloženu řádku:
 
<sourcesyntaxhighlight lang="c" >
#include <sklon.h>
</syntaxhighlight>
</source>
 
Pokud jsme dotyčnou místnost vytvořili okopírováním <code>workroom.c</code> a následným předěláním, pak takovou řádku nejspíše někde na začátku souboru už máme. Pokud ne, tak ji vložíme buď na úplný začátek, nebo za rovněž někde na začátku se nacházející řádky, které začínají slovem nebo obsahují slovo <code>inherit</code> (o těch budeme také podrobně mluvit až později).
Do těla funkce <code>create()</code>, která se automaticky spouští při vytvoření objektu (v případě jednotlivé místnosti při jejím načtení do paměti), vložíme nyní volání funkce <code>add_v_item()</code>, jejímž jediným parametrem bude asociativní pole popisující virtuální objekt. Za vzor si můžeme vzít třeba poháry z Horepovy krčmy:
 
<sourcesyntaxhighlight lang="c" >
void create()
{
...
}
</syntaxhighlight>
</source>
 
Identifikátory psané velkými písmeny jsou konstanty definované v souboru <code>/sys/sklon.h</code>, který jsme načetli oním řádkem <code>#include <sklon.h></code>. Jsou to vlastně interní čísla různých rodů, čísel a vzorů, ale protože s čísly by se pracovalo podstatně hůř, jsou takto nahrazena aspoň přibližně zapamatovatelnými slovy. <code>ROD_F</code>, <code>ROD_MA</code>, <code>ROD_MI</code>, <code>ROD_N</code> znamenají po řadě rod ženský, mužský životný, mužský neživotný a střední, <code>CISLO_J</code>, <code>CISLO_MN</code>, <code>CISLO_POMN</code>, <code>CISLO_HROM</code> číslo jednotné, číslo množné, jméno pomnožné a jméno hromadné, identifikátory začínající na <code>VZOR_</code> znamenají jednotlivé skloňovací vzory. Protože skloňovacích vzorů je v češtině ve skutečnosti mnohem více, než se běžně učí ve škole (například slova „hrad“, „stan“ a „padák“ se všechna řadí ke školskému vzoru „hrad“, ale při skloňování se v některých pádech liší), budeme se muset občas kouknout buď do souboru <code>/sys/sklon.h</code> (jde to například ze hry andělským příkazem <code>more /sys/sklon.h</code>), nebo si postupně zapamatovat možné vzory při zacházení s již hotovými virtuálními objekty.
Jednotlivé položky asociativního pole pak nastavují jednotlivé vlastnosti virtuálního objektu. Poměrně jasný nám je asi význam položek <code>"long"</code> a <code>"smell"</code> (obdobně bychom mohli definovat ještě položky <code>"noise"</code>, <code>"feel"</code> a řadu dalších, které najdeme popsány v Podprahové encyklopedii v sekci Jak to funguje, podsekci Virtuální detaily). Položka <code>"name"</code> definuje, pod jakým hlavním jménem bude objekt vystupovat, tedy pod jakým se bude třeba objevovat v hláškách typu „Michael si prohlíží poháry.“ (jméno píšeme malými písmeny, případné velké písmeno u jmen vlastních řešíme jinak), <code>"gender"</code>, <code>"plural"</code> a <code>"vzor"</code> udávají, jak se bude toto jméno skloňovat. Mohli bychom definovat ještě <code>"adjektiv"</code> pro přívlastek shodný a <code>"attribut"</code> pro přívlastek neshodný:
 
<sourcesyntaxhighlight lang="c" >
"adjektiv":({"použitý","skleněný"}),
"attribut":"na pultě",
</syntaxhighlight>
</source>
 
Takové nastavení by pak způsobilo, že výše uvedená hláška by měla podobu „Michael si prohlíží použité skleněné poháry na pultě.“
V programu místnosti nyní provedeme několik úprav. Především někde v úvodu souboru (ale až za různá <code>inherit</code> a <code>#include</code>) deklarujeme proměnnou typu objekt, která bude odkazovat na vytvářený objekt. Tuto proměnnou bychom mohli nazvat klidně <code>Franta</code> nebo <code>x3356762</code>, ale je dobrým zvykem nazývat věci tak, aby byly podle názvu rozpoznatelné, tedy ji nazvěme třeba <code>batoh</code>:
 
<sourcesyntaxhighlight lang="c" >
object batoh;
</syntaxhighlight>
</source>
 
Od této řádky dále pak můžeme v programu místnosti používat proměnnou <code>batoh</code> a ukládat do ní odkazy na objekty.
Jako další úpravu vložíme do programu místnosti novou funkci <code>reset()</code>. Funkce tohoto jména se u objektů, které se právě nacházejí ve hře, volá automaticky přibližně jednou za 40 minut, a slouží k tomu, aby se tyto objekty mohly vždy znovu uvést do nějakého kýženého základního stavu. Základním stavem naší místnosti ovšem bude, aby obsahovala batoh, a proto, pokud objekt <code>batoh</code> neexistuje nebo už není v místnosti přítomen, naklonujeme nový batoh z <code>/obj/batoh.c</code> a přemístíme ho do této místnosti:
 
<sourcesyntaxhighlight lang="c" >
void reset()
{
}
}
</syntaxhighlight>
</source>
 
Tato funkce <code>reset()</code> se musí nacházet ''za'' deklarací proměnné <code>batoh</code> (protože v ní tuto proměnnou používáme) a ''před'' funkcí <code>create()</code>.
Jako třetí a poslední úpravu nyní do funkce <code>create()</code> přidáme zavolání funkce <code>reset()</code>, aby se náš batoh vytvořil hned při vytvoření místnosti:
 
<sourcesyntaxhighlight lang="c" >
void create()
{
reset();
}
</syntaxhighlight>
</source>
 
Velmi často se samozřejmě stává, že bychom rádi vytvořili objekt, který je sice ''podobný'' nějakému předpřipravenému objektu (tedy, jinak řečeno, je téže třídy), ale některé vlastnosti má mít jiné. Pak musíme vlastnosti objektu po naklonování ještě změnit funkcemi, jejichž použití snadno pochopíme z toho, co už známe z vytváření místností a virtuálních objektů:
 
<sourcesyntaxhighlight lang="c" >
void reset()
{
}
}
</syntaxhighlight>
</source>
 
Někde v úvodu programu pak samozřejmě budeme muset načíst definice gramatických kategorií a deklarovat proměnnou <code>stud</code>:
 
<sourcesyntaxhighlight lang="c" >
#include <sklon.h>
 
object stud;
</syntaxhighlight>
</source>
 
Za upozornění zde ještě stojí funkce <code>set_id()</code>, která nastavuje nejen vedlejší identifikátory, ale také jejich skloňovací vzory a mluvnická čísla. Zatímco u virtuálního objektu jsme na to potřebovali tři různé položky, nyní můžeme místo položek použít funkci, kterážto může mít i více parametrů — a v případě funkce <code>set_id()</code> jsou parametry právě ona tři pole, která jsme u virtuálního objektu museli uvést zvlášť.
Na začátek souboru napišme do programátorských komentářů, oč se v souboru bude jednat (ani my sami to možná nebudeme za nějaký čas vědět přesně):
 
<sourcesyntaxhighlight lang="c" >
// Salátův bublátor: když se do něj kopne, vypouští bublinky
</syntaxhighlight>
</source>
 
Popis můžeme případně (časem) rozšířit o další smysluplné informace (pro ukázku nyní použijeme druhý typ zápisu komentářů):
 
<sourcesyntaxhighlight lang="c" >
/* proměnné:
bubcount ... kolik bublinek se vypustí na jedno kopnutí
TODO: nastavení barvy bublinek
*/
</syntaxhighlight>
</source>
 
Nyní využijeme již hotových tříd, jejichž programy nalezneme ve složce <code>i</code> a jejích podsložkách, abychom nemuseli všechno programovat sami. Pokud má být bublátor krom bublání (ježto budeme muset určitě sami naprogramovat) obyčejným předmětem, který se dá též přemisťovat a případně i prodat, napíšeme na následující řádky:
 
<sourcesyntaxhighlight lang="c" >
inherit "/i/item";
inherit "/i/move";
inherit "/i/value";
</syntaxhighlight>
</source>
 
Pokud bychom se rozhodli, že bublátor má být zároveň použitelný jako zbraň pro boj zblízka, pak využijeme příslušné třídy (která již dědí všechny tři výše zmíněné a má nějaké ty metody a vlastnosti navíc) a místo těchto tří řádků napíšeme:
 
<sourcesyntaxhighlight lang="c" >
inherit "/i/weapon/zblizka";
</syntaxhighlight>
</source>
 
Poté, co jsme takto deklarovali, od kterých tříd bude náš objekt dědit vlastnosti a metody, načteme si definice konstant, které budeme využívat. Budou to přinejmenším konstanty označující nám již známé gramatické kategorie (neukončuje se středníkem, protože to vlastně není příkaz LPC, nýbrž [[w:Preprocesor|preprocesoru]], o kterém si něco více povíme později):
 
<sourcesyntaxhighlight lang="c" >
#include <sklon.h>
</syntaxhighlight>
</source>
 
Nyní již můžeme dát svému objektu počáteční tvar, tedy definovat základní funkci ([[w:Konstruktor|konstruktor]]) <code>create()</code> a v ní pomocí nám již známých funkcí nastavit vlastnosti:
 
<sourcesyntaxhighlight lang="c" >
void create()
{
...
}
</syntaxhighlight>
</source>
 
V případě, že by bublátor dědil <code>/i/weapon/zblizka</code> nebo další programové moduly, které už obsahují funkci <code>create()</code>, je potřeba v naší funkci <code>create()</code> spustit též toto zděděné <code>create()</code>, aby se provedla nutná nastavení. Pokud objekt dědí jen jednu třídu, pak stačí napsat:
 
<sourcesyntaxhighlight lang="c" >
void create()
{
...
}
</syntaxhighlight>
</source>
 
Pokud objekt dědí více tříd, pak můžeme zavolat všechna v nich definovaná <code>create()</code> zápisem:
 
<sourcesyntaxhighlight lang="c" >
void create()
{
...
}
</syntaxhighlight>
</source>
 
Volání děděných funkcí je možno specifikovat i podrobněji, ale to si podrobně probereme až v jedné z příštích lekcí.
1 121

editací