Hlavní navigace

Knihovna ClanLib (7)

Petr Kavánek 21. 6. 2004

Dnes navážeme na minulý díl a dokončíme popis třídy CL_Sprite, která je mocným nástrojem při vytváření 2D animací. Zaměříme se podrobně na její vytváření z RDF.

Obecný popis spritu v RDF

<sprite
  name="jmeno_spritu"
  description="jmeno_jineho_spritu"
  pack_texture="[yes, no]"

  <!-- Popis nahravani obrazku pro jednotlive snimky -->

  <image file="cesta_k_souboru_s_obrazkem" />

  <image file="cesta_k_souboru_s_obrazkem">
    <grid
      pos="x, y"
      size="sirka, vyska"
      array="tiles_x, tiles_y"
      spacing="sirka, vyska" />
  </image>

  <image file="cesta_k_souboru_s_obrazkem">
    <palette
      pos="x, y" />
  </image>

  <image file="cesta_k_souboru_s_obrazkem">
    <alpha
      pos="x, y"
      free="true"
      trans_limit="limit" />
  </image>

  <!-- Nastaveni rendrovani a animovani -->

  <color
    red="cervena_slozka"
    green="zelena_slozka"
    blue="modra_slozka"
    alpha="pruhlednost" />

  <animation
    speed="rychlost"
    loop="[yes, no]"
    pingpong="[yes, no]"
    direction="[backward, forward]
    on_finish="[blank, last_frame, first_frame]" />

  <scale x="horizontalni_meritko" y="vertikalni_meritko" />

  <translation
    origin="[top_left, top_center, top_right, center_left,center,
    center_right, bottom_left, bottom_center, bottom_right]"
    x="offset_x"
    y="offset_y" />

  <rotation
    origin="[top_left, top_center, top_right, center_left, center,
    center_right, bottom_left, bottom_center, bottom_right]"
    x="offset_x"
    y="offset_y" />

  <frame
    nr="cislo_snimku"
    speed="zpozdeni_snimku"
    x="offset_x"
    y="offset_y" />

</sprite> 

Všechny tyto vlastnosti spritu je možné nadefinovat přímo v RDF. Pojďme se tedy s nimi postupně seznámit.

Nejprve sprite pojmenujeme pomocí atributu name, jak jsme na to již zvyklí.

Dalším důležitým krokem je zadat nejakým způsobem snímky, ze kterých se bude sprite skládat, což je možné udělat několika následujícími způsoby.

Je možné prostě zadat cestu k souboru s obrázkem v nějakém z podporovaných formátů jako v následujícím příkladu. Celý obrázek je pak považován za jeden snímek.

<image file="cesta_k_souboru_s_obrazkem" />

Další možností je, že všechny snímky umístíme do dvojrozměrné mřízky v jediném obrázku, tj. všechny snímky máme v jednom souboru. Tuto mřížku pak popíšeme v RDF, jak naznačuje další příklad. Příslušná instance CL_Sprite si pak dokáže mřížku rozsekat na jednotlivé snímky.

<image file="cesta_k_souboru_s_obrazkem">
  <grid
    pos="x, y"
    size="sirka, vyska"
    array="tiles_x, tiles_y"
    spacing="mezera_x, mezera_y" />

</image>

Zde pos označuje levý horní roh mřížky, size rozměry políček v mřížce, array udává počet sloupců a řádků mřížky a konečně spacing udává mezeru mezi jednotlivými políčky. Pokud se chcete podívat na konkrétní příklad využití této techniky, můžete nahlédnout do příkladového programu Packman umístěného v adresáři Examples vaší knihovny ClanLib.

Podobně je třída CL_Sprite schopná rozsekat si jednotlivé snímky z obrázku, v němž jsou tyto odděleny nějakou barvou. Příklad naleznete opět v Packmanovi. Přiznám se však, že si nejsem úplně jistý, jestli jsem dobře pochopil princip. Nejspíš je to tak, že jako pos udáme opět souřadnice levého horního rohu prohledávané plochy a barvu tcol, kterou jsou snímky odděleny.

<image file="cesta_k_souboru_s_obrazkem">
  <palette
     pos="x, y"
     tcol="barva"/>
</image>

Posledním z možných způsobů je oddělování snímků průhledností. Princip by měl být podobný. Atribut free je přepínačem mezi dvěma možnými algoritmy, které jsem však také nikde nenašel dostatečně zdokumentované. Pokud tedy budete tuto možnost potřebovat, doporučuji vám udělat si několik experimentů.

<image file="cesta_k_souboru_s_obrazkem">
  <alpha
    pos="x, y"
    free="true"
    trans_limit="limit" />
</image>

Všechny uvedené postupy je možné kombinovat.

Nyní, když nadefinujeme, ze kterých snímků se bude náš sprite skládat, může se nám stát, že i jiný sprite bude těmito snímky začínat. Pokud nebudeme chtít vše znova přepisovat, stačí zadat pouze jméno tohoto řekněme rodičovského spritu v atributu description. Pokud je rodičovský sprite součástí nějaké sekce, je třeba uvést celou cestu, tj. jméno_sekce/jmé­no_spritu. Mně by se dosud vždy mnohem více hodilo „dědění“ vlastností než dědění snímků, ale pro to jsem podporu dosud nenašel.

Pokud u atributu pack_texture zadáme yes, bude se CL_Sprite snažit uložit co nejvíce snímků jako jednu texturu.

