Hlavní navigace

Knihovna ClanLib (6)

Petr Kavánek

Dnes se sezámíme s třídou CL_Sprite, která nám umožňuje pohodlně vytvářet 2D animace z nějaké sady obrázků, pracovat s průhledností, barevností a pod.

Úvodem

Spritem budeme rozumět nějakou sadu 2D obrázků (frames), promítanou postupně s určitými prodlevami mezi přechodem od jednoho snímku ke druhému.

Využití spritů je poměrně rozsáhlé. V 2D hrách podobných té, kterou píšeme, může být spritem skoro všechno – panáček, příšery, animované předměty. Příkladem spritu je ale i animovaný kursor myši nebo animace zdobící některé z oken GUI vašeho programu.

Vytvoření spritu

Existují vlastně dva rozdílné způsoby, jak můžeme CL_Sprite vytvořit. První využívá výhod RDF (úvod do RDF byl v předminulém dílu seriálu) a je dle mého názoru přesně tím, co obvykle potřebujeme. Druhý nám umožní zkonstruovat CL_Sprite přímo, tj. bez použití RDF. Tato přímá konstrukce je mnohem méně přehledná a přiznám se, že jsem ji dosud nikdy nepoužil, zmiňuji se o ní pouze pro úplnost (popis najdete například ve sprites_overvi­ew.html, které je součástí dokumentace).

Pojďme se tedy podrobněji podívat na první zmíněnou možnost. V nejjednodušší podobě může definice spritu v RDF vypadat nějak takto:

<sprite     name="Jmeno">

    <image file="cesta_k_souboru_s_obrazkem1"/>
    <image file="cesta_k_souboru_s_obrazkem2"/>

</sprite>

Sprite prostě pojmenujeme pomocí atributu name a následně vypíšeme seznam obrázků v tom pořadí, v jakém je budeme chtít přehrávat (je třeba alespoň jeden obrázek).

Předpokládejme, že máme tento popis uvedený v RDF spravovaném resource managerem, na který ukazuje SpravceZdroju (jak je tomu třeba v naší hře). Potom příslušný sprite vytvoříme v našem programu takto jednoduše:

CL_Sprite NasSprite("Jmeno", SpravceZdroju)

Tedy konstruktoru předáme jako první parametr jméno vytvářeneho spritu. Druhým parametrem pak je ukazatel na příslušný CL_ResourceManager.

Schopnosti třídy CL_Sprite

Ještě než se vrátíme k obecné definici spritu v RDF, tj. ke spoustě dalších podporovaných (volitelných) nastavení, uvedu výčet nejužitečnějších metod definovaných v CL_Sprite. Díky nim si uděláme lepší představu o tom, co všechno je možné se sprity dělat.

NasSprite.draw(X, Y);

Vykreslí NasSprite na zadané souřadnice. Jako všude v ClanLibu platí i zde, že počátek, tj. Bod 0,0, je levý horní roh a kladné hodnoty jsou vpravo na ose x a dole na ose y. Parametry jsou typu int a návratová hodnota je void, tedy žádná.

NasSprite.update();

Automaticky si spočítá, kolik času uplynulo od posledního volání této metody a nastaví snímek, který se v tomto čase má vykreslovat. Každý snímek má totiž definovanou dobu, po kterou má být zobrazován (frame delay). Tato doba může být nastavena pro každý snímek zvlášť, nebo globálně pro všechny stejná. Pokud nechceme, aby si sprite počítal čas sám, můžeme metodě update() přímo předat počet milisekund, které uplynuly (jako float).

Jak je vidět, pokud chceme, aby se sprite „hýbal“, měli bychom před každým voláním draw() volat update().

NasSprite.rota­te(Uhel);

Otočí NasSprite o zadaný úhel. Uhel je typu float, kde 0.0f je otočení o 0 stupňů a 1.0f je otočení o 360 stupňů.

NasSprite.get_an­gle();

Vrací úhel, o nějž jsme NasSprite dosud natočili.

