Tipy a triky pro animace ve Flash 5, II. díl - Grafika.cz - vše o počítačové grafice

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Poptávka práce


Webdesign

Tipy a triky pro animace ve Flash 5, II. díl

Flash

14. září 2001, 00.00 | V prvním dílu jste našli popisy základních (a velmi jednoduchých) animačních skriptů, dnes se podíváme na jejich praktické využití a na složitější (a efektnější) skripty.

Tento tutorial navazuje na předchozí díl a seznámíte se v něm s dalšími "fintami" a postupy pro skriptově řízené animace. V prvním díle jste našli popisy základních (a velmi jednoduchých) animačních skriptů, dnes se podíváme na jejich praktické využití a na složitější (a efektnější) skripty.

Začneme malým varováním :o)). Pokud je někdo z vás opravdu začátečník a neprošel si předchozí díl tohoto tutorialu, doporučuji NEJDŘÍVE prostudovat onen předchozí, kde se naučíte chápat základní principy, které Action Script používá pro animace. V dnešním tutorialu totiž přijdou na přetřes složitější záležitosti a nebude prostor na podrobné komentáře.

Hned také přidám dobrou zprávu. Zatímco v prvním dílu byly popsány velmi jednoduché příklady skriptů, dnes se dostaneme k složitějším a přiměřeně efektnějším animacím.

Jak už jste si určitě zvykli v mých tutorialech, přeskočíme nudné úvodní pasáže :o)) typu "udělejte si plochu o velikosti.... a nyní zelený obdélníček o velikosti" a přejdeme hned k věci. Stáhněte si ukázkový soubor zde a vrhněme se po hlavě na první ze dvanácti dnešních ukázek.

1. Řízení pohybu mezi více body
Na straně číslo 1 ukázkového souboru najdete ukázku skriptu, který nemá jen počáteční a koncový bod, ale pohyb probíhá mezi více body.

souradniceX = [500,20,400,700]
souradniceY = [20,400,300,450]
startX = souradniceX[c1]
startY = souradniceY[c1]
endX = souradniceX[c2]
endY = souradniceY[c2]
koef = 80
speedX = (endX - startX)/koef
speedY = (endY - startY)/koef
this._x = startX
this._y = startY
c1++
if (c1 == 3) {
  c2 = 0
}
if (c1 < 3) {
  c2 = c1 + 1
}
if (c1 >3) {
  c1 = 0
  c2 = 1
}
play()

Tak, tento děsivý skriptový "štrúdl" vás doufám příliš nevyděsil a můžeme se pustit do objasňování principu.
Základní myšlenka je jednoduchá. Vytvoříme dvě pole (Array), do kterých zaneseme souřadnice. Z těchto polí budeme postupně číst, a to tak, že když objekt dorazí do koncového bodu, načtou se z polí nové souřadnice koncového bodu a pohyb pokračuje.

Pro ty, kteří nevědí, co jsou to pole neboli Arrays, nejprve krátký komentář. Array (pole) je objekt, který se tváří jako "vícenásobná proměnná". Můžete si jej představit jako řádku chlívečků, přičemž v každém jednotlivém chlívečku je uložená jedna hodnota. "Chlívečky" jsou číslovány od 0 výše. K jednotlivým položkám pole se potom dostanete pomocí syntaxe

mojePole [cisloChlivecku]

S poli lze provádět mnoho různých zajímavých operací a některé složitější skripty bez nich nevytvoříte. Bohužel, jak jsem již v předchozích tutorialech upozorňoval, AS není zrovna nejrychlejší a některé operace s poli jsou UKRUTNĚ pomalé. Nicméně v některém z dalších tutorialů bych se přesto chtěl věnovat speciálně objektům typu generický objekt, pole a podobně. Ale vraťme se k našemu skriptu.

Takže první dva řádky vytvoří pole se souřadnicemi. Další část skriptu používá dvě proměnné, "c1" a "c2". Jsou to jednoduché čítače, které "vyzvedávají" z polí příslušné souřadnice. Když animovaný objekt dorazí do koncového bodu, přičte se k oběma čítačům jednička a tím se z původních koncových souřadnic stanou souřadnice startovní a načtou se nové koncové. Přeloženo do lidštiny, skript říká toto: "odstartuj z bodu A do bodu B. Když do něj dorazíš, vezmi bod B a z něj odstartuj do bodu C. Až dorazíš do bodu C, vezmi ho jako startovní a jdi do bodu D". Body A, B, C a D si skript vyzvedává z polí, kde jsou umístěny takto:

souradniceX[Ax,Bx,Cx,Dx]
souradniceY[Ay,By,Cy,Dy]

