středa 4. srpna 2004

AnimAce - díl třetí: Navštivte strojový kód

autor: George K.

Welcome to Machine Code! Možná, že je některým čtenářům líto, že jsem bezcitně opustil Basic a jistě se najdou i tací, co mi budou tvrdit, že v tom krásném jazyce by se dalo napsat daleko více, než jsem minule ukázal, ale moje letitá zkoušenost je, že animovat by se mělo ve strojáku a toho se ve zbytku seriálu budu držet. Tento díl nepřinese asi tolik konkrétních informací, jako ty předchozí, protože je třeba dohodnout se na určitých pojmech a výrazech, které budeme nadále používat a které mohou být pro někoho horkou novinkou.
Ti, kteří neovládají strojový kód, nemusejí zoufat, že jim budou následující stránky na nic - doporučuji sehnat si Universumovu knihu Assembler a ZX Spectrum - vždyť: kolik řečí znáš, tolikrát jsi člověkem...

3.1 Trochu (více) nudná teorie

Každá animace má svůj účel - většinou ji chceme využít v hrách - a na ten je třeba od samého počátku myslet. Neexistuje pravidlo, kdy jakou animaci použít - to je prostě na existenci jak postaviček tak pozadí, navíc je potřeba to všechno sladit (ne cukrem) a tady narazíme na ten největší problém: VZÁJEMNÉ PŘEKRÝVÁNÍ. Tomuto typu grafiky se říká sprajty (sprites) a využívá ho 90 % všech her. Díky náročnosti na rychlost nemůže být o Basicu ani řeč.
3.1.1 Nemaskované sprajty
Než abych složitě popisoval, co mám nemaskovaným sprajtem na mysli, bude jednodušší, když si nahrajete nějakou pěknou hru, kde na ně můžeme narazit. Jistě vám nemusím dvakrát připomínat Manic Manera; zde bylo většinou použito nemaskovaných sprajtů OR (pozadí a postavičky splývají do jednoho celku - přesvědčte se o tom).
Další bezmaskové sprajty najdete ve hrách PYJAMARAMA, ATIC ATAC, SAMANTHA (tam vlastně ne, tam jsou k vidění jiné zajímavé věci), STARQUAKE, atd; tentokrát to bude typ XOR (jako když nastavíte OVER 1 - nevypadá to moc hezky). Nesympatická na sprajtech OR a XOR je, jak se chovají k pozadí a k sobě navzájem; často není vůbec patrné, co se děje, zvláště navrství-li se několik sprajtů na sebe.
3.1.2 Zamaskované sprajty - to je ono!
Pyšní se jimi takové hry, jako je COBRA, GREEN BERET, BAT MAN, Jméno Růže (to musel dělat nějakej machr!), THREE WEEKS IN PARADISE, HERBERT, HIGHWAY, HEARTLAND a dalších pár stovek. Všimněte si např. v Green Beret co se stane, potká-li se víc chlapíků najednou (krom toho, že vás zabijí) - a to se ke všemu ještě roluje pozadí...! Klasickým příkladem sprajtu s maskou je šipka v Art Studiu, Desktopu, Orfeovi...
Co je myšleno maskou? Podívejte se na obrázek: jsou na něm tři typy čtverečků: 1) černé - to je Joe, tak jak ho znáte; 2) bílé - patří také Joeovi (tvoří mu vnitřek těla, obličej a jakousi ochranou čáru kolem); 3) šedé - a to je maska.Ve skutečnosti se grafika a maska nedají zakreslit do jednoho obrázku, udělal jsem to jenom kůli názorné ilustraci. Obrázky by správně měli být dva: na jednom by byla jen grafika a na druhém jen maska (obrázky musí mít stejné rozměry a když je dáte "na sebe" musí dohromady vypadat právě takto). V praxi se využije jednotlivých čtverečků následovně: maska se přiloží na pozadí a to, co "leží pod ní" zůstane zachováno. Vznikne "díra", do které se potom dokreslí grafika, a pak to vypadá přesně jako v Green Beret (Jonathan Smifff mi zaplatil, abych ho propagoval, tak se snažím). Uvědomte si, že tím, jak definujete masku, ovlivňujete výsledný efekt - když v masce necháte v místě skla "bílo", neuvidíte skrz lupu nic, když prostor skla vyplníte, zůstane "průhledné". Existují i masky založené na opačném principu, ale připadá mi výhodnější používat tyto.