NasSprite.set_an­gle(Uhel);

Přímo nastaví, o kolik má být NasSprite natočen.

NasSprite.set_al­pha(Pruhlednos­t);

Naství průhlednost NasSprite. Průhlednost je opět typu float. Plná průhlednost je 0.0f, nulová průhlednost odpovídá 1.0f.

NasSprite.get_al­pha();

Vrátí aktuální průhlednost jako float.

NasSprite.set_co­lor(R, G, B);

Nastaví podíl barevných složek při vykreslování obrázku v pořadí červená, zelená, modrá. Volitelně můžeme i zde nastavit průhlednost jako čtvrtý parametr. Hodnoty jsou opět typu float.

NasSprite.get_co­lor(R, G, B, A);

Nastaví do předaných proměnných příslušné hodnoty barevnosti resp. průhlednosti.

NasSprite.set_fra­me(CisloSnimku);

Způsobí, že se aktuálním snímkem stane ten, jehož číslo (id) odpovídá zadanému. Snímky jsou číslovány od nuly v pořadí, v němž jsou uvedeny v RDF.

NasSprite.get_cu­rrent_frame();

Vrátí číslo aktuálního snímku.

NasSprite.set_fra­me_delay(CisloS­nimku, DobaZobrazení);

Nastaví, jakou dobu má být zobrazován snímek zadaného čísla. Číslo snímku je int, doba zobrazení float (počet milisekund).

NasSprite.get_fra­me_delay(CisloS­nimku);

Vrátí dobu zobrazování snímku zadaného čísla.

NasSprite.finish();

Ukončí animaci.

NasSprite.is_fi­nished();

Odpoví, zda už animace skončila.

NasSprite.res­tart();

Začne animaci od začátku.

NasSprite.set_pla­y_loop(TrueNe­boFalse);

Nastaví, zda se má animace přehrávat neustále dokola (tj. po posledním snímku se zobrazí opět první).

NasSprite.is_pla­y_loop();

Odpoví, zda přehráváme dokola.

NasSprite.set_pla­y_pingpong(Tru­eNeboFalse);

Nastaví, že po přehrání posledního snímku se začneme vracet, tj. přehrajeme předposlední atd., až nakonec po prvním snímku opět změníme směr přehrávání, přehrajeme druhý snímek a tak pořát dokola.

NasSprite.is_pla­y_pingpong();

Odpoví, zda přehráváme „ping-pongově“.

NasSprite.set_pla­y_backward(Tru­eNeboFalse);

Přehrávání v opačném směru.

NasSprite.is_pa­ly_backward();

Odpoví, zda přehráváme v opačném poředí.

NasSprite.set_show_on­_finish(ShowOn­Finish);

Nastaví, co se má vykreslovat po ukončení animace. Možnými hodnotami jsou show_blank (nevykresluje se nic), show_last_frame (vykresluje se poslední snímek), show_first_frame (vykresluje se první snímek).

NasSprite.get_show_on­_finish();

Vrátí jednu ze tří výše uvedených hodnot podle toho, co se bude dít po skončení animace.

NasSprite.get_wid­th();

Vrátí šířku aktuálního snímku v pixelech.

NasSprite.get_he­ight();

Vrátí výšku aktuálního snímku v pixelech.

NasSprite.get_fra­me_surface(Cis­loSnimku);

Vrátí snímek zadaného čísla jako CL_Surface, což je typ uchovávající obrázek, se kterým jsme se již setkali.

Závěrem

Jelikož si myslím, že CL_Sprite je velice užitečná třída, rád bych se podobně věnoval i volbám a nastavením, které je možné zapsat přímo do RDF. Samotný, byť neúplný výčet metod CL_Sprite však, jak vidíte, zabral několik stránek, proto si podrobnosti o RDF necháme raději napříště. Snad zbude i čas podívat se opět i na nějaký zajímavý příklad využití nových znalostí v naší hře.

Našli jste v článku chybu?