takže třeba souradniceX[0] obsahuje hodnotu pro Ax, souradniceX[1] pro Bx atd.

Podívejme se ještě trochu blíže na to, jak pracují čítače "c1" a "c2". "c1" vyzvedává hodnoty pro startovní bod, tedy pokud je c1 = 0, bude startovním bodem bod A. Čítač "c2" vyzvedává hodnoty pro koncový bod. Pokud je startovním bodem A, koncovým bodem je v tom okamžiku B a "c2" tudíž musí mít hodnotu 1 (protože souřadnice pro bod B v obou polích jsou na indexu 1).

Tento vztah, kdy je vlastně "c2" o jednu pozici dále než "c2", popisuje poslední část skriptu:

c1++
if (c1 == 3) {
c2 = 0
}
if (c1 < 3) {
c2 = c1 + 1
}
if (c1 >3) {
c1 = 0
c2 = 1
}

První řádek této části skriptu zvýší hodnotu čítače "c1" o jednu, tudíž "posune se z bodu A na bod B atd.".
Musíme ale ošetřit fakt, že pole mají jen čtyři pozice, od 0 do 3. A my chceme, aby se pohyb opakoval ve smyčce. To znamená "z bodu D se vrať do bodu A".
Proto se další části skriptu ptají, jakou hodnotu má "c1".
Pokud je c1 rovno 3, znamená to, že bere souřadnice z poslední pozice polí. Startovní bod je D a koncový bod musí být A. Proto se "c2" přiřadí hodnota 0 (skript pak vezme koncové pozice bodu z prvních pozic polí, které mají index 0).
Pokud je "c1" menší než 3, "c2" je o jednu větší a jednoduše bere z polí souřadnice z následujícího indexu.
Pokud "c1" překročí hodnotu 3, neexistuje v poli už žádná další položka a "c1" se musí "vyresetovat" na první index pole, tedy na nulu.

Nezapomeňte na to, že při startu celé animace musíte nastavit hodnoty pro oba čítače, v našem případě jsou tyto hodnoty umístěny jako handler:

onClipEvent (load) { c1 = 0 c2 = 1 }

Samotný pohyb je zajišťován jednoduchým principem, popsaným v předchozím díle tutorialu.

Tento typ skriptové animace můžete využít například pro různá menu, kde se na základě stisknutého tlačítka objekt přesune na potřebné souřadnice, nebo pro dynamicky rostoucí grafy.... atd. atd. Záleží jen na vaší představivosti.

2. Pseudo 3D animace
Flash sám o sobě není postaven pro 3D animace. Existují sice různé 3D enginy, které na principu goniometrických funkcí dokáží animovat jednoduché 3D objekty, ale jsou poměrně složité a poměrně pomalé. Můžete ale použít pseudo 3D animace, které sice skutečné 3D nenahradí, ale mohou vaše projekty oživit.

Typickým příkladem pseudo 3D je rotace objektu. Pokud vám nevadí, že objekt nemá žádnou tloušťku (kdybych tím objektem byl já, pravděpodobně bych byl spokojenější než jsem teď :o))), můžete tento princip používat.

Podívejte se na stránku 2 ukázkového souboru.

Jak to celé vlastně pracuje? Klip, který budeme "rotovat", mění svoje proporce v jedné ose. Tím, jak se zužuje a rozšiřuje, vytváří dojem jako by se otáčel. Aby byla iluze pohybu o něco blíže realitě, musí mít objekt přední a zadní stranu. To zajistíme tím, že klip bude mít dva snímky, přední a zadní stranu, a mezi nimi budeme přepínat.

onClipEvent (load) {
  krok = -5
  this._xscale = 100
}

onClipEvent (enterFrame) {
  if (Math.abs(this._xscale) > 100) {
     krok = -krok
     }
  if (Math.abs(this._xscale) < Math.abs(krok)) {
     krok/Math.abs(krok) == -1 ? snimek = 2 : snimek = 1
     this.gotoAndStop(snimek)
  }
  this._xscale += krok
}

Tak, a tohle je celý skript, který řídí animaci.
První část s handlerem onClipEvent(load) pouze provádí inicializaci proměnných.

Samotný pohyb řídí druhá část skriptu.
První "if" podmínka sleduje, zdali šířka objektu nepřekročila hodnotu 100%. Pokud ji překročí, otočí se hodnota proměnné "krok" a objekt se začne zmenšovat.