Tag <color> nám umožňuje nastavit barevnost spritu, tj. jak mají být zastoupeny jednotlivé tři složky barevného spektra a průhlednost. Hodnoty se musí pohybovat mezi 0.0 a 1.0. Implicitně jsou všechny hodnoty 1.0.

Velmi užitečný je tag <animation> a jeho atributy.

Speed udává, jak dlouho mají být promítány jednotlivé snímky.

Loop říká, zda má promítání probíhat v nekonečné smyčce.

Pingpong zase udává, zda má být použit „ping-pong“ mód, jak jsem si ho popsali v minulém dílu.

Direction nastavuje směr přehrávání.

On_finish udává, co se stane na konci přehrávání. Možnosti opět odpovídají tomu, co jsme si řekli minule.

Pomocí tagu <translation> nastavujeme posunutí snímku, tj. bod, který se má vykreslit na souřadnice předané metodě draw(). Můžeme nastavit jednu z předdefinovaných hodnot v atributu origin, nebo nastavit konkrétní bod atributy x, y. Je možné obojí zkombinovat. To znamená, že x, y udávají posun vzhledem ke zvolenému origin (bodu, kterým je implicitně levý horní roh).

Obdobně je možné nestavit i střed rotace pomocí tagu <rotation>.

Konečně tagy <frame> slouží k přesnému nastavení doby promítání pro jednotlivé snímky. Snímek je identifikován svým pořadovým číslem nr a rychlost nastavuje atribut speed. Je dokonce možné zde nastavit i posunutí pro jednotlivé snímky vzhledem k ostatním snímkům atributy x, y.

Závěrem

Tím jsme dokončili takovou teoretickou část věnovanou spritům, a jelikož jsem opět popsal poměrně mnoho řádků, nebudu se již pouštět do ničeho dalšího.

Mám již napsaná některá rozšíření naší hry demonstrující použití spritů, avšak nejsou ještě zcela podle mých představ, a proto si je necháme až na příště, kdy si povíme, jak vytvořit sprite resp. jeho snímky tak, aby se vykresloval pouze samotný obrázek, nikoliv však jeho pozadí.

Příště také doufám začneme se zpracováním událostí vyvolaných klávesnicí a myší.

Nakonec bych se ještě rád pokusil o jakýsi průzkum mezi vámi čtenáři a zeptal se vás, nakolik vám pomáhají rozsáhlejší příklady, se kterými jste se mohli setkat zejména v minulých dílech? Rád bych také zjistil, jestli si někdo stahujete přikládané KDevelopí projekty a díváte se přímo do zdrojáků, nebo zda vám spíše vyhovuje jeden PDF soubor, v němž jsou všechny zdrojáky k nahlédnutí. Také mě napadlo, že bych mohl na konci každého článku zadat nějaký příklad k procvičení a v příštím článku zveřejnit nějaké vzorové řešení. Budu rád za každý podnět, na jehož základě bych byl schopen zvýšit úroveň těchto článků tak, aby byly co nejvíc prospěšné vám čtenářům, a případně bych si rád ušetřil zbytečnou práci s věcmi, které by nikdo nevyužil. Za vaše reakce předem děkuji.

Našli jste v článku chybu?

22. 6. 2004 22:32

Petr Kavanek (neregistrovaný)

O puhlednosti v CL_Sprite bude pulka pristiho clanku :-). Dopredu vsak mohu rict, ze nastaveni jedne pruhledne barvy v RDF ci programu neni uplne dobre podporovane, coz jak se za tyden doctete neni omezujici, protoze maska pruhlednosti se nacita primo z obrazku, coz umoznuje i castecnou pruhlednost, nebo treba pouziti vsech barev (coz nelze, kdyz se jedna zvoli jako pruhledna).

Doporucuji tedy pristi clanek, snad se to vyjasni.



22. 6. 2004 11:39

Phoenix (neregistrovaný)

zatim sem se nedocetl ( ani v clanku, ani v dokumentaci ) jestli je nejak mozne nastavit CL_Sprite nebo CL_Surface color key (tzn. barvu, ktera se bude vykreslovat jako pruhledna), je to mozne? a je tuto barvu mozne nastavit v RDF?

Podnikatel.cz: EET zvládneme, budou horší zákony

EET zvládneme, budou horší zákony

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

DigiZone.cz: ČRo rozšiřuje DAB do Berouna

ČRo rozšiřuje DAB do Berouna

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Na poslední chvíli šokuje vyjímkami v EET

Na poslední chvíli šokuje vyjímkami v EET

Vitalia.cz: Tesco: Chudá rodina si koupí levné polské kuře

Tesco: Chudá rodina si koupí levné polské kuře

Vitalia.cz: Baletky propagují zdravotní superpostel

Baletky propagují zdravotní superpostel

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Vitalia.cz: 9 největších mýtů o mase

9 největších mýtů o mase

Podnikatel.cz: Prodává přes internet. Kdy platí zdravotko?

Prodává přes internet. Kdy platí zdravotko?

Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

DigiZone.cz: NG natáčí v Praze seriál o Einsteinovi

NG natáčí v Praze seriál o Einsteinovi

Lupa.cz: Google měl výpadek, nejel Gmail ani YouTube

Google měl výpadek, nejel Gmail ani YouTube

Podnikatel.cz: Víme první výsledky doby odezvy #EET

Víme první výsledky doby odezvy #EET

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

DigiZone.cz: ČRa DVB-T2 ověřeno: Hisense a Sencor

ČRa DVB-T2 ověřeno: Hisense a Sencor

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“