Hlavní navigace

Knihovna ClanLib (7)

21. 6. 2004
Doba čtení: 6 minut

Sdílet

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í.

CS24 tip temata

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.

Autor článku