Druhá podmínka "if" "překlápí" mezi přední a zadní stranou klipu, tedy mezi snímky 1 a 2. K tomuto překlopení dojde ve chvíli, kdy šířka klipu přechází z kladných hodnot na záporné a naopak. Skript se nejdříve zeptá "je objekt tak zúžený, že se v příštím kroku překlopí z malé kladné na malou zápornou šířku?". Pokud tomu tak je, skript pomocí conditionalu (popsáno v předchozím tutorialu) podle směru pohybu zjistí, jestli má "překlopit" klip na přední nebo zadní stranu.

Jde opravdu jen o napodobeninu 3D, ale v mnoha případech, kdy by bylo příliš složité a neefektivní používat objekty, renderované v jiných programech a kdy potřebujete animaci opravdu řídit (tj. používat skripty), si s tímto principem bohatě vystačíte. Jen bych připomenul, že příliš pravidelné objekty (např. symetrický trojúhelník, úplný kruh apod.) při této animaci moc prostorově nepůsobí, je třeba používat objekty nesymetrické a nepravidelné.

3. Pronásleduj myš!
Často se můžete setkat se skripty typu "follow mouse", při kterých objekt "pronásleduje" kurzor. Tyto skripty jsou málokdy opravdu praktické, ale občas působí efektně nebo aspoň mile :o). Pokud je používáte jako "permanentní reklamu", neustále se táhnoucí za myší, pak je tento typ animace sice velmi praktický, ale ne tak milý :o)...

Než si začneme hrát s tímto typem skriptu, podívejme se na ukázku č. 3. Nedělá nic světoborného a závratného, přesto jsem ji sem zařadil. Obsahuje totiž jeden důležitý princip, který začátečníci a minulí uživatelé Flash 4 často neznají.

Určitě znáte akci startDrag(objekt). Tato akce vám zajistí, že se objekt bude pohybovat souběžně s kurzorem. Stejného efektu lze dosáhnout i jiným způsobem, a navíc efektivněji.

onClipEvent (mouseMove) {
this._x = _root._xmouse
this._y = _root._ymouse
updateAfterEvent(mouseMove)
}

Tento skript říká: "kdykoliv se pohne myš, posuň souřadnice objektu na aktuální souřadnice kurzoru".

Jaké jsou výhody proti startDrag()? Tento skript můžete použít pro libovolný počet objektů, kdežto startDrag() jen pro jeden. A navíc: poslední řádek skriptu, "updateAfterEvent(mouseMove)", ošetřuje jednu starou bolest, kterou startDrag() trpí, a to je "cukavý" pohyb objektu na pomalejších počítačích (a bohužel při větších objektech i na rychlých počítačích). Akce "updateAfterEvent" totiž obnovuje obrazovku nezávisle na snímkování animace, takže kdykoliv pohne uživatel myší, Flash se vykašle na snímkování frame-to-frame a honem rychle překreslí objekt, který se pohybuje. Animace je čistší a hladší.

A honem k ukázce číslo 4. Tu bychom mohli nazvat "pronásleduj myš, ale nemusíš se strhat" :o).

onClipEvent(load) {
koef = 5
}

onClipEvent(mouseMove) {
cilX = _root._xmouse
cilY = _root._ymouse
}

onClipEvent (enterFrame) {
this._x += (cilX - this._x)/koef
this._y += (cilY - this._y)/koef
}

Jak vidíte, skript je opravdu jednoduchoučký. Část, uvozená handlerem "mouseMove", neustále nastavuje nový cílový bod, do kterého má objekt dorazit. Ve chvíli, kdy uživatel přestane hýbat myší, zůstane cílový bod "stát na místě" a objekt k němu postupně "dojíždí".

Pohybu, který je "přibržďovaný", je docíleno tak, že přírůstek pohybu je počítán ze vzdálenosti mezi objektem a cílovým bodem. Pokud vám není tento princip akcelerovaného/dekcelerovaného pohybu jasný, přečtěte si tutorial "BRZDĚTE aneb...", který je celý věnovaný tomuto tématu a najdete jej zde.

Na straně 5 ukázkového souboru najdete další vylepšení "pronásledované myši". Jednoduchým skriptem zde zařídíme, aby "pronásledující" objekt vypadal ve své snaze ještě urputněji a neustále ukazoval, kterým směrem se požene. Tento efekt zařídí jediný řádek:

this._rotation = Math.atan2(this._y - cilY, this._x - cilX) * 180/Math.PI

Jak vidíte, skript počítá rotaci objektu na základě tangenty (tedy pomocí goniometrické funkce).

V ukázkách 6 a 7 najdete další z mnoha možných vylepšení tohoto druhu skriptu.