3.2 Zákadní sprajtovací algoritmus

Všechny hry, využívající sprajty, vycházejí z jednoho systému jejich přemísťování, který je podle potřeby individuálně přizpůsobován a optimalizován, až k nepoznání. Jeho základ by mohl vypadat přibližně takto:
1. je-li to nutné, vykresli pozadí (např. při posunu ulice to nutné je)
2. nastav nové souřadnice sprajtů
3. polož všechny sprajty od nejspodnějšího k nejsvrchnějšímu (tento bod bývá konkretizován podle toho, zda se hraje ve 3D (BAT MAN, KNIGHT LORE) nebo "nadhledu z boku" (RENEGADE 1, 2, jízda městem v BAT MAN 3) nebo jen "pohledu z boku" (RoboCop, Green Beret) či "shora" (STAR DRAGON, LIGHT FORCE); obecně platí, že sprajty s nejnižším pořadovým číslem jsou "nejdál")
4. zvedni všechny sprajty od nejsvrchnějšího k nejspodnějšímu (viz. 3.)
5. zpátky na bod 1.
Vypadá to na první pohled trochu pochybně, ale hned si k tomu řekneme víc - je jisté, že něco vykreslit a vzápětí to smazat je hloupost - mezi bodem 3. a 4. se musí čekat, aby si člověk vůbec měl šanci sprajty prohlédnout, někdy se také musí otestovat pohyb a podoby, narazí na nejrůznější komplikace: program bude nechutně pomalý a při velkém počtu sprajtů bude obraz blikat až hrůza. Řešení spočívá v tom, že se všechny přípravné práce musejí provést někde v paměti a na obrazovku se dostane pouze nový "snímek", který bleskurychle překreje ten předcházející. Opět existuje několik způsobů, jak se vypořádat s přípravnými pracemi: tuším že v COBŘE se to dělá tak, že během jednoho přerušení se vyhodnotí nové pozice sprajtů, uloží se na odkazy na jejich data na zásobníku, a v dalším přerušení se to všechno nakreslí a to ještě zbyde čas na zvuk. Jiná varianta je mít někde v paměti rezervní obrazovku, jejíž obsah se bude kopírovat do videoram (bývá relativně pomalé), chytřejší programy kopírují pouze tu část, kde došlo ke změnám.

3.3 Prográmek na dobrou noc

Program byl odladěna na systému Prometheus - používáte-li jiný překladač, může dojít u pseudoinstrukcí k odlišnostem v zápisu. Program se snaží konkretizovat mlhavé představy o magické moci masky... Zkuste zpozorovat rozdíl, ke kterému dojde uvnitř čtverečku, když v datech změníte čísla 24 na 0.
ent START  ;pseudoinstrukce, udávající kde má program
    ;začátek
START ld hl,16384 ;bitová mapa videoram je zaplněna vzorkem
 ld de,16385 ;kvůli demonstraci účinků masky
 ld bc,6143
 ld (hl),255 ;číslo vzorku (255) je možno měnit podle libosti...
 ldir
 ld hl,DATA  ;HL ukazuje začátek dat sprajtu
 ld de,#4022 ;DE říká, kam do videoram se bude kreslit
 ld b,8  ;výška sprajtu je osm bodů
LOOP ld a,(de)  ;vezmi bajt z videoram
 and (hl)  ;a ponech pouze to, co je v masce
 inc hl  ;posuň se bajt grafiky
 or (hl)  ;a přidej ho k masce
 inc hl  ;posuň se na další masku
 ld (de),a  ;bajt polož do videoram
 inc d  ;posuň se ve videoram na další řádek
 djnz LOOP  ;opakuj 8x
 ret   ;konec - vrať se

DATA defb 0,0,0,126,0,66,24,66,24,66,0,66,0,126,0,0
(pokračování příště)

Žádné komentáře:

Okomentovat