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:
-
5. září 2024
Matrixmedia - Obsluha a tisk na velkoformátových digitálních tiskárnách
-
30. září 2024
-
4. října 2024
Webdesign
Tipy a triky pro animace ve Flash 5, III. díl
25. září 2001, 00.00 | Tentokrát si mimo jiné detailně prohlédneme slíbený Tsunami efekt legendárního Joshuy Davise a vysvětlíme si další vlastnost, která není zdokumentována v Action Script Reference, takzvanou "dědičnost", vytvářenou pomocí "prototype".
Předpokládejme, že jste bez úhony (tedy ne jako já :o) prošli předchozími dvěma díly tohoto miniseriálu o skriptovém řízení animací. V tom případě byste se právem alespoň v tomto oboru měli cítit jako středně nebo alespoň mírně pokročilí...
Ale to znamená, že se musíme podívat opět na o něco složitější skriptovací techniky! Takže vzhůru do boje!
Nejdříve si stáhněte ukázkový soubor zde. Podívejme se, co v něm dnes najdete.
1. Výpočet rotace objektu na základě goniometrických funkcí
Nejdříve ze všeho vám musím zase říct další ošklivou věc o Flash 5: jeho AS sice obsahuje Math objekt s množstvím vlastností, které narozdíl od F4 umožňují provádět korektní a jednoduché výpočty. Leč je to bohužel na úkor rychlosti skriptů. Obecně se dá říct, že používání Math objektů, obzvláště ve větším množství (například ve spojení se smyčkami "for") skripty citelně zpomaluje a tím je zpomalená samozřejmě celá animace.
Ale nenechte si tím AS zošklivit :o) a podívejte se na stránku 1 v ukázkovém souboru. Pokud si pamatujete na ukázky v prvním díle tohoto miniseriálu, byla tam uvedená ukázka velmi jednoduchého výpočtu rotace objektu pouhým zvětšováním úhlu otočení. Ne vždycky si ale s takovým typem skriptu vystačíte.
V naší dnešní ukázce jsou pro výpočet rotace použité goniometrické funkce. Dvojklikněte si na MC "kruh". Na MC "bod" najdete kompletní skript, který ovládá jeho pohyb.
onClipEvent (load) {
krok = 0.1
r = 100
uhel = 0
this._x = r*Math.cos(uhel)
this._y = r*Math.sin(uhel)
}
Tato část skriptu provede inicializaci počátečních hodnot. Nastaví délku kroku, o který se bude bod po kružnici otáčet, důležitým parametrem je samozřejmě poloměr kružnice "r".
onClipEvent(enterFrame) {
uhel += krok
this._x = r*Math.cos(uhel)
this._y = r*Math.sin(uhel)
}
Tato část skriptu provádí samotnou rotaci. Pokud nemáte panickou hrůzu z goniometrických funkcí (já ji už překonal :o))), vidíte, že skript je velice jednoduchý.
Pravděpodobně vás napadne, jaké výhody má tato metoda oproti ukázce z prvního dílu seriálu.
Ano, efektu, který vidíte na této ukázce, lze velmi jednoduše dosáhnout prostým přičítáním velikosti úhlu otočení. Jenomže co když je pohyb objektu komplikovanější? Co když chceme, aby například přilétl na scénu zleva, poté třikrát vykroužil elegantní kolečko a pak vylétl pravou stranou scény ven?
V takovýchto případech je potřeba použít typ skriptu, o kterém jsme hovořili výše. Podívejte se na jednoduché aplikace v dalších ukázkách.
2. Pohyb po spirále
Na straně 2. ukázkového souboru najdete bod, který rotuje po spirále uvnitř kružnice. Lehkým náhledem na skript MC "bod" zjistíte, že se toho mnoho nezměnilo:
onClipEvent(enterFrame) {
r += spiral
if (r < 2 || r > 100) {
spiral = -spiral
}
uhel += krok
this._x = r*Math.cos(uhel)
this._y = r*Math.sin(uhel)
}
Přibyla pouze sekce, která plynule zmenšuje a zvětšuje poloměr pohybu "r" (řádky 2 - 5).
3. Pohyb po obvodu elipsy a plynulá změna parametrů
Prohlédněte si stránku 3 ukázkového souboru. Najeďte kurzorem dovnitř modré elipsy, stiskněte levé tlačítko myši a pohněte kurzorem. Velikost a proporce objektu se začnou plynule měnit, ale kroužící bod se drží obvodu jako klíště.
Nejdříve se podívejme na to, jak je zařízená změna velikosti a proporcí. Skript vychází z následující úvah:
- nejdříve musím detekovat, zdali se kurzor nachází nad objektem
- pokud se nachází v požadované oblasti, musím detekovat, zdali bylo stisknuto pravé tlačítko myši
- pokud byly obě předchozí podmínky splněny, od pohybu kurzoru odvodím změnu velikosti objektu
To vše nám zařídí tento skript:
onClipEvent(mouseMove) {
oldX = newX
oldY = newY
newX = this._xmouse
newY = this._ymouse
if (dole) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
narustX = newX - oldX
narustY = newY - oldY
this._width += narustX
this._height += narustY
}
}
}
onClipEvent(mouseDown) {
dole = true
}
onClipEvent(mouseUp) {
dole = false
}
První část skriptu, uvozená handlerem "mouseMove", vytváří smyčku, ve které se při každém pohybu myši neustále přepisují hodnoty pro původní a novou pozici kurzoru.
V další části se provádí tzv. "hitTest" neboli test, který detekuje, zdali se kurzor nachází nad plochou MC. Pokud je tato podmínka skriptem schválená, skript upraví šířku a výšku MC pomocí rozdílu mezi původními a novými souřadnicemi kurzoru.
Další dva handlery, mouseUp a mouseDown, detekují, zdali bylo stisknuto levé tlačítko myši. Mění logickou/booleanskou proměnnou "dole", používanou v předcházejícím bloku skriptu.
Nyní si prohlédněte upravené skipty na MC "bod":
onClipEvent (load) {
krok = 0.1
}
onClipEvent(enterFrame) {
a = _parent.Se._width/2
b = _parent.Se._height/2
uhel += krok
this._x = a*Math.cos(uhel)
this._y = b*Math.sin(uhel)
}
Jsou velmi podobné skriptům v předcházejících ukázkách. Jediné dvě změny, které byly provedeny, jsou 1) skript neustále měří osy elipsy "a" a "b", 2) skript používá pro výpočet pohybu MC rovnici pro elipsu.
4. Legendární Tsunami efekt
Nejprve se pokochejte :o) na čtvrté straně ukázkového souboru tímto efektem. Původně jej cca před rokem a půl vymyslel Joshua Davis, velký fleší guru a filozof. Byl napsán ještě ve Flash 4.
Dodnes najdete na různých diskuzních fórech dotazy "jak vytvořit Tsunami efekt". Není se čemu divit. Jde o vcelku jednoduchý, chytrý animační skript, a nutno také říct, že je to jeden z prvních experimentů s animačními schopnostmi AS.
Nicméně čas se posunul o něco dál, takže jste pravděpodobně jako já tento efekt viděli použitý v různých variantách na různých webech. A protože se ten čas skutečně posunul o dost dál (nenechte se mýlit, rok a půl ve vývoji skriptovacích Flash technik znamená velmi mnoho), je možné původní Davisův jednaosmdesátiřádkový(!!) skript napsat mnohem efektivněji a využít rozšířených možností AS ve verzi 5.
Popravdě řečeno, abych dostál své pověsti českého flashguru :o))))), vlastně jsem z původního skriptu převzal jenom základní ideu a napsal jsem vše úplně znovu.
Pokusím se skript vzít postupně myšlenku po myšlence a vysvětlit blíže jednotlivé techniky.
"Dědičnost" neboli "prototype"
Jistě jste si všimli, že objektově orientovaný Flash 5 používá tzv. vlastnosti objektů neboli "properties". Asi nejužívanějším objektem je Movie Clip, který má například vlastnosti:
_xscale
_alpha
_visible
_height
a tak dále a tak dále. Tyto vlastnosti jsou velmi praktické. Ptáte se v čem?
Zatímco ve Flash 4 jste museli zdlouhavě vypisovat všechny ty getProperty a setProperty, nyní můžete adresovat přímo danou vlastnost, takže NE:
setProperty("mujMC", _alpha = 30);
ale TAKTO:
mujMC._alpha = 30
Jak vidíte, zápis pomocí vlastností objektu je kratší a ušetří vám omačkané prstíky i klávesnici. Údajně jsou také skripty, přímo adresující vlastnosti objektu, o poznání rychlejší, což jak už víte je bohužel u Flash 5 VELICE důležité.
No, a nyní vězte, že takovou vlastnost, kterou budou mít VŠECHNY objekty daného typu, si můžete vytvořit sami.
Co to znamená? Že potřebnou vlastnost nadefinujete pouze jednou pro daný typ objektu a ona pak bude platit pro všechny objekty daného typu. Například:
MovieClip.prototype._hniSebou = function (kolikPixelu) {
this._x += kolikPixelu
}
nadefinuje pro všechny MC ve vašem projektu vlastnost _hniSebou, která posune MC o potřebný počet pixelů ve směru osy X.
Takže když máte například klip "modreKolecko", můžete s ním nyní pohnout takto:
modreKoleckou._hniSebou (10)
Tento řádek posune klip o deset pixelů.
Výraz "MovieClip.prototype" je oním kouzelným kouskem, který vše zařídí. "MovieClip" znamená, že se dědičnost vlastnosti bude týkat všech Movie Clipů, slůvko "prototype" nastavuje právě onu dědičnost.
Tato skriptovací technika je velmi užitečná v případech, kdy potřebujete pro více objektů, například klipů, použít podobné skripty. Ušetří se tím hromada programových řádků a následně skripty poběží nejen rychleji, ale uvolní se drahocenná paměť, do které si Flash "odhazuje" proměnné a další části skriptů (a buďte si jistí, že u rozsáhlejších skriptů to velmi oceníte).
Náš případ "dědičnosti"
Podívejte se na jednotlivé MC, ze kterých je naše Tsunami vlna postavená. Na každém klipu je pouze totálně jednoduchý skript:
onClipEvent (enterFrame) {
this._move(this._ymouse, _parent.detect.spust)
}
Tento skriptík dokáže řídit celkem komplikované chování všech pohybujících se klipů. Na první pohled vidíte, že skript používá jakousi vlastnost, která je označená jako "_move". Tato vlastnost je volána se dvěma parametry: pozicí myši vůči klipu a detekční proměnné "spust".
Podívejme se nejdříve na detekční proměnnou "spust", ať máme ve všem pořádek. Tato logická/booleanská proměnná je definována klipem "detect", což je tmavomodrý obdélník, ležící pod "Tsunami řádky". Úkolem tohoto klipu je spouštět a vypínat Tsunami efekt: pokud je kurzor nad plochou klipu, efekt probíhá, pokud kurzor vyjede z definované oblasti, "řádky" se postupně vracejí do původní pozice. To je zařízeno následujícím skriptem:
onClipEvent (enterFrame) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
spust = true
} else {
spust = false
}
}
O použití "hitTest" jsme si už dnes povídali, takže vše je předpokládám jasné.
Nyní se podívejme na definici "_move" vlastnosti MovieClipů. Najdete ji napsanou přímo na čtvrtém frame ukázkového souboru:
MovieClip.prototype._move = function (param, det) {
var cesta = this.v1
if (det) {
if (Math.abs(param) < 200) {
cesta._xscale = 100 + 0.0012*Math.pow(200 - Math.abs(param),2.2)
cesta._yscale = 100 + 0.0012*Math.pow(200 - Math.abs(param),2.2)
cesta._alpha = 20 + 0.0005*Math.pow(200 - Math.abs(param),2.3)
cesta._y = -(200 - Math.abs(param))/6
} else {
cesta._xscale = 100
cesta._yscale = 100
cesta._y = 0
cesta._alpha = 20
}
} else {
if (cesta._xscale > 100) {
cesta._xscale -= (cesta._xscale - 100)/6
cesta._yscale -= (cesta._yscale - 100)/6
cesta._y -= (cesta._y - 0)/6
cesta._alpha -= (cesta._alpha - 20)/6
} else {
cesta._alpha = 20
}
}
}
Funkce prvního řádku skriptu je jasná, říkáme, že objektu typu MovieClip přidáme novou vlastnost, zvanou "_move", a že tato vlastnost je funkce dvou parametrů.
Další řádek je taková drobná "vychytávka", která opět šetří paměť a urychluje skript. Každý z klipů "Tsunami řádků" obsahuje uvnitř sebe klip s názvem "v1", který provádí všechny potřebné animace (zvětšení, změna polohy, změna průhlednosti). Místo toho, abychom donekonečna opisovali "this.v1._xscale" apod., máme jednoduše nadefinovanou proměnnou "cesta = this.v1" a všude můžeme psát "cesta._xscale" atd. Flash si údajně dokáže tuto proměnnou nějak uložit a pak už pokaždé neidentifikuje celou cestu, ale čte ji odněkud z vyrovnávací paměti.
Další řádky matematicky popisují samotný Tsunami efekt. Skript se nejprve zeptá, zdali je proměnná "det" pravdivá, to jest jestli se kurzor nachází nad detekčním klipem.
Pokud se nachází, skript zjistí, zdali je kurzor vzdálený od daného MC "Tsunami řádku" méně než 200 pixelů. Pokud je tato podmínka splněná, MC je zahrnut do "zóny vlivu skriptu" a tento skript přepočítá velikost, pozici a průhlednost klipu. Pokud podmínka splněná není, klip je nastaven na výchozí hodnoty.
Poslední část skriptu zajišťuje plynulý "návrat" "Tsunami řádků" do původní pozice. Jestliže kurzor vyjede z "aktivní zóny", vlastnosti klipu se postupně "resetují" na původní hodnoty.
"Jak jednoduché"
Tak, a to je celá moje verze slavného Tsunami efektu. Ti, kteří s Flashem teprve začínají, se možná cítí trochu nejistě a potřebují si jednotlivé skripty ještě několikrát projít, aby jejich funkce pochopili do detailů.
Ti zkušenější si možná řeknou "no a, to je toho, vždyť je to hračka" :o)). Nicméně Tsunami efekt pravděpodobně zůstane s několika dalšími technikami v galerii klasických, nebojím se říct i průkopnických skriptovacích postupů. Je to zkrátka nepříliš složitý, chytrý a hezký efekt.
Pokud jste některým částem skriptů v tomto tutorialu nerozuměli, podívejte se do prvních dvou dílů tohoto miniseriálu, které najdete zde a zde. Doufám, že v nich najdete objasnění vašeho problému. Pokud ne, pište dolů pod článek do diskuze.
KONEC??? seriálu o animačních technikách, založených na skriptování?
Tak, a teď už to záleží jenom na vás. Přiznám se k pocitu, že jsem více méně vyčerpal nejdůležitější základní principy skriptových animací... ale třeba právě vás napadne další otázka na toto téma, něco, co byste sami rádi viděli podrobněji rozebrané a co by pomohlo ostatním.... takže hurá do toho, pokud na něco takového narazíte, napište to pod tento článek jako diskuzní příspěvek a v dalším tutorialu vám rád poskytnu ukázku s výkladem...
A pokud nikoho z vás nic nenapadne, příští tutorial by se měl zabývat objekty typu pole a generický objekt.
-
14. května 2014
Jak vkládat snímky do galerií a soutěží? Stručný obrazový průvodce
-
23. dubna 2014
Konica Minolta přenesla výhody velkých zařízení do kompaktních modelů
-
12. června 2012
-
9. dubna 2014
-
29. listopadu 2013
-
6. září 2004
OKI snižuje ceny barevných laserových tiskáren C3100 a C5200n
-
13. května 2004
-
19. ledna 2004
QuarkXPress Passport 6: předvedení nové verze na konferenci Apple Forum 27.1.2004
-
6. února 2001
-
30. listopadu 2014
Nový fotoaparát α7 II: první plnoformát s pětiosou optickou stabilizací obrazu na světě
-
5. srpna 2024
Bubnový scanner na 4000dpi optické rozlišení + PC + software
-
8. září 2024
-
14. října 2024
-
5. listopadu 2024