Ukázka č. 6, kterou můžete nazvat třeba "neodbytná reklama" :o), je využito výše uvedeného "přibrždujícího" skriptu. Na jednotlivé klipy je potom aplikován pomalejší pohyb (větší hodnota proměnné "koef") a cílový bod pohybu je posunutý vůči bodu, kde se nachází nebo zastaví kurzor.

Ukázka č. 7 je příkladem toho, že takový skript nemusíme využít pouze ve spojení s jednoduchým "follow mouse" skriptem, ale může vytvořit i odlišně reagující objekty. V našem případě je to meníčko, které lze přesunovat pomocí přemisťování první položky po obrazovce, další položky plynule doplouvají do nadefinované pozice.

V tomto příkladě je skript o něco málo složitější. Podívejte se nejdříve na objekt "menu1". Uvnitř tohoto objektu je vložený button, který pouze detekuje, zdali se kurzor ocitl nad klipem a zdali byla stisknuta myš.

Handler na samotném klipu "menu1" potom zajišťuje jeho "tahání" a zároveň počítá základní cílový bod pro ostatní klipy:

onClipEvent (mouseMove) {
if (stisknuto) {
this._x = _root._xmouse
this._y = _root._ymouse
_root.cilX = this._x
_root.cilY = this._y
}
}

Proměnná "stisknuto" je přebíraná z buttonu uvnitř klipu.

Skripty na dalších klipech pak už jen neustále posouvají objekty do příslušné polohy.

4. Přirozenost = náhoda
Nadpisem této kapitoly nechci říct, že se typický fleší skriptař dokáže chovat přirozeně jen občas a to zcela nahodile :o))). Ani nechci propagovat myšlenku, že většina geniálních nápadů je dílem náhody... Chci tím říct, že samotné matematicky generované skriptové pohyby mají jednu základní nevýhodu: jsou "strojové" a v některých případech působí nepřirozeně.

Proto se často pro simulaci "živých" objektů používají náhodně generovaná čísla.

Podívejte se na jednoduchý příklad na straně 8 ukázkového souboru. Použil jsem skript, který je totožný s ukázkou 4, pouze jsem přidal dva řádky, generující náhodná čísla:

onClipEvent (enterFrame) {
this._x += (cilX - this._x)/koef
this._y += (cilY - this._y)/koef
this._x += -2 + 4*Math.random()
this._y += -2 + 4*Math.random()
}

Tyto dva řádky přičítají k souřadnicím číslo, které se náhodně vygeneruje v intervalu od -2 do 2. A tyto dva řádky způsobí, že k hladkému pohybu objektu se přidá jakýsi....eeeehm... "mikrobiální neklid" nebo jak to nazvat. Musíte uznat, že pohyb objektu jednoznačně získal na jisté "živočišnosti".

Jedním z příkladů použití náhodně generovaných čísel je příklad 9 v ukázkovém souboru. Je to jedna z mých prvních skriptových animací, "pan Nervóza" (můj kolega o ní prohlásil, že "ta animace je celkově taková nemocná" :o))). Záměr však byl určitě "zdravý": chtěl jsem vyřešit problém jak pohybovat náhodně objektem v určených hranicích, aniž bych stavěl mnohasetframovou animaci. Když se podíváte na jednotlivé skripty, zjistíte, že jsou velmi jednoduché a vyházejí z náhodně generované pozice klipu mouchy.

Že nemusí být náhodná čísla použitá jen k "neklidným" animačním pohybům ukazuje další, tedy 10. stránka příkladového souboru.

První frame animace:

startX = this._x + 1
startY = this._Y + 1
endX = 800*Math.random()
endY = 500*Math.random()
koef = 100 + 40*Math.random()
speedX = (endX - startX)/koef
speedY = (endY - startY)/koef
play()

používá staré známé skripty s počátečním a koncovým bodem pohybu. V tomto případě jsou však proměnné náhodně generovány (například endX v intervalu od 0 do 800, koef v intervalu 100 až 140).

Další frame animace obsahuje jednak kontrolní skripty, které už znáte z předchozích příkladů, jednak skripty, které vytvářejí jakýsi "rozmaz" nebo "chvost komety". Podívejme se na tyto skripty blíže kousek po kousku.

if (Math.abs(speedX) < 0.5 && Math.abs(speedY) < 0.5) {
gotoAndPlay(1)
}

Tento řádek hlídá, zdali není pohyb objekt příliš pomalý. Tím by na obrazovce vznikla "nuda", kdy by se objekt ploužil téměř na místě. Pokud jsou tedy rychlosti objektu v obou směrech najednou příliš nízké, skript skočí na první snímek a vygenerují se nové náhodné hodnoty.

_parent.attachMovie("stopa", "s" + counter, counter)
_parent["s" + counter]._x = this._x
_parent["s" + counter]._y = this._y

Tak, a tato část skriptu vytváří onen "ohon". Je zde použitá metoda "attachMovie" neboli "připoj klip".

Tato metoda je jedinou cestou jak dostat na scénu klip z knihovny. První krok, který musíte udělat než klip připojíte, je vyexportovat ho. Podívejte se do knihovny ukázkového souboru, v jejím základním adresáři jsem nechal klip s názvem "stopaMovie". Označte ho a nyní v pravém horním rohu paletky knihovny klikněte na Options a v otevřeném menu zvolte Linkage. Otevře se paletka Symbol Linkage Properties. V ní, jak vidíte, je zavoleno Export this symbol a jako Indentifier (identifikační jméno) je zapsáno "stopa".

Touto volbou se symbol vyexportuje do výsledného .swf, aniž by byl viditelný. Je však připravený k použití a má jméno, pomocí kterého jej můžeme zavolat.

Klipy je nutné připojovat do samostatných vrstev či spíše "hloubek" (depth). V každé hloubce může být pouze jeden objekt. Bližší informace o tom co to vlastně přesně "hloubky" jsou a jak se liší od vrstev a úrovní najdete v mém starším tutorialu "Definice cest k objektům a úrovním".

To, že každý připojený objekt bude připojen do své vlastní hloubky/vrstvy, je zajištěno pomocí proměnné "counter". Ta se neustále zvyšuje o vkládá objekty do dalších a dalších "depths".

První řádek skriptu tedy připojí z knihovny klip s identifikačním jménem "stopa", pojmenuje jej "s" + hodnota čítače (tedy například pro counter = 100 bude jméno nového klipu znít "s100") a umístí se do příslušné depth. Další dva řádky používají tzv. square bracket syntaxi, která umožňuje přístup k objektům pomocí dynamicky generovaného jména. Já vím, zní to složitě, tak si to zkusme ukázat na příkladě.

Řekněme, že první řádek skriptu nám připojením vytvořil klip se jménem "s85", tedy hodnota proměnné "counter" byla 85. Další dva řádky potřebují najít klip "s85", ale to skript dopředu neví. Proto použijeme zápis _parent["s" + counter], který vyhodnotí ("spočítá") obsah hranaté závorky a použije jej jako odkaz na klip.

Ti z vás, kteří znají starou funkci "eval", tento postup znají. Nicméně funkce "eval" je skutečně "fleší archaizmus", protože syntaxe hranatých závorek je jednak syntakticky korektnější, druhak se provádí rychleji než eval.

Aby byl efekt rozmazu dokonalý, je třeba, aby se připojené klipy zprůhledňovaly a nakonec zcela zmizely. To nám zajistí skript uvnitř klipu "stopaMovie":

this._alpha -= 5
if (this._alpha < 5) {
this.removeMovieClip()
}

Tento skript neustále snižuje hodnotu _alpha a pokud je hodnota velmi nízká, skript úplně smaže klip ze scény.

5. Co vás čeká příště
Nebojte, možnosti skriptových animací ještě ani zdaleka nekončí, proto budeme v našem seriálu pokračovat i příště. Opět jsem vám nechal v příkladovém souboru dvě ukázky. U té poslední vyzkoušejte následující: klikněte dovnitř modré elipsy a zatáhněte. Vidíte? Elipsa se zvětšuje a zmenšuje a rotující bod se pevně drží jejího obvodu....hezké, ne? Přitom tak jednoduché... A v příštím pokračování si ukážeme také legendární "tsunami" efekt stejně legendárního Joshuy Davise. Není to taková bomba, jak to zní, ale je to dost působivý a chytrý efekt.

Závěrečné slovo
Pokud jste čemukoliv v tomto tutorialu nerozuměli, podívejte se do předcházejícího prvního dílu. Pokud vám ani pak nebude některá funkce nebo metoda jasná, napište to do příspěvku k tomuto článku a já k němu ihned připojím komentář.

Jestliže jste tímto tutorialem prošli bez úhony :o) a bezpečně jste ho zvládli, můžete přidat k popsaným pohybům tzv. nelineární složku, která dodá animacím přirozenost. Můj starší tutorial k tomuto tématu se jmenuje "BRZDĚTE! aneb efekty přirozeného pohybu animací".

Ufff, tak to máme dnes společně za sebou....taky vás to tak vyčerpalo? :o)) takže těším se na příště....

Tématické zařazení:

 » Rubriky  » Go verze  

 » Rubriky  » Webdesign  

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: