Stáhnout PDF s nápovědou( 10MB)

Transkript

Stáhnout PDF s nápovědou( 10MB)
Programování v jazyce
ADOBE ACTIONSCRIPT 3.0
®
®
© 2008 Adobe Systems Incorporated. Všechna práva vyhrazena.
Copyright
Programování v jazyce Adobe® ActionScript® 3.0 pro aplikaci Adobe® Flash®
Pokud je tato příručka distribuovaná se softwarem, ke kterému patří smlouva s koncovým uživatelem, je tato příručka stejně jako v ní popisovaný software
poskytována na základě licence a může být používána nebo kopírována pouze podle podmínek této licence. S výjimkami povolenými v takové licenci nesmí být
žádná část této příručky reprodukována, ukládána ve vyhledávacím systému a přenášena v jakékoliv formě nebo jakýmikoliv prostředky, elektronickými,
mechanickými, záznamovými nebo jinými, bez předchozího písemného povolení společnosti Adobe Systems Incorporated. Uvědomte si prosím, že obsah této
příručky je chráněn copyrightem i v případě, že není šířena se softwarem, ke kterému patří licenční smlouva s koncovým uživatelem.
Obsah této příručky slouží pouze pro informaci, může se měnit bez upozornění a nelze ho vykládat jako závazek společnosti Adobe Systems Incorporated.
Společnost Adobe Systems Incorporated nepřebírá žádnou odpovědnost za chyby nebo nepřesnosti, které se v informačním obsahu této příručky mohou objevit.
Uvědomte si prosím, že existující umělecká díla nebo obrazy, které byste chtěli zahrnout do svých projektů, mohou být chráněny copyrightem. Neautorizované
začlenění takových materiálů do vaší nové práce může být porušením práv majitele copyrightu. Opatřete si prosím vyžadované povolení pro použití díla od
majitele copyrightu.
Všechny odkazy na názvy společností ve vzorových předlohách jsou pouze pro demonstrační účely a nejsou zamýšleny jako odkaz na jakoukoliv skutečnou
organizaci.
Adobe, the Adobe logo, Adobe AIR, ActionScript, Flash, Flash Lite, Flex, Flex Builder, MXML, and Pixel Bender are either registered trademarks or trademarks
of Adobe Systems Incorporated in the United States and/or other countries.
ActiveX and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and other countries. Macintosh is a
trademark of Apple Inc., registered in the United States and other countries. Java is a trademark or registered trademark of Sun Microsystems, Inc. in the United
States and other countries. All other trademarks are the property of their respective owners.
This product includes software developed by the Apache Software Foundation (http://www.apache.org/).
MPEG Layer-3 audio compression technology licensed by Fraunhofer IIS and Thomson Multimedia (http://www.mp3licensing.com)
Speech compression and decompression technology licensed from Nellymoser, Inc. (www.nellymoser.com).
Video compression and decompression is powered by On2 TrueMotion video technology. © 1992-2005 On2 Technologies, Inc. All Rights Reserved.
http://www.on2.com.
This product includes software developed by the OpenSymphony Group (http://www.opensymphony.com/).
This product contains either BSAFE and/or TIPEM software by RSA Security, Inc.
Sorenson Spark™ video compression and decompression technology licensed from Sorenson Media, Inc.
Adobe Systems Incorporated, 345 Park Avenue, San Jose, California 95110, USA
Notice to U.S. government end users. The software and documentation are “Commercial Items,” as that term is defined at 48 C.F.R. §2.101, consisting of
“Commercial Computer Software” and “Commercial Computer Software Documentation,” as such terms are used in 48 C.F.R. §12.212 or 48 C.F.R. §227.7202,
as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §§227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Software and
Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial items and (b) with only those rights
as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States.
Adobe Systems Incorporated, 345 Park Avenue, San Jose, CA 95110-2704, USA. For U.S. Government End Users, Adobe agrees to comply with all applicable
equal opportunity laws including, if appropriate, the provisions of Executive Order 11246, as amended, Section 402 of the Vietnam Era Veterans Readjustment
Assistance Act of 1974 (38 USC 4212), and Section 503 of the Rehabilitation Act of 1973, as amended, and the regulations at 41 CFR Parts 60-1 through 60-60,
60-250 ,and 60-741. The affirmative action clause and regulations contained in the preceding sentence shall be incorporated by reference.
iii
Obsah
Kapitola 1: O této příručce
Používání této příručky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Přístup k dokumentaci jazyka ActionScript
............................................................................. 2
Zdroje pro vzdělávání v jazyce ActionScript
............................................................................ 3
Kapitola 2: Úvodní informace k jazyku ActionScript 3.0
O ActionScriptu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Výhody jazyka ActionScript 3.0
......................................................................................... 4
Co je nového v jazyce ActionScript 3.0
Kompatibilita s předchozími verzemi
................................................................................. 5
................................................................................... 7
Kapitola 3: Začínáme s ActionScriptem
Základy programování . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Práce s objekty
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Společné prvky programu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Příklad: animace kusu portfolia
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Vytváření aplikací v jazyce ActionScript
Vytváření vlastních tříd
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Příklad: Vytváření základních aplikací
Spuštění následných příkladů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Kapitola 4: Jazyk ActionScript a jeho syntaxe
Přehled jazyka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Objekty a třídy
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Balíčky a jmenné prostory
Proměnné
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Typy dat
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Syntaxe
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Operátory
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Podmíněné příkazy
Opakování
Funkce
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Kapitola 5: Objektově orientované programování v jazyce ActionScript
Základy objektově orientovaného programování . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Třídy
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Rozhraní
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Zdědění
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Pokročilá témata
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Příklad: GeometricShapes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Kapitola 6: Práce s daty a časy
Základy data a času . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Správa kalendářních dat a časů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH iv
Obsah
Kontrola časových intervalů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Příklad: Jednoduché analogové hodiny
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Kapitola 7: Práce s řetězci
Základy řetězců . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Vytváření řetězců
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Vlastnost length
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Práce se znaky v řetězci
Porovnávání řetězců
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Získání vyjádření řetězce z jiných objektů
Zřetězení řetězců
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Vyhledání podřetězců a vzorků v řetězci
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Převod řetězců mezi velkými a malými písmeny
Příklad: kresba ASCII
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Kapitola 8: Práce s poli
Základní informace o polích
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Indexovaná pole
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Asociativní pole
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Vícedimenzionální pole
Klonování polí
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Pokročilá témata
Příklad: PlayList
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
Kapitola 9: Zpracování chyb
Základy zpracování chyb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Typy chyb
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Zpracování chyb v jazyce ActionScript 3.0
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Práce s ladicími verzemi aplikací Flash Player a AIR
Zpracování synchronních chyb v aplikaci
Vytvoření vlastních tříd chyb
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Reakce na chybové události a stavy
Porovnání tříd Error
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Příklad: použití třídy CustomErrors
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Kapitola 10: Používání regulárních výrazů
Základní informace o regulárních výrazech . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Syntaxe regulárního výrazu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Metody pro použití regulárních výrazů s řetězci
Příklad: analyzátor Wiki
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Kapitola 11: Práce s jazykem XML
Základy jazyka XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
Přístup E4X ke zpracování XML
Objekty XML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Objekty XMLList
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Inicializace proměnných XML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
Sestavování a transformace objektů XML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH v
Obsah
Procházení struktur XML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Použití jmenných prostorů XML
Převod typu XML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Čtení externích dokumentů XML
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Příklad: Načtení dat RSS z Internetu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Kapitola 12: Zpracování událostí
Základy zpracování událostí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Jak se zpracování událostí v jazyce ActionScript 3.0 liší od předchozích verzí
Tok událostí
Objekty událostí
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Posluchače událostí
Příklad: budík
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Kapitola 13: Programování zobrazení
Základy programování zobrazení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Základní třídy zobrazení
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Výhody přístupu seznamu zobrazení
Práce s objekty zobrazení
Manipulace s objekty zobrazení
Animace objektů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Dynamické načtení obsahu zobrazení
Příklad: SpriteArranger
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Kapitola 14: Používání kreslicího rozhraní API
Základy použití kreslicího rozhraní API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Vysvětlení třídy Graphics
Kreslení čar a křivek
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Kreslení tvarů pomocí vestavěných metod
Vytváření čar a výplní přechodu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
Použití třídy Math s kreslicími metodami
Animování s kreslicím rozhraním API
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Příklad: Algoritmický vizuální generátor
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Pokročilé použití kreslicího rozhraní API
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
Cesty kreslení
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Definování pravidel vinutí
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Používání tříd grafických dat
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
O použití metody drawTriangles()
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
Kapitola 15: Práce s geometrií
Základy geometrie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Používání objektů Point
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Používání objektů Rectangle
Používání objektů Matrix
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Příklad: Použití transformace matice na objekt zobrazení
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH vi
Obsah
Kapitola 16: Filtrování objektů zobrazení
Základní informace o filtrování objektů zobrazení
Vytváření a používání filtrů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Dostupné filtry zobrazení
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Příklad: Filter Workbench
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Kapitola 17: Práce s shadery Pixel Bender
Základy shaderů Pixel Bender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
Načtení nebo vložení shaderu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Přístup k metadatům shaderu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
Určení hodnot vstupu a parametrů shaderu
Používání shaderu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Kapitola 18: Práce s filmovými klipy
Základy filmových klipů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Práce s objekty MovieClip
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
Ovládání přehrávání filmových klipů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
Vytváření objektů MovieClip pomocí kódu ActionScript
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
Načítání externích souborů SWF
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
Příklad: RuntimeAssetsExplorer
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
Kapitola 19: Práce s doplněními pohyby
Základy doplnění pohybu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
Kopírování skriptů doplnění pohybu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Začlenění skriptů doplnění pohybu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Popisování animace
Přidávání filtrů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Přidružování doplnění pohybů k jejich objektům zobrazení
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
Kapitola 20: Práce s inverzní kinematikou
Základy inverzní kinematiky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
Přehled Animování Armatur IK
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Získávání informací o armatuře IK
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Konkretizace IK Mover a omezení pohybu
Posun armatury IK
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Používání událostí IK
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
Kapitola 21: Práce s textem
Základy práce s textem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Použití třídy TextField
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
Používání funkce Flash Text Engine
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Kapitola 22: Práce s bitmapami
Základy práce s bitmapami . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
Třídy Bitmap a BitmapData
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
Manipulace s obrazovými body
Kopírování dat bitmapy
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
Vytváření textur s funkcemi šumu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH vii
Obsah
Posouvání bitmap
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
Využívání výhod mipmappingu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
Příklad: Animovaný otáčející se měsíc
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
Kapitola 23: Práce ve třech rozměrech (3D)
Základy 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Vysvětlení 3D funkcí runtime programů Flash Player a AIR
Vytváření a posouvání 3D objektů
Zobrazení 3D objektů na 2D zobrazení
Příklad: perspektivní projekce
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Provádění komplexních 3D transformací
Používání trojúhelníků pro 3D efekty
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Kapitola 24: Práce s videem
Základy videa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
Vysvětlení formátů videa
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Vysvětlení třídy Video
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Načítání souborů videa
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Ovládání přehrávání videa
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Přehrávání videa v režimu celé obrazovky
Streamování souborů videa
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Vysvětlení startovacích bodů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Zapisování zpětně volaných metod pro metadata a startovací body
Používání startovacích bodů a metadat
Zachycování vstupu z kamery
Odeslání videa na server
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
Další témata pro soubory FLV
Příklad:Video Jukebox
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
Kapitola 25: Práce se zvukem
Základy práce se zvukem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
Porozumění architektuře zvuku
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
Načítání externích zvukových souborů
Práce s vloženým zvukem
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
Práce s datovým přenosem zvukových souborů
Práce s dynamicky generovaným zvukem
Přehrávání zvuku
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
Bezpečnost načítání a přehrávání zvuku
Řízení hlasitosti zvuku a jeho vyvážení
Práce s metadaty zvuku
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
Přístup k nezpracovaným zvukovým datům
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
Záznam zvukového vstupu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
Příklad: přehrávač podcastů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
Kapitola 26: Zachycování uživatelských vstupů
Základy uživatelského vstupu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
Zachycení vstupu z klávesnice
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH viii
Obsah
Zachycení vstupu z myši
Příklad: WordSearch
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
Kapitola 27: Sítě a komunikace
Základy práce v síti a komunikace
Práce s externími daty
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Připojování k instancím přehrávače Flash Player a programu AIR
Připojení soketu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609
Ukládání lokálních dat
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613
Práce s datovými soubory
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615
Příklad: Budování klienta Telnet
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
Příklad: nahrávání a stahování souborů
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632
Kapitola 28: Prostředí klientského systému
Základy prostředí klientského systému . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638
Použití třídy System
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640
Použití třídy Capabilities
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
Použití třídy ApplicationDomain
Použití třídy IME
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Příklad: Zjištění schopností systému
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649
Kapitola 29: Kopírování a vkládání
Základy kopírování a vkládání . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
Načítání ze systémové schránky a zápis do této schránky
Schránka:formáty dat
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654
Kapitola 30: Tisk
Základy tisku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
Tisk stránky
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660
Úlohy přehrávačů Flash Player a AIR a systémový tisk
Nastavení velikosti, měřítka a orientace
Příklad: Vícestránkový tisk
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665
Příklad: Změna velikosti, ořezání a reakce
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
Kapitola 31: Používání externího rozhraní API
Základy používání externího rozhraní API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
Požadavky a výhody externího rozhraní API
Používání třídy ExternalInterface
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673
Příklad: Používání externího rozhraní API s kontejnerem webové stránky
Příklad: Používání externího rozhraní API s kontejnerem ActiveX
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
Kapitola 32: Zabezpečení přehrávače Flash Player
Přehled zabezpečení přehrávače Flash Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
Karantény zabezpečení
Ovládání práv
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692
Omezení síťových rozhraní API
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699
Zabezpečení režimu celé obrazovky
Načítání obsahu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH ix
Obsah
Křížové skriptování
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
Přístup k načteným médiím jako datům
Načítání dat
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
Načítání vloženého obsahu ze souborů SWF importovaných do domény zabezpečení
Práce s obsahem ze starších verzí
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
Nastavení povolení LocalConnection
Ovládání výchozího přístupu URL
Sdílené objekty
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715
Přístup kamery, mikrofonu, schránky, myši a klávesnice
Rejstřík
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
1
Kapitola 1: O této příručce
Tato příručka je základem pro vývoj aplikací v Adobe® ActionScript® 3.0. chcete-li lépe porozumět návrhům a
technikám zde popsaným, měli byste již být seznámeni s obecnými koncepty programování, jako jsou například
datové typy, proměnné, cykly a funkce. Měli byste také rozumět základním konceptům objektově orientovaného
programování, jako jsou třídy a dědičnost. Předchozí znalosti jazyků ActionScript 1.0 nebo 2.0 jsou užitečné, nejsou
však nezbytné.
Používání této příručky
Kapitoly v této příručce jsou organizovány do následujících logických skupin, což y vám mělo lépe pomoci nalézt
jednotlivé oblasti dokumentace jazyka ActionScript:
Kapitoly
Popis
Kapitoly 2 až 5, přehled programování v jazyce
ActionScript
Věnuje se hlavním konceptům jazyka ActionScript 3.0, včetně syntaxe jazyka,
příkazů a operátorů a programování v jazyce ActionScript orientovanému na
objekt.
Kapitoly 6 až 11, klíčové datové typy a třídy jazyka
ActionScript 3.0
Popisuje datové typy na nejvyšší úrovni v jazyce ActionScript 3.0.
Kapitoly 12 až 32, rozhraní API přehrávače Flash Player
a aplikace Adobe AIR
Popisuje důležité vlastnosti, které jsou implementovány v balíčcích specifických pro
aplikaci Adobe Flash Player a Adobe AIR, včetně zpracování událostí, práce s objekty
zobrazení a seznamem zobrazení, práce v síti a komunikace, vstupu a výstupu
souborů, externího rozhraní, modelu zabezpečení aplikace a další.
Tato příručka také obsahuje různé vzorové soubory, které ukazují koncepty aplikačního programování pro důležité
nebo běžně používané třídy. Vzorové soubory jsou obsaženy způsobem, které usnadňuje jejich načítání a používání v
aplikaci Adobe® Flash® CS4 a mohou obsahovat také soubory obalu. Klíčový vzorový kód je však ryzím kódem jazyka
ActionScript 3.0, který můžete používat v kterémkoliv vývojovém prostředí, kterému dáváte přednost.
Jazyk ActionScript 3.0 může být psán a kompilován mnoha způsoby, včetně následujících:
• Používání vývojového prostředí Adobe Flex Builder 3
• Používání libovolného textového editoru a kompilátorů s příkazovým řádkem, například takovým, který se dodává
k vývojovému prostředí Flex Builder 3
• Používání vývojového nástroje aplikace Adobe® Flash® CS4 Professional
Další informace o vývojovém prostředí jazyka ActionScript, viz také „Úvodní informace k jazyku ActionScript 3.0“ na
stránce 4
Chcete-li porozumět vzorovému kódu v této příručce, není nutné mít předchozí zkušenost s používáním
integrovaného vývojového prostředí jazyka ActionScript, například vývojového prostředí Flex Builder nebo
vývojového nástroje Flash. Bude však vhodné se informovat v dokumentaci těchto nástrojů a naučit se je používat k
zapisování a kompilování kódu jazyka ActionScript 3.0. Další informace naleznete v části „Přístup k dokumentaci
jazyka ActionScript“ na stránce 2.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 2
O této příručce
Přístup k dokumentaci jazyka ActionScript
Protože se tato příručka zaměřuje na popisování jazyka ActionScript 3.0, který je bohatým a výkonným objektově
orientovaným programovacím jazykem, nepokrývá rozsáhle proces vývoje aplikací nebo pracovní postup v rámci
specifických nástrojů nebo serverové architektury. Takže kromě programování v jazyce ActionScript 3.0 bude vhodné
využívat také další zdroje dokumentace s tím, jak budete postupně navrhovat, vyvíjet, testovat a nasazovat aplikace
vytvořené v jazyce ActionScript 3.0.
Dokumentace jazyka ActionScript 3.0
Tato příručka vás seznámí s koncepty, které stojí za programovacím jazykem ActionScript 3.0, nabídne podrobnosti o
implementaci a vzory popisující důležité vlastnosti jazyka. Tato příručka však není vyčerpávajícím referenčním
dokumentem jazyka. Takovým dokumentem je Referenční příručka jazyka ActionScript 3.0 a jeho součástí, která
popisuje každou třídu, metodu, vlastnost a událost použité v jazyce. Referenční příručka jazyka ActionScript 3.0 a jeho
komponent poskytuje podrobné referenční informace o klíčovém jazyce, a součástech vývojového nástroje Flash (v
balících flash) a rozhraních API přehrávače Flash Player (v balících flash).
Dokumentace aplikace Flash
Pokud budete používat vývojový nástroj Flash, může být vhodné se informovat v následujících příručkách:
Kniha
Popis
Používání programu Flash
Popisuje způsob vývoje dynamických webových aplikací ve vývojovém nástroji
Flash
Programování v jazyce ActionScript 3.0
Popisuje specifické použití jazyka ActionScript 3.0 a jádra rozhraní API aplikace
Flash Player a Adobe AIR
Referenční příručka jazyka ActionScript 3.0 a jeho součástí
Uvádí syntaxi, použití a příklady kódu pro komponenty vývojového nástroje Flash
a rozhraní API jazyka ActionScript 3.0
Používání součástí jazyka ActionScript 3.0
Vysvětluje podrobnosti používání komponent k vývoji aplikací vytvořených
nástrojem Flash
Vývoj aplikací Adobe AIR pomocí programu Adobe Flash Popisuje způsob vývoje a nasazení aplikací Adobe AIR pomocí jazyka ActionScript
CS4 Professional
3.0 a rozhraní API jazyka Adobe AIR v programu Flash.
Jak se naučit jazyk ActionScript 2.0 v aplikaci Adobe Flash
Uvádí přehled syntaxe jazyka ActionScript 2.0 a vysvětluje způsob použití jazyka
ActionScript 2.0 při práci s různými typy objektů
ActionScript 2.0 Language Reference
Uvádí syntaxi, použití a příklady kódu pro komponenty vývojového nástroje Flash
a rozhraní API jazyka ActionScript 2.0
Používání součástí jazyka ActionScript 2.0
Podrobně vysvětluje způsob použití součástí jazyka ActionScript 2.pro vývoj
aplikací vytvořených nástrojem Flash
Reference součástí jazyka ActionScript 2.0
Popisuje každou součást dostupnou v architektuře součástí Adobe, verze 2,
společně s programovacím rozhraním API
Rozšíření programu Flash
Popisuje objekty, metody a vlastnosti dostupné v rozhraní API jazyka JavaScript
Začínáme s aplikací Flash Lite 2.x
Vysvětluje způsob použití aplikace Adobe® Flash® Lite™ 2.x pro vývoj aplikací a
popisuje syntaxi, použití a uvádí příklady kódu vlastností jazyka ActionScript,
které jsou dostupní v Flash Lite 2.x
Vývoj aplikací Adobe Flash Lite 2.x
Vysvětluje způsob vývoje aplikací Flash Lite 2.x
Úvod do Flash Lite 2.x ActionScript
Uvádí způsob vývoje aplikací s pomocí Flash Lite 2.x a popisuje všechny funkce
ActionScript dostupné pro vývojáře Flash Lite 2.x
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 3
O této příručce
Kniha
Popis
Referenční příručka jazyka ActionScript pro Adobe Flash Lite Popisuje syntaxi, použití a uvádí příklady kódu rozhraní API jazyka ActionScript
2.x
2.0, které jsou k dispozici v Flash Lite 2.x
Začínáme s aplikací Flash Lite 1.x
Uvádí aplikaci Flash Lite 1.x a popisuje, jak testovat obsah pomocí emulátoru
aplikace Adobe® Device Central CS4
Vývoj aplikací Adobe Flash Lite 1.x
Popisuje způsob vývoje aplikací pro mobilní zařízení pomocí aplikace Flash Lite
1.x
Učíme se jazyk ActionScript v aplikaci Flash Lite 1.x
Vysvětluje způsob použití jazyka ActionScript v aplikaci Flash Lite 1.x a popisuje
všechny funkce jazyka ActionScript dostupné v aplikaci Flash Lite 1.x
Referenční příručka jazyka ActionScript pro Adobe Flash Lite Popisuje syntaxi a použití prvků jazyka ActionScript, které jsou dostupné v aplikaci
1.x
Flash Lite 1.x
Zdroje pro vzdělávání v jazyce ActionScript
Kromě obsahu uvedeného v těchto příručkách poskytuje společnost Adobe pravidelně aktualizované články, nápady
pro vývoj a příklad prostřednictvím vývojového centra Adobe Developer Center a návrhářského centra Adobe Design
Center.
Adobe Developer Center
Vývojové centrum Adobe Developer Center je zdrojem nejnovějších informací o jazyce ActionScript, článků o
vyvinutých aplikacích z reálného světa a informací o důležitých objevujících se problémech. Vývojové centrum Adobe
Developer Center naleznete na adrese www.adobe.com/devnet/.
Adobe Design Center
Nejnovější novinky z digitálního designu a filmové grafiky. Můžete procházet díly předních umělců, objevovat nové
trendy designu a zdokonalovat své dovednosti pomocí výukových programů, klíčových pracovních kroků a
pokročilých technik. Dvakrát měsíčně si můžete prohlédnout nejnovější výukové programy a články a inspirující
exponáty galerií. Návrhářské centrum Adobe Design Center naleznete na adrese www.adobe.com/designcenter/.
4
Kapitola 2: Úvodní informace k jazyku
ActionScript 3.0
Tato kapitola poskytuje přehled produktu Adobe®ActionScript® 3.0, nejnovější a nejrevolučnější verze jazyka
ActionScript.
O ActionScriptu
ActionScript je programovací jazyk pro prostředí přehrávače Adobe® Flash® Player a programu Adobe® AIR™ v době
běhu. Umožňuje interakce, zpracovávání dat a další možnosti v obsahu a v aplikacích Flash, Flex a AIR.
Jazyk ActionScript je prováděn pomocí aplikace ActionScript Virtual Machine (AVM), která je součástí přehrávače
Flash Player a programu AIR. Kód jazyka ActionScript je obvykle kompilován do formátu bytového kódu (druh
programovacího jazyka, který je zapsán a chápán počítači) kompilátorem, například kompilátorem, který je součástí
produktu Adobe® Flash® CS4 Professional nebo Adobe® Flex™ Builder™, nebo který je dostupný v sadě SDK Adobe®
Flex™. Bytový kód je vnořen do souborů SWF, které jsou spouštěny přehrávačem Flash Player a programem AIR.
Jazyk ActionScript 3.0 nabízí stabilní programovací model, který dobře znají vývojáři se základní znalostí objektově
orientovaného programování. Některé z klíčových funkcí jazyka ActionScript 3.0, které vylepšují předchozí verze
jazyka ActionScript, zahrnují následující:
• Nový nástroj ActionScript Virtual Machine nazvaný AVM2, který používá novou sadu pokynů bytového kódu a
nabízí o mnoho lepší výkon
• Modernější základ pro kód kompilátoru, který provede hlubší optimalizaci než předcházející verze kompilátoru
• Rozšířené a vylepšené programovací rozhraní aplikace (API) s nízkoúrovňovým ovládáním objektů a správným na
objekt orientovaným modelem
• Rozhraní API XML založené na ECMAScript pro specifikaci XML (E4X) (ECMA-357 vydání 2). E4X je rozšíření
jazyka pro ECMAScript, které přidává XML jako nativní datový typ jazyka.
• Model události založený na specifikaci událostí na úrovni 3 modelu objektu dokumentu (DOM)
Výhody jazyka ActionScript 3.0
Jazyk ActionScript 3.0 předčí skriptovací schopnosti předcházejících verzí jazyka ActionScript. Jeho účelem je
umožnit vytváření vysoce komplexních aplikací s velkými sadami dat a na objekt orientovanými, opětovně
použitelnými základnami kódů. Zatímco jazyk ActionScript 3.0 není vyžadován pro obsah, který je spuštěn v
přehrávači Adobe Flash Player, umožňuje vylepšení výkonu, které je k dispozici pouze v případě AVM2, nového
virtuálního zařízení. Kód v jazyce ActionScript 3.0 umí provádět operace až desetkrát rychleji než kód v dřívějších
verzích jazyka ActionScript.
Starší verze ActionScript Virtual Machine, AVM1, pracuje s kódem v jazyce ActionScript 1.0 a ActionScript 2.0.
AVM1 je podporován přehrávačem Flash Player 9 a 10 pro zpětnou kompatibilitu se stávajícím obsahem i obsahem z
předcházejících verzí. Více informací naleznete v části „Kompatibilita s předchozími verzemi“ na stránce 7.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 5
Úvodní informace k jazyku ActionScript 3.0
Co je nového v jazyce ActionScript 3.0
Ačkoliv jazyk ActionScript 3.0 obsahuje mnoho tříd a funkcí, které budou pro programátory jazyka ActionScript
známé, jazyk ActionScript 3.0 je architektonicky a koncepčně odlišný od předcházejících verzí ActionScript. Vylepšení
v jazyce ActionScript 3.0 zahrnují nové funkce základního jazyka a vylepšené rozhraní API přehrávače Flash Player,
které poskytuje lepší kontrolu objektů na nižších úrovních.
Poznámka: Aplikace produktu Adobe® AIR™ mohou také použít rozhraní API přehrávače Flash Player.
Základní jazykové prvky
Základní jazyk definuje základní stavební bloky programovacího jazyka, například příkazy, výrazy, podmínky,
opakování a typy. Jazyk ActionScript 3.0 obsahuje mnoho nových funkcí, které urychlují proces vývoje.
Výjimky v době běhu
Jazyk ActionScript 3.0 hlásí více stavů chyb než předcházející verze jazyka ActionScript. Výjimky v době běhu jsou
použity pro běžné stavy chyb, vylepšují zkušenosti s laděním a umožňují vám vyvinout aplikace, které účinně
zpracovávají chyby. Chyby v době běhu mohou poskytnout sledování zásobníku, které je anotováno se zdrojovým
souborem a informací a počtu řádků. Tím vám umožňují rychlé a přesné určení chyb.
Typy v době běhu
V jazyce ActionScript 2.0 byly anotace určeny primárně pro pomoc vývojářům; v době běhu byly všechny hodnoty
dynamicky typovány. V jazyce ActionScript 3.0 je informace typu v době běhu zachována a použita k několika účelům.
Runtime přehrávače Flash Player a programu Adobe AIR provádějí kontrolu typu v době běhu a vylepšují tak
zabezpečení typu systému. Informace o typu se také používá pro znázornění proměnných v nativních reprezentacích
počítače, vylepšování výkonu a snižování využití paměti.
Uzavřené třídy
Jazyk ActionScript 3.0 zavádí koncept uzavřených tříd. Uzavřená třída má pouze fixní sadu vlastností a metod, které
byly definovány v době běhu; další vlastnosti a metody přidat nelze. To umožňuje přísnější kontrolu v době kompilace,
která přinese stabilnější programy. Vylepšuje také využití paměti tím, že nevyžaduje pro každou instanci objektu
interní tabulku křížku. Dynamické třídy jsou také přístupné pomocí klíčového slova dynamic. Všechny třídy v definici
jazyka ActionScript 3.0 jsou implicitně uzavřeny, ale lze je deklarovat tak, aby byly dynamické, a to s klíčovým slovem
dynamic.
Uzavření metody:
Jazyk ActionScript 3.0 umožňuje uzavření metody pro automatické zapamatování si původní instance objektu. Tato
funkce je užitečná pro zpracovávání událostí. V jazyce ActionScript 2.0 by si uzavření metody nepamatovala, z jaké
instance objektu byla vyjmuta, což by vedlo k nečekanému chování při iniciaci uzavření metody. Třída
mx.utils.Delegate byla oblíbením způsobem obejití tohoto problému, ale již není potřeba.
ECMAScript pro XML (E4X)
Jazyk ActionScript 3.0 implementuje ECMAScript pro XML (E4X), nedávno standardizovaný jako ECMA-357. E4X
nabízí přirozenou plynulou sadu jazykových konstruktů pro manipulaci s XML. Oproti tradiční analýze XML rozhraní
API má XML s E4X funkce stejné jako nativní datový typ jazyka. E4X urychluje vývoj aplikací, které manipulují s XML,
a to značným snížením potřebného množství kódu. Více informací o implementaci jazyka ActionScript 3.0 E4X
naleznete v části „Práce s jazykem XML“ na stránce 222.
Pro zobrazení specifikace E4X ECMA přejděte na www.ecma-international.org.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 6
Úvodní informace k jazyku ActionScript 3.0
Regulární výrazy
Jazyk ActionScript 3.0 zahrnuje nativní podporu pro regulární výrazy, takže můžete rychle vyhledávat řetězce a
manipulovat s nimi. Jazyk ActionScript 3.0 implementuje podporu pro regulární výrazy dle jejich definice ve
specifikaci jazyka ECMAScript (ECMA-262), 3. vydání.
Jmenné prostory
Jmenné prostory se podobají tradičním specifikátorům přístupu používaným pro ovládání viditelnosti deklarací
(public, private, protected). Pracují jako vlastní specifikátory přístupu, které můžete pojmenovat dle svého
výběru. Pro zabránění kolizím jsou jmenné prostory vybaveny identifikátorem Universal Resource Identifier (URI) a
jsou také používány pro reprezentaci jmenných prostorů XML při práci s E4X.
Nové primitivní typy
Jazyk ActionScript 2.0 má jediný numerický typ, číslo, dvojitou přesnost a číslo s plovoucí čárkou. Jazyk ActionScript
3.0 obsahuje typy int a uint. Typ int je 32-bitové celé číslo se znaménkem, které umožňuje kódu jazyka ActionScript
využít výhody rychlých matematických schopností celého čísla CPU. Typ int je užitečný pro čítače opakování a
proměnné tam, kde jsou použita celá čísla. Typ uint je typ 32-bytového celého čísla bez znaménka, který je užitečný
pro barevné hodnoty RGB, počty bytů, atd.
Funkce rozhraní API přehrávače Flash Player
Rozhraní přehrávače Flash Player API v jazyku ActionScript 3.0 obsahují mnoho tříd, které vám umožňují ovládat
objekty na nízké úrovni. Architektura jazyka je navržena tak, aby byla intuitivnější než předchozí verze. Protože zde
existuje příliš mnoho nových tříd, aby jsme se jim věnovali podrobně, zdůrazníme v následujících částech některé
významné změny.
Poznámka: Aplikace produktu Adobe® AIR™ mohou také použít rozhraní API přehrávače Flash Player.
Model události DOM3
Model události Document Object Model Level 3 (DOM3) nabízí standardní způsob generování a zpracovávání hlášení
událostí, takže objekty v rámci aplikací mohou navzájem reagovat a komunikovat, zachovají si svůj statut a budou
reagovat na změny. Protože je tento model vytvořený dle Specifikací událostí konsorcia www (World Wide Web
Consortium DOM Level 3 Events Specification), poskytuje jasnější a účinnější mechanismus než systémy událostí
dostupné v předchozích verzích jazyka ActionScript.
Události a události chyb jsou umístěny v balíku flash.events. Rámec komponent programu Flash používá stejný model
událostí jako rozhraní přehrávače Flash Player API, takže je systém událostí na celé platformě Flash jednotný.
Rozhraní API seznamu zobrazení
Rozhraní API pro získání přístupu k seznamu zobrazení přehrávače Flash Player a programu Adobe API - stromová
struktura, která obsahuje jakékoliv vizuální elementy v aplikaci - se skládá z tříd pro práci se základními vizuálními
tvary.
Nová třída Sprite je lehkým stavebním prvkem a podobá se třídě MovieClip, ale je vhodnější jako základní třída pro
komponenty UI. Nová třída Shape představuje prosté vektorové tvary. Tyto třídy lze přirozeně konkretizovat pomocí
operátoru new a lze je kdykoliv dynamicky znovu přiřadit jako nadřazené.
Ovládání hloubky je nyní automatické a vestavěné do přehrávače Flash Player a programu Adobe AIR. Přiřazení čísel
hloubky během vykreslování již není nutné. Pro určení a ovládání z-pořadí objektů jsou k dispozici nové metody.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 7
Úvodní informace k jazyku ActionScript 3.0
Zpracovávání dynamických dat a obsahu
Jazyk ActionScript 3.0 obsahuje mechanismy pro načítání a zpracovávání datových zdrojů a dat ve vaší aplikaci, které
jsou intuitivní a ve všech rozhraních API stejné. Nová třída Loader poskytuje jediný mechanismus pro načítání
souborů SWF a datových zdrojů obrazů a nabízí způsob získání přístupu k podrobným informacím o načteném
obsahu. Třída URLLoaderposkytuje samostatný mechanismus pro načítání textu a binárních dat v aplikacích
zaměřených na data. Třída Socket poskytuje způsob načtení a zapsání binárních dat na servery soketů, a to v
jakémkoliv formátu.
Přístup k datům na nízké úrovni
Různá rozhraní API poskytují přístup nízké úrovně k datům, který v jazyce ActionScript nikdy před tím dostupný
nebyl. Pro načítaná data poskytuje třída URLStream, která je implementována URLLoader, při načítání přístup k
datům jako k prvotním binárním datům. Třída ByteArray vám umožňuje optimalizovat čtení, zapisování a práci s
binárními daty. Nové rozhraní API Sound poskytuje podrobné ovládání zvuku pomocí tříd SoundChannel a
SoundMixer. Nová rozhraní API zabývající se zabezpečením poskytují informace o právech zabezpečení souboru SWF
nebo načteného obsahu, a umožňují vám tak lepší zpracování chyb zabezpečení.
Práce s textem
Jazyk ActionScript 3.0 obsahuje balík flash.text pro všechna rozhraní API související s textem. Třída TextLineMetrics
poskytuje podrobnou metriku pro řádek textu v rámci textového pole; nahrazuje metodu
TextFormat.getTextExtent() v jazyce ActionScript 2.0. Třída TextField obsahuje několik zajímavých nových
metod nízké úrovně, které mohou poskytnout specifické informace o řádku textu nebo jednotlivém znaku v textovém
poli. Mezi tyto metody patří getCharBoundaries(), která vrátí obdélník představující ohraničovací rámeček znaku,
getCharIndexAtPoint(), která vrátí index znaku v určitém bodě a getFirstCharInParagraph(), která vrátí index
prvního znaku v odstavci. Mezi metody na úrovni řádku patří getLineLength(), která vrátí počet znaků na určitém
řádku textu, a getLineText(), která vrátí text určeného řádku. Nová třída Font poskytuje způsob ovládání vnořených
písem v souborech SWF.
Kompatibilita s předchozími verzemi
Přehrávač Flash Player jako vždy poskytuje plnou zpětnou kompatibilitu s předchozím publikovaným obsahem.
Jakýkoliv obsah, který mohl být spuštěn v předchozích verzích přehrávače Flash Player, lze spustit i v přehrávači Flash
Player verze 9 a pozdější. Úvod k jazyku ActionScript 3.0 v přehrávači Flash Player 9 nicméně uvádí některé problémy
týkající se vzájemné spolupráce mezi starým a novým obsahem spuštěným v přehrávači Flash Player 9 nebo pozdější.
Mezi problémy se slučitelností patří:
• Jediný soubor SWF nemůže kombinovat kód jazyka ActionScript 1.0 nebo 2.0 s kódem jazyka ActionScript 3.0.
• Kód jazyka ActionScript 3.0 může načíst soubor SWF zapsaný v jazyce ActionScript 1.0 nebo 2.0, ale nemůže získat
přístup k proměnným a funkcím daného souboru SWF.
• Soubory SWF zapsané v jazyce ActionScript 1.0 nebo 2.0 nemohou načíst soubory SWF zapsané v jazyce
ActionScript 3.0. To znamená, že soubory SWF vytvořené v programu Flash 8 nebo Flex Builder verze 1.5 nebo
starší nemohou načíst soubory SWF jazyka ActionScript 3.0 SWF.
Jedinou výjimkou tohoto pravidla je, že soubor SWF jazyka 2.0 SWF může nahradit sám sebe souborem SWF
jazyka ActionScript 3.0, pokud soubor SWF jazyka ActionScript 2.0 dříve nenačetl nic na žádnou ze svých úrovní.
Soubor SWF jazyka ActionScript 2.0 může tento postup provést voláním loadMovieNum() a předáním hodnoty 0
parametru level.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 8
Úvodní informace k jazyku ActionScript 3.0
• Obecně musí být soubory zapsané v jazyce ActionScript 1.0 nebo 2.0 migrovány, jestliže mají spolupracovat se
soubory SWF zapsanými v jazyce ActionScript 3.0. Představte si například, že jste pomocí jazyka ActionScript 2.0
vytvořili přehrávač médií. Tento přehrávač médií načítá různý obsah, který byl také vytvořen pomocí jazyka
ActionScript 2.0. Nemůžete vytvořit nový obsah v jazyce ActionScript 3.0 a načíst jej do daného přehrávače médií.
Musíte daný přehrávač migrovat do jazyka ActionScript 3.0.
Jestliže ale přehrávač vytvoříte v jazyce ActionScript 3.0, může daný přehrávač médií provést jednoduché načtení
obsahu jazyka ActionScript 2.0.
Následující tabulka uvádí souhrn omezení předchozích verzí přehrávače Flash Player ve vztahu k načítání nového
obsahu a spouštění kódu, i omezení křížového skriptu mezi soubory SWF zaspanými v různých verzích jazyka
ActionScript.
Podporované funkce
Flash Player 7
Flash Player 8
Flash Player 9 a 10
Načíst můžete soubory SWF publikované
pro
verzi 7 a starší
verzi 8 a starší
9 (nebo 10) a dřívější
Obsahuje tento AVM
AVM1
AVM1
AVM1 a AVM2
Spustí soubory SWF zapsané v jazyce
ActionScript
1.0 a 2.0
1.0 a 2.0
1.0 a 2.0 a 3.0
V následující tabulce se pojem „Podporované funkce“ vztahuje na obsah spuštěný v přehrávači Flash Player verze 9
nebo starší. Obsah spuštěný v přehrávači Flash Player verze 8 nebo starší lze načíst, zobrazit, spustit a křížově
skriptovat pouze v jazyku ActionScript 1.0 a 2.0.
Podporované funkce
Obsah vytvořený v jazyce ActionScript 1.0 Obsah vytvořený v jazyce ActionScript 3.0
a 2.0
Může načíst obsah a spustit kód vytvořený
pouze v jazyce ActionScript 1.0 a 2.0
v jazyce ActionScript 1.0 a 2.0 jazyce
ActionScript 3.0
Může křížit obsah skriptu vytvořený
pouze v jazyce ActionScript 1.0 a 2.0
(ActionScript 3.0 pouze pomocí místního
připojení)
v jazyce ActionScript 1.0 a 2.0 pomocí
LocalConnection.
ActionScript 3.0
9
Kapitola 3: Začínáme s ActionScriptem
Tato kapitola je navržena tak, aby vám pomohla začít s programováním v jazyce ActionScript a poskytla vám základní
informace nutné k porozumění konceptům a příkladům ve zbývající části této příručky. Začneme diskusí o základních
konceptech programování, popsaných v kontextu jejich aplikování v jazyce ActionScript. Rovněž se podíváme na
základy organizování a vytváření aplikací v jazyce ActionScript.
Základy programování
Protože ActionScript je programovací jazyk, bude při jeho studiu nejprve porozumět několika obecným konceptům
počítačového programování.
Co dělají počítačové programy
Nejprve je vhodné koncepčně porozumět tomu, co počítačový program je a co má za úkol. Existují dva hlavní aspekty
počítačového programu:
• Program je sledem instrukcí nebo kroků, které má počítač provádět.
• Každý krok znamená zpracování části informace nebo dat.
V obecném smyslu je počítačový pouze seznamem posloupností instrukcí, které předáváme počítači, aby je jednu za
druhou provedl. Každá jednotlivá instrukce se nazývá příkaz. Jak v této příručce dále uvidíte, v jazyce ActionScript je
každý příkaz zapsán na konci se středníkem.
V podstatě všechny instrukce uvedené v programu zpracovávají kus dat, který je uložen v paměti počítače. V
jednoduchém případě můžete počítači vydat příkaz sečíst dvě čísla a uložit výsledek do paměti. Ve složitějších
případech si představte, že existuje obdélník vykreslený na obrazovce a vy chcete napsat program, který jej přesune
jinam na obrazovce. Počítač sleduje jisté informace o obdélníku - souřadnice X, Y umístění, jeho šířku a výšku, barvu
atd. Každý takový kus informace je uložen kdesi v paměti počítače. Program pro přesunutí obdélníku do jiného
umístění bude mít kroky, jako například „změnit souřadnici X na 200; změnit souřadnici Y na 150“ (jinými slovy,
specifikování nových hodnot použitých pro souřadnice X a Y). Samozřejmě, že počítač s těmito daty cosi učiní, aby
čísla přetvořil v obrázek, který se zobrazí na obrazovce počítače; ale v rámci podrobností, které nás zajímají, postačuje
znát, že proces „přesouvání obdélníku na obrazovce“ pouze zahrnuje změny kusů dat v počítačové paměti.
Proměnné a konstanty
Protože programování převážně zahrnuje změnu kusů informace v paměti počítače, existuje potřeba vyjadřování kusů
informací v programu. Proměnná je název vyjadřující hodnotu v paměti počítače. Když zapisujete příkaz pro
zpracování hodnot, zapisujete název proměnné namísto hodnoty; kdykoliv počítač vidí v programu název proměnné,
prohledá paměť a použije hodnotu, kterou zde nalezne. Například pokud máte dvě proměnné pojmenované value1 a
value2 a každá obsahuje číslo, pro sečtené těchto dvou čísel můžete zapsat příkaz:
value1 + value2
Při provádění těchto kroků počítač vyhledá hodnoty každé proměnné a poté je sečte.
V jazyce ActionScript 3.0 je proměnná tvořena třemi různými součástmi:
• Název proměnné
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 10
Začínáme s ActionScriptem
• Typ dat, které lze do proměnné uložit
• Skutečná hodnota uložená v paměti počítače
Právě jsme popsali, jak počítač používá název jako vyhrazené místo pro hodnotu. Typ dat je také důležitý. Když v
jazyce ActionScript vytvoříte proměnnou, zadáváte specifický typ dat, které bude uchovávat; poté mohou instrukce
programu uložit pouze typ dat v proměnné a můžete zpracovat hodnotu pomocí specifické charakteristiky související
s příslušným datovým typem. V jazyce ActionScript vytváříte proměnnou (nazývá se to deklarování proměnné)
pomocí příkazu var:
var value1:Number;
V tomto případě sdělujeme počítači, aby vytvořit proměnnou pojmenovanou value1, která uchová pouze číselná data
(„číslo“ je specifický datový typ definovaný v jazyce ActionScript). Hodnotu můžete také uložit přímo do proměnné:
var value2:Number = 17;
V aplikaci Adobe Flash CS4 Professional existuje jiný způsob, jak deklarovat proměnnou. Když umístíte symbol
filmového klipu, symbol tlačítka nebo textové pole na plochu, můžete jej pojmenovat názvem instance v Inspektoru
vlastností. Na pozadí aplikace Flash vytvoří proměnnou se stejným názvem, jaký má instance, který můžete použít v
kódu ActionScript k odkazování na položku plochy. Takže pokud máte například symbol filmového klipu na ploše a
pojmenujete jej názvem instance rocketShipkdykoliv použijete proměnnou rocketShip v kódu jazyka ActionScript,
budete ve skutečnosti zpracovávat daný filmová klip.
Konstanta je velmi podobná proměnné v tom smysli, že její název zastupuje v paměti počítače hodnotu se stanoveným
datovým typem. Rozdíl je v tom, že konstanta může mít přiřazenou hodnotu pouze v průběhu aplikace jazyka
ActionScript. Jakmile je hodnota konstanty přiřazena, je stejná v celé aplikaci. Syntaxe pro deklarování konstanty je
shodná jako pro deklarování proměnné, kromě toho, že použijete klíčové slovo const místo slova var:
const SALES_TAX_RATE:Number = 0.07;
Konstanta je užitečná pro definování hodnoty, která se používá na několika místech projektu, které se za normálních
okolností nebudou měnit. Použitím konstanty namísto použití hodnoty literálu bude váš kód čitelnější. Například je
snazší porozumět smyslu řádky kódu, který násobí cenu hodnotou SALES_TAX_RATE, ve srovnání s řádkem kódu,
který násobí cenu hodnotou 0.07. Kromě toho, musí-li se hodnota definovaná konstantou někdy změnit, pokud
použijete konstantu k vyjádření dané hodnoty v celém projektu, musíte pouze změnit hodnotu na jednom místě
(deklarace konstanty), nemusíte ji tedy měnit na různých místech, jako by tomu bylo u pevně stanovených literálových
hodnot.
Typy dat
V jazyce ActionScript existuje mnoho datových typů, které můžete použít jako datový typ vytvářené proměnné.
Některé z těchto typů můžete považovat za „jednoduché“ nebo „základní“ datové typy:
• String (řetězec): textová hodnota, například název nebo text kapitoly knihy
• Numeric (číselný typ): jazyk ActionScript 3.0 zahrnuje tři specifické datové typy pro číselná data:
• Number (číslo): kterákoliv číselná hodnota, zahrnující hodnoty se zlomkem nebo bez něj
• int: celočíselná hodnota (celé číslo bez zlomku)
• uint: celočíselná hodnota bez znaménka, což znamená, že celé číslo nemůže být záporné
• Boolean (booleovská hodnota): logická hodnota PRAVDA nebo NEPRAVDA, například jako přepínač, který může
být zapnutý nebo vypnutá, nebo zad se dvě hodnoty rovnají či nikoliv
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 11
Začínáme s ActionScriptem
Jednoduché datové typy představují jednotlivý kus informací: například jedno číslo nebo jednu posloupnost textu.
Většina datových typů definovaných v jazyce ActionScript by mohla být popsána jako komplexní datové typy, protože
představují soubor seskupených hodnot. Například proměnná s datovým typem Date představuje jednu hodnotu časový okamžik. Datová hodnota je však zastoupena jako několik hodnot - den, měsíc, rok, hodina, minuta, sekunda
atd., všechny ty jsou jednotlivými čísly. Takže když uvažujeme o datu jako o jednotlivé hodnotě (a můžeme jej
zpracovat jako jednotlivou hodnotu vytvořením proměnné Date), vnitřně o něm počítač uvažuje jako o několika
seskupených hodnotách, definujících jediné datum.
Většina z vestavěných datových typů a také datových typů definovaných programátory, jsou komplexní datové typy.
Některé komplexní datové typy jsou následující:
• MovieClip: symbol filmového klipu
• TextField: dynamické nebo vstupní textové pole
• SimpleButton: symbol tlačítka
• Date: informace o jednotlivém okamžiku v čase (datum a čas)
Dvě slova, která jsou často používána jako synonymum pro datový typ, jsou třída a objekt. Třída je jednoduše definicí
datového typu - je to jako šablona všech objektů datového typu, jako bychom tvrdili „všechny proměnné datového
typu Example mají tyto vlastnosti: A, B a C.“ Object je na druhou stranu pouze stávající instancí třídy; proměnnou, jejíž
datový typ je MovieClip, je možné popsat jako objekt MovieClip. Níže jsou uvedeny různé způsoby, jak vyjádřit
stejnou věc:
• Datový typ proměnné myVariable je Number.
• Proměnná myVariable je instancí Number.
• Proměnná myVariable je objektem Number.
• Proměnná myVariable je instancí třídy Number.
Práce s objekty
Jazyk ActionScript znám jako objektově orientovaný programovací jazyk. Objektově orientované programování je
jednoduše přístup k programování - nic více, než způsob organizování kódu v programu pomocí objektů.
Dříve jsme definovali počítačový program jako soubor kroků nebo instrukcí, které počítač provádí. Koncepčně je pak
možné si představit počítačový program jako jeden dlouhý seznam instrukcí. U objektově orientovaného
programování jsou však instrukce programu rozděleny mezi různé objekty - kód je seskupen do kusů funkcí, takže
související typy funkcí nebo související kusy informace jsou seskupeny dohromady v jednom kontejneru.
Pokud jste v aplikaci Flash pracovali se symboly, již jste pracovali s objekty. Představte si, že jste definovali symbol
filmového klipu - vykreslení obdélníku - a umístili jste jeho kopii na plochu. Tento symbol filmového klipu je (doslova)
objektem v jazyce ActionScript, instancí třídy MovieClip.
Existují různé charakteristiky filmového klipu, které můžete změnit. Například když jej vyberete, existují zde hodnoty,
které můžete změnit v Inspektoru vlastností, například souřadnici X, nebo šířku či různá nastavení barvy, například
změnit hodnotu alfa (průhlednost), nebo aplikování filtru vrženého stínu. Jiné nástroje aplikace Flash umožní
provádět více změn, například používání nástroje Volná transformace k otočení obdélníku. Všechny tyto věci, které
můžete provádět pro modifikování symbolu filmového klipu ve vývojovém prostředí Flash jsou také věci, které můžete
provádět v jazyce ActionScript změnou kusů dat, které jsou složeny k sobě do jednoho svazku nazvaného objekt
MovieClip.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 12
Začínáme s ActionScriptem
V objektově orientovaném programování v jazyce ActionScript existují tři typy charakteristiky, které může obsahovat
kterákoliv třída.
• Vlastnosti
• Metody
• Události
Společně jsou tyto prvky použity pro správu kusů dat použitých programem a pro rozhodování o tom, které činnosti
jsou provedeny a v jakém pořadí.
Vlastnosti
Vlastnost představuje jeden z kusů dat, které jsou seskupené dohromady do objektu. Objekt song může mít vlastnosti
pojmenované artist a title; třída MovieClip má vlastnosti rotation, x, width a alpha. S vlastnostmi pracujete
jako s jednotlivými proměnnými - ve skutečnosti na vlastnosti můžete pohlížet jako na „podřízenou“ proměnnou
obsaženou v objektu.
Zde jsou některé příklady kódu jazyka ActionScript využívajícího vlastnosti. Tento řádek kódu pohybuje klipem
MovieClip pojmenovaným square do souřadnice X o 100 obrazových bodů:
square.x = 100;
Tento kód používá vlastnost rotation k otočení MovieClip square tak, aby to odpovídalo otočení MovieClip
triangle:
square.rotation = triangle.rotation;
Tento kód mění horizontální stupnici třídy MovieClip square tak, aby byla 1,5krát větší než předtím:
square.scaleX = 1.5;
Povšimněte si společné struktury: používáte proměnnou (square, triangle) jako název objektu, následuje tečka (.)
a pak název vlastnosti (x, rotation, scaleX). Tečka, které se říká operátor dot, se používá k označení přístupu k
jednomu z podřízených prvků objektu. Celá struktura společně, „název proměnné-tečka-název vlastnosti“ se používá
jako jedna proměnná, jako název jedné hodnoty v paměti počítače.
Metody
Metoda je činností, kterou může provádět objekt. Například pokud vytvoříte v aplikaci Flash symbol filmového klipu
několika klíčovými snímky a animaci v časové ose, tento filmový klip lze přehrát, zastavit nebo přesunou na specifický
snímek.
Tento kód vydává instrukci klipu MovieClip pojmenovanému shortFilm, aby se začal přehrávat:
shortFilm.play();
Tato řádka způsobí zastavení klipu MovieClip pojmenovaného shortFilm (přehrávací hlava se zastaví na místě, jako
při pozastavení videa):
shortFilm.stop();
Tento kód vydává instrukci klipu MovieClip pojmenovanému shortFilm přesunout přehrávací hlavu na snímek
Frame 1 a zastavit přehrávání (jako při převíjení videa):
shortFilm.gotoAndStop(1);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 13
Začínáme s ActionScriptem
Jak můžete vidět, metody, podobně jako vlastnosti, jsou přístupné zapsáním názvu objektu (proměnné), pak tečky, pak
názvu metody následované závorkami. Závory jsou způsobem, jak naznačit, že voláte metodu - jinými slovy vydává
objektu instrukci provést danou činnost. Někdy jsou hodnoty (či proměnné) umístěny do závorek, což je způsob
předání dalších informace, které jsou nutné k provedení činnosti. Tyto hodnoty jsou známy jako parametry metody.
Například metoda gotoAndStop() musí znát snímek na který má přejít, takže vyžaduje v závorce jeden parametr. Jiné
metody, jako play() a stop(), jsou zřejmé a nevyžadují další informace. Nicméně jsou i přesto psány se závorkami.
Na rozdíl od vlastností (a proměnných) nejsou metody použity jako vyhrazená místa pro hodnotu. Některé metody
však mohou provádět výpočty a vracet výsledky, které lze použít jako proměnnou. Například metoda toString()
třídy Number převádí číselnou hodnotu na textové vyjádření.
var numericData:Number = 9;
var textData:String = numericData.toString();
Například můžete použít metodu toString() v případě, že chcete zobrazit hodnotu proměnné Number v textovém
poli na obrazovce. Vlastnost text třídy TextField (představující skutečný obsah textu zobrazený na obrazovce) je
definován jako String, takže může obsahovat pouze textové hodnoty. Tento řádek kódu převádí číselnou hodnotu v
proměnné numericData na text a pak jej zobrazí na obrazovce v objektu TextField pojmenovaném
calculatorDisplay:
calculatorDisplay.text = numericData.toString();
Události
Popsali jsme počítačový program jako řadu instrukcí, které počítač vykonává krok za krokem. Některé jednoduché
počítačové programy nejsou tvořeny ničím jiným - několika kroky, které počítač provede a poté se ukončí. Programy
v jazyce ActionScript jsou však navrženy tak, aby se uchovaly v chodu, vyčkaly na vstup uživatele nebo jinou událost.
Události jsou mechanismy jež stanoví, které instrukce počítač provede a kdy.
V podstatě jsou události věci, které nastávají, kterých si je jazyk ActionScript vědom a může na ně reagovat. Mnoho
událostí souvisí s interakcí uživatele - klepnutí na tlačítko, stisknutí kláves - ale existují také jiné typy událostí. Pokud
například použijete jazyk ActionScript k načtení externího obrázku, existuje události, která vás vyrozumí, když
načítání obrázku skončí. Když program jazyka ActionScript pracuje, aplikace Adobe Flash Player a Adobe AIR pouze
vyčkají na to, než nastanou některé události, a když k nim dojde, spustí specifický kód jazyka ActionScript, který jste
pro tyto události stanovili.
Základní zpracování událostí
Technika specifikování jistých činností, které by měly být provedeny v odezvě na specifické události, je známá jako
zpracování událostí. Když zapisujete kód v jazyce ActionScript k provedení zpracování události, existují tři důležité
prvky, které musíte identifikovat:
• Zdroj události: který objekt je ten, jemuž se událost přihodí? Například na které tlačítko bude klepnuto, nebo který
objekt Loader bude načítat obrázek? Zdroj události se také nazývá cíl události, protože se jedná o objekt, kde je
událost cílena aplikací Flash Player nebo AIR (tj. kde k události ve skutečnosti dochází).
• Událost: co je to za věc, která se stane, věc, na kterou chcete reagovat? To je důležité identifikovat, protože mnoho
objektů spouští několik událostí.
• Odezva: jaké kroky chcete provádět když k události dojde?
Vždy když zapisujete kód ActionScript pro zpracování událostí, bude zahrnovat tyto tři prvky a kód bude dodržovat
základní strukturu (prvky napsané tučně jsou vyhrazená místa, která pro specifický případ vyplníte):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 14
Začínáme s ActionScriptem
function eventResponse(eventObject:EventType):void
{
// Actions performed in response to the event go here.
}
eventSource.addEventListener(EventType.EVENT_NAME, eventResponse);
Tento kód provádí dvě věci. Nejprve definuje funkci, která je způsobem specifikace činností, které budou provedeny
v odezvě na událost. Dále je zavolána metoda addEventListener() zdrojového objektu, v podstatě “odběr”
specifikované události funkcí tak, že když k události dojde, jsou provedeny činnosti funkce. Každou z těchto částí
popíšeme podrobněji.
Funkce poskytuje způsob, kterým můžete seskupit činnosti dohromady, s jedním názvem, který je jako název zástupce
k provedené činností. Funkce je shodná s metodou, kromě toho, že nemusí být nutně spojena se specifickou třídou (ve
skutečnosti může být metoda definována jako funkce, která souvisí se specifickou třídou). Když vytváříte funkci pro
zpracování událostí, musíte vybrat název této funkce (v tomto případě je pojmenovaná eventResponse). Musíte také
specifikovat jeden parametr (v tomto případě je pojmenovaný eventObject). Specifikování parametru funkce je jako
deklarování proměnné, takže musíte také uvést datový typ parametru. (V tomto příkladu je datový typ parametru
EventType.)
Každý typ události, které chcete naslouchat, má připojenou třídu jazyka ActionScript. Specifikovaný datový typ pro
parametr funkce je vždy přidruženou třídou specifické události, na kterou chcete reagovat. Například událost click
(spustí se, když uživatel klepne na položku myší) je připojena k třídě MouseEvent. Chcete-li zapsat funkci posluchače
pro událost click, definuje funkci posluchače s parametrem datového typu MouseEvent. Nakonec mezi levou a
pravou složenou závorkou ({ ... }) zapište instrukce, které má počítač provést.
Jakmile zapíšete funkci pro manipulaci s událostí, musíte sdělit objektu zdroje události (objekt, kterému se událost
stane - například tlačítko), že chcete zavolat funkci, kdy k události dojde. To provedete zavoláním metody
addEventListener() tohoto objektu (všechny objekty, které mají události, mají také metodu
addEventListener()). Metoda addEventListener()má dva parametry:
• První, název specifické události, na kterou chcete reagovat. Znovu, každá událost je spojena se specifickou třídou a
tato třída bude mít speciální hodnotu předdefinovanou pro každou událost - podobně jako jedinečný název
události, který byste měli použít pro první parametr.
• Druhý, název funkce odezvy na událost. Povšimněte si, že název funkce je zapsán bez závorek, když je předáván
jako parametr.
Prověření procesu zpracování události
Následující podrobný popis se věnuje procesu, který nastává, když vytvoříte posluchače události. V tomto případě je
příkladem vytvoření funkce posluchače, která je zavolaná po klepnutí na objekt nazvaný myButton.
Skutečný programátorem zapsaný kód je následující:
function eventResponse(event:MouseEvent):void
{
// Actions performed in response to the event go here.
}
myButton.addEventListener(MouseEvent.CLICK, eventResponse);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 15
Začínáme s ActionScriptem
Zde je uvedeno, jak by kód pracoval při spuštění v aplikaci Flash Player. (Toho chování je také identické pro aplikaci
Adobe AIR):
1 Když se načte soubor SWF, aplikace Flash Player si povšimne skutečnosti, že existuje funkce pojmenovaná
eventResponse().
2 Přehrávač Flash Player pak spustí kód (specificky řádky kódu, které nejsou funkcí). V tomto případě to je pouze
jedna řádka kódu: zavolání metody addEventListener() pro objekt zdroje události (pojmenovaný myButton) a
předávající funkci eventResponse jako parametr.
a Vnitřně má objekt myButton seznam funkcí, které naslouchají jeho událostem, takže když je zavolána metoda
addEventListener(), objekt myButton uloží funkci eventResponse() do seznamu posluchačů událostí.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 16
Začínáme s ActionScriptem
3 V některém bodě uživatel klepne na objekt myButton, spustí událost click (identifikována v kódu jako
MouseEvent.CLICK).
V tento okamžik nastane následující:
a Přehrávač Flash Player vytvoří objekt, instanci třídy spojenou s dotyčnou událostí (v tomto příkladu
MouseEvent). Pro mnoho události to bude instance třídy Event; pro události myši to bude instance MouseEvent
a pro ostatní události to bude instance třídy, která je danou událostí spojena. Tento vytvořený objekt je znám
jako objekt události a obsahuje specifické informace o událostí, které nastaly, o jaký typ události se jedná, kde k
ní došlo a ostatní informace specifické pro danou události, pokud jsou k dispozici.
b Přehrávač Flash Player poté vyhledá posluchače událostí uložené objektem myButton. Postupně projde těmito
funkcemi, zavolá každou z nich a předá objekt události funkci jako parametr. Protože funkce eventResponse()
je jednou z posluchačů objektu myButton, jako součást tohoto procesu aplikace Flash Player zavolá funkci
eventResponse().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 17
Začínáme s ActionScriptem
c Když je zavolána funkce eventResponse(), kód v této funkci se spustí, takže jsou vykonány specifikované
činnosti.
Příklady zpracování událostí
Zde je uvedeno několik dalších konkrétních příkladů událostí, které vám umožní získat představu o některých běžných
prvcích událostí a možných dostupných změnách, když zapisujete kód zpracování události.
• Klepnutím na tlačítko spustíte přehrávání stávajícího filmového klipu. V následujícím příkladu je playButton
název instance tlačítka a this je speciální název, mající význam „stávající objekt“:
this.stop();
function playMovie(event:MouseEvent):void
{
this.play();
}
playButton.addEventListener(MouseEvent.CLICK, playMovie);
• Detekce zadávání textu do pole. V tomto příkladu je entryText vstupní textové pole a outputText je dynamické
textové pole:
function updateOutput(event:TextEvent):void
{
var pressedKey:String = event.text;
outputText.text = "You typed: " + pressedKey;
}
entryText.addEventListener(TextEvent.TEXT_INPUT, updateOutput);
• Klepnutí na tlačítko a přesun na adresu URL. V tomto příkladu je linkButton názvem instance tlačítka:
function gotoAdobeSite(event:MouseEvent):void
{
var adobeURL:URLRequest = new URLRequest("http://www.adobe.com/");
navigateToURL(adobeURL);
}
linkButton.addEventListener(MouseEvent.CLICK, gotoAdobeSite);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 18
Začínáme s ActionScriptem
Vytváření instancí objektu
Samozřejmě, že předtím, než můžete použít objekt v jazyce ActionScript, musí tento objekt existovat. Jednou z částí
procesu vytváření objektu je deklarování proměnné. Toto deklarování však pouze vytvoří prázdné místo v paměti
počítače. Proměnné musíte přiřadit skutečnou hodnotu - tj. vytvořit objekt a uložit jej do proměnné - před pokusem
o použití nebo zpracování. Procesu vytváření objektu se říká konkretizace objektu - jinými slovy vytvoření instance
specifické třídy.
Jednoduchý způsob vytvoření instance objektu vůbec nevyžaduje jazyk ActionScript. V aplikaci Flash, když umístíte
symbol filmového klipu, tlačítka nebo textové pole na plochu a přiřadíte mu název instance v Inspektoru vlastností,
aplikace Flash automaticky deklaruje proměnnou s tímto názvem instance, vytvoří instanci objektu a uloží tento objekt
do proměnné. Podobně, ve vývojovém prostředí Adobe Flex Builder, když vytváříte součást v aplikaci MXML (buď
kódováním značky MXML nebo uložením součásti do editoru v režimu návrhu) a přiřadíte ID této součásti (v MXML
nebo zobrazení Vlastnosti Flex), toto ID se stane názvem proměnné ActionScript a vytvoří se instance součásti, která
se uloží v proměnné.
Vždy však nebudete chtít vytvářet objekt vizuálně. Existuje několik způsobů, jak můžete vytvořit instance objektu
pouze pomocí jazyka ActionScript. Nejprve s několika datovými typy ActionScript můžete vytvořit instanci pomocí
literálového výrazu - hodnoty zapsané přímo do kódu jazyka ActionScript. Zde jsou uvedeny některé příklady:
• Literálová číselná hodnota (zadejte číslo přímo):
var someNumber:Number = 17.239;
var someNegativeInteger:int = -53;
var someUint:uint = 22;
• Literálová hodnota řetězce (text uložte do uvozovek):
var firstName:String = "George";
var soliloquy:String = "To be or not to be, that is the question...";
• Literálové booleovská hodnota (použijte literálové hodnoty true nebo false):
var niceWeather:Boolean = true;
var playingOutside:Boolean = false;
• Literálová hodnota pole (seznam hodnot oddělených čárkami v vložte do hranatých závorek):
var seasons:Array = ["spring", "summer", "autumn", "winter"];
• Literálová hodnota XML (zadejte XML přímo):
var employee:XML = <employee>
<firstName>Harold</firstName>
<lastName>Webster</lastName>
</employee>;
Jazyk ActionScript také definuje literálové výrazy pro datové typy Array, RegExp, Object a Function. Podrobnosti o
těchto třídách naleznete v části „Práce s poli“ na stránce 152, „Používání regulárních výrazů“ na stránce 202 a „Datový
typ Object“ na stránce 58.
V případě dalších datových typů, chcete-li vytvořit instanci objektu, použijte operátor new s názvem třídy, takto:
var raceCar:MovieClip = new MovieClip();
var birthday:Date = new Date(2006, 7, 9);
Vytváření objektu pomocí operátoru new je často označováno za „volání konstruktoru třídy“. Konstruktor je speciální
metodou volanou jako část procesu vytváření instance třídy. Povšimněte si, že když vytváříte instanci tímto způsobem,
závorky dáváte za název třídy a někdy zadáváte hodnoty parametru - dvě věci, které také činíte při volání metody.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 19
Začínáme s ActionScriptem
I pro ty datové typy, které umožňují vytvářet instance pomocí literálového výrazu, můžete použít operátor new k
vytvoření instance objektu. Například tyto dvě řádky kódu provádějí zcela stejnou činnost:
var someNumber:Number = 6.33;
var someNumber:Number = new Number(6.33);
Je důležité se dobře seznámit s vytvářením objektů způsobem newClassName() . Pokud potřebujete vytvořit instanci
datového typu jazyka ActionScript, který nemá vizuální znázornění (a proto jej nelze vytvořit uložením položky na
plochu aplikace Flash nebo v režimu návrhu editoru MXML vývojového prostředí Flex Builder), může tak učinit pouze
vytvořením objektu přímo v jazyce ActionScript pomocí operátoru new.
Specificky v aplikaci Flash operátor new můžete také použít pro vytvoření instance symbolu filmového klipu, který je
definován v knihovně, ale není umístěn na plochu. Další informace naleznete v části „Vytváření objektů MovieClip
pomocí kódu ActionScript“ na stránce 402.
Společné prvky programu
Kromě deklarování proměnných, vytváření instancí objektů a manipulace s objekty pomocí jejich vlastností a metod
existuje několik dalších stavebních bloků, které potřebujete vytvořit v programu jazyka ActionScript.
operátory
Operátory jsou speciální symboly (nebo příležitostně slova), která jsou používána k provádění výpočtů. Jsou většina
používány pro matematické operace a rovněž pro porovnávání hodnot. Jako obecné pravidlo používá operátor jednu
nebo více hodnot a „vypracuje“ jeden výsledek. Například:
• Operátor sčítání (+) sečte dvě hodnoty a vytvoří jedno číslo:
var sum:Number = 23 + 32;
• Operátor násobení (*) vynásobí jednu hodnotu druhou a vytvoří jedno číslo:
var energy:Number = mass * speedOfLight * speedOfLight;
• Operátor rovnosti (==) porovná dvě hodnoty a poskytne výsledek ve formě jedné booleovské hodnoty (pravda nebo
nepravda).
if (dayOfWeek == "Wednesday")
{
takeOutTrash();
}
Jak je zde znázorněno, operátor rovnosti a další operátory „porovnání“ jsou nejčastěji používány s příkazem if, zda
mají být některé instrukce vykonány nebo nikoliv.
Podrobnosti a příklady použití operátorů naleznete v kapitole „Operátory“ na stránce 68.
Poznámky
Když zapisujete kód jazyka ActionScript, často budete sami pro sebe zanechávat poznámky, vysvětlující jak části kódu
pracují nebo proč jste provedli specifický výběr. Komentáře kódu jsou nástrojem pro zapsání textu, který by měl
počítač v kódu ignorovat. Jazyk ActionScript zahrnuje dva typy komentářů:
• Jednořádkový komentář: jednořádkový komentář je označen vložením dvou lomítek kdekoliv do řádky. Vše za
lomítky až na konec řádky je počítačem ignorováno.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 20
Začínáme s ActionScriptem
// This is a comment; it's ignored by the computer.
var age:Number = 10; // Set the age to 10 by default.
• Víceřádkový komentář: víceřádkový komentář zahrnuje značku počátku (/*), pak samotný obsah a nakonec
značku konce (*/). Vše mezi počáteční a koncovou značkou je počítačem ignorováno, bez ohledu na počet řádku,
na kterých se komentář nachází.
/*
This might be a really long description, perhaps describing what
a particular function is used for or explaining a section of code.
In any case, these lines are all ignored by the computer.
*/
Dalším běžným použitím komentáře je dočasné „vypnutí“ jednoho nebo několika řádků kódu - například testujete
různé způsoby funkce, nebo zkoušíte zjistit, proč kód jazyka ActionScript nepracuje způsobem, kterým požadujete.
Řízení toku
Mnohokrát v programu budete potřebovat opakovat jisté činnosti, provést pouze jedny činnosti a nikoliv druhé,
provést alternativní činnosti v závislosti na podmínkách atd. Řízení toku je ovládáním provádění jednotlivých činností.
Existuje několik typů prvků řízení tok, které jsou v jazyce ActionScript dostupné.
• Funkce: funkce jsou jako zástupci - poskytují možnost seskupení činnosti pod jedním názvem a mohou být použity
k provedení výpočtů. Funkce jsou obzvláště důležité pro zpracování událostí, ale jsou také použity jako obecné
nástroje pro seskupení řady instrukcí. Další informace o funkcích, viz „Funkce“ na stránce 78.
• Cykly: struktury cyklů umožňují označit sadu instrukcí, kterou bude počítač provádět po stanovený počet
opakování, nebo dokud se nezmění stanovená podmínka. Cykly se často používají pro zpracování několika
souvisejících položek, pomocí proměnné, jejíž hodnota se změní pokaždé, když počítač dokončí jednotlivý cyklus.
Další informace o cyklech, viz „Opakování“ na stránce 75.
• Podmíněný příkaz: podmíněný příkaz poskytuje způsob, jak označit jisté instrukce, které mají být provedeny pouze
za jistých okolností nebo pro poskytnutí alternativní sady instrukcí pro různé podmínky. Nejběžnějším typem
podmíněného příkazu je příkaz if. Příkaz if kontroluje hodnotu nebo výraz v závorkách. Pokud je hodnota true,
řádky kódu ve složených závorkách jsou provedeny, jinak jsou ignorovány. Například:
if (age < 20)
{
// show special teenager-targeted content
}
Společník příkazu if, příkaz else, umožňuje označit alternativní instrukce, které mají být provedeny pokud
podmínka nemá hodnotu true:
if (username == "admin")
{
// do some administrator-only things, like showing extra options
}
else
{
// do some non-administrator things
}
Další informace o podmíněném příkazu, viz „Podmíněné příkazy“ na stránce 73.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 21
Začínáme s ActionScriptem
Příklad: animace kusu portfolia
Tento příklad je navržen tak, aby vám poskytl příležitost vidět, jak můžete sestavit kusy kódu ActionScript do
kompletní, pokud ne rovnou kódem ActionScript propletené, aplikace. Animace kusu portfolia je příkladem, jak
můžete vzít stávající lineární animaci (například kus vytvořený pro klienta) a přidat drobné interaktivní prvky vhodní
pro vložení této animace do online portfolia. Interaktivní chování, které přidáme do animace, bude zahrnovat dvě
tlačítka, na které může uživatel klepnout: jedno pro spuštění animace a druhé pro přechod na samostatnou adresu
URL (například nabídka portfolia nebo úvodní stránka autora).
Proces vytvoření tohoto kusu lze rozdělit do následujících hlavních částí:
1 Připravení souboru FLA pro přidání kódu v jazyce ActionScript a interaktivních prvků.
2 Vytvoření a přidání tlačítek.
3 Zapsání kódu v jazyce ActionScript.
4 Testování aplikace.
Příprava na přidání interaktivních prvků
Před přidáním interaktivních prvků do animace je vhodné nastavit soubor FLA vytvořením míst pro přidání nového
obsahu. Sem patří vytvoření skutečného prostoru na ploše, kde lze umístit tlačítka a také vytvoření „prostoru“ v
souboru FLA pro uchování samostatnosti různých položek.
Chcete-li nastavit soubor FLA pro přidání interaktivních prvků:
1 Pokud zatím nemáte lineární animaci, do které byste přidali interaktivní prvky, vytvořte nový soubor FLA s
jednoduchou animaci jako je jednotlivé doplnění pohybu nebo doplnění tvaru. Jinak otevřete soubor FLA
obsahující animaci, kterou zobrazujete v projektu a uložte jej s novým názvem a vytvořte tak nový pracovní soubor.
2 Rozhodněte se, kde na obrazovce chcete zobrazit dvě tlačítka (jedno pro spuštění animace, druhé pro připojení k
portfoliu autora nebo jeho výchozí stránce). V případě potřeby pro tento nový obsah uvolněte nebo přidejte další
prostor na ploše. Pokud animace zatím nemá úvodní obrazovku, můžete ji vytvořit na prvním snímku
(pravděpodobně budete chtít posunout animaci a začít od snímku 2 nebo později).
3 Přidání nové vrstvy nad ostatní vrstvy v časové ose a její přejmenování na buttons. Toto bude vrstva v místě, kde
přidáte tlačítka.
4 Přidejte novou vrstvu na vrstvu tlačítek a pojmenujte ji actions. To bude místo, kde přidáte kód ActionScript do
aplikace.
Vytváření a přidávání tlačítek
Dále musíte vytvořit a umístit tlačítka, která budou tvořit střed naší interaktivní aplikace.
Vytvoření a přidání tlačítek do souboru FLA:
1 Pomocí nástrojů kreslení vytvořte vizuální vzhled prvního tlačítka (tlačítko přehrávání) na vrstvě tlačítek.
Například můžete nakreslit vodorovný ovál s textem nad ním.
2 Pomocí nástroj výběru vyberte všechny součásti grafiky jednoho tlačítka.
3 V hlavní nabídce zvolte Změnit > Převést na symbol.
4 V dialogovém okně zvolte jako typ symbolu Tlačítko, zadejte název a klepněte na tlačítko OK.
5 S vybraným tlačítkem Inspektor vlastností stanoví pro tlačítko název instance playButton.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 22
Začínáme s ActionScriptem
6 Opakujte kroky 1 až 5 a vytvořte tlačítko, které přesune uživatele na výchozí webovou stránku autora. Pojmenujte
toto tlačítko homeButton.
Zápis kódu
Kód ActionScript pro tuto aplikaci lze rozdělit do tří souborů funkčnosti, i když vše bude zadáváno na jednom místě.
Tři věci, které kód musí učinit, jsou následující:
• Zastavit přehrávací hlavu, jakmile se soubor SWF načte (když přehrávací hlava najede na snímek 1).
• Naslouchat události, která spustí přehrávání souboru SWF, když uživatel klepne na tlačítko přehrávání.
• Naslouchat události, která odešle prohlížeč na příslušnou stránku URL, když uživatel klepne na tlačítko výchozí
webové stránky autora.
Vytvoření kódu, který zastaví přehrávací hlavu po najetí na snímek 1:
1 Zvolte klíčový snímek jako snímek 1 vrstvy akcí.
2 Otevřete panel Akce z hlavní nabídky vybráním možnosti Okno > Akce.
3 V panelu Skript zadejte následující kód:
stop();
Zapsání kódu, který spustí animaci, když klepnete na tlačítko přehrávání:
1 Na konci kódu zadaného v předchozích krocích přidejte dvě prázdné řádky.
2 Na konec skriptu zadejte následující kód:
function startMovie(event:MouseEvent):void
{
this.play();
}
Tento kód definuje funkci nazvanou startMovie(). Když zavoláte funkci startMovie(), způsobí spuštění
přehrávání hlavní časové osy.
3 Na řádku za kódem přidaným v předchozím kroku zadejte tento řádek kódu:
playButton.addEventListener(MouseEvent.CLICK, startMovie);
Tento řádek kódu registruje funkci startMovie() jako posluchače pro událost click tlačítka playButton. Jinými
slovy, kdykoliv klepnete na tlačítko pojmenované playButton, je zavolána funkce startMovie().
Chcete-li zapsat kód pro přesměrování prohlížeče na adresu URL, když je klepnuto na tlačítko výchozí stránky:
1 Na konci kódu zadaného v předchozích krocích přidejte dvě prázdné řádky.
2 Na konec skriptu zadejte následující kód:
function gotoAuthorPage(event:MouseEvent):void
{
var targetURL:URLRequest = new URLRequest("http://example.com/");
navigateToURL(targetURL);
}
Tento kód definuje funkci nazvanou gotoAuthorPage(). Tato funkce nejprve vytvoří instanci URLRequest
představující adresu URL http://example.com/ a pak předá tuto adresu URL funkci navigateToURL(), způsobí
tak, že prohlížeč uživatele otevře tuto adresu URL.
3 Na řádku za kódem přidaným v předchozím kroku zadejte tento řádek kódu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 23
Začínáme s ActionScriptem
homeButton.addEventListener(MouseEvent.CLICK, gotoAuthorPage);
Tento řádek kódu registruje funkci gotoAuthorPage() jako posluchače pro událost click tlačítka homeButton.
Jinými slovy, kdykoliv klepnete na tlačítko pojmenované homeButton, je zavolána funkce gotoAuthorPage().
Testování aplikace
V tomto okamžiku by měla být aplikace zcela funkční. Otestujme ji a přesvědčme se o tom.
Testování aplikace:
1 V hlavní nabídce zvolte Ovládání > Testovat film. Aplikace Flash vytvoří soubor SWF a otevře jej v okně Flash
Player.
2 Vyzkoušejte obě tlačítka a ujistěte se, že provádějí přesně ty činnosti, které zamýšlíte.
3 Pokud tlačítka nepracují, měli byste ověřit následující:
• Mají obě tlačítka odlišné názvy instancí?
• Volají metody addEventListener() použití stejných názvů, jako jsou názvy instancí tlačítek?
• Jsou použité správné názvy událostí ve volání metody addEventListener()?
• Je specifikován správný parametr pro každou funkci? (Oba by měly mít jeden parametr s datovým typem
MouseEvent.)
Všechny tyto chyby a většina dalších by měly signalizovat chybové hlášení, buď když zvolíte příkaz Testovat film
nebo když klepnete na tlačítko. Podívejte se na panel Chyby kompilátoru a vyhledejte chyby kompilace (chyby, ke
kterým dochází při první zvolení příkazu Testovat film) a zkontrolujte panel Výstup, zda se zde vyskytují chybu
běhu programu (chyby, které nastávají při přehrávání souboru SWF - například při klepnutí na tlačítko).
Vytváření aplikací v jazyce ActionScript
Proces psaní kódu v jazyce ActionScript a vytváření aplikace zahrnuje více než jenom znalost syntaxe a názvů tříd,
které použijete. Zatímco většina informací v této příručce je směřována ke dvou tématům (syntaxe a použití tříd
ActionScript), budete také musíte znát informace o tom, které programy lze pro zapisování kódu ActionScript
používat, jak lze kód ActionScript organizovat a zahrnout do aplikace a jaké kroky byste měli sledovat při vývoji
aplikace v kódu jazyka ActionScript.
Možnosti organizování kódu
Kód jazyka ActionScript 3.0 můžete použít pro cokoliv, od jednoduchých grafických aplikací, až po složité systém
zpracování transakcí klient-server. V závislosti na typu vytvářené aplikace můžete dávat přednost použití jednoho
nebo několika těchto různých způsobů zahrnutí kódu ActionScript do svého projektu.
Uložení kódu do snímků časové osy aplikace Flash
Ve vývojovém prostředí aplikace Flash můžete přidat kód ActionScript ke kterémukoliv snímku v časové ose. Tento
kód bude vykonán při přehrávání filmu, když přehrávací hlava najede na daný snímek.
Umístění kódu ActionScript dovnitř snímků poskytuje jednoduchý způsob, jak přidat do aplikace chování vestavěné
ve vývojovém nástroji Flash. Můžete přidat kód ke kterémukoliv snímku v hlavní časové ose nebo ke kterémukoliv
snímku v časové ose kteréhokoliv symbolu MovieClip. Tato flexibilita však není zdarma. Když vytváříte větší aplikace,
snadno ztratíte povědomí o tom, které snímky obsahují které skripty. To může po čase způsobit obtížnější údržbu
aplikace.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 24
Začínáme s ActionScriptem
Mnoho vývojových pracovníků zjednodušuje organizaci kódu ActionScript ve vývojovém nástroji Flash vložením
kódu přímo do prvního snímku časové osy, nebo do specifické vrstvy dokumentu Flash. To usnadňuje lokalizaci a
údržbu kódu v souborech Flash FLA. Chcete-li však použít stejný kód v jiném projektu Flash, musíte nakopírovat a
vložit kód do nového souboru.
Pokud chcete použít kód ActionScript v jiném projektu Flash v budoucnosti, budete muset uložit kód do externího
souboru ActionScript (textový soubor s příponou .as).
Uložení kódu v souborech ActionScript
Pokud projekt zahrnuje velkou část v kódu ActionScript, nejlepším způsobem organizace kódu je jeho oddělení do
samostatných souborů ActionScript (textové soubory s příponou .as). Soubor ActionScript může být strukturován
jedním ze dvou způsobů, v závislosti na tom, jak jej zamýšlíte použít v aplikaci.
• Nestrukturovaný kód ActionScript: řádky kódu ActionScript, včetně definicí příkazů nebo funkcí, zaspané jako by
byly zadány přímo do časové osy skriptu, souboru MXML atd.
Kód ActionScript zapsaný tímto způsobem, je přístupný pomocí příkazu include v ActionScript, nebo pomocí
značky <mx:Script> v Adobe Flex MXML. Příkaz include v jazyce ActionScript způsobí vložení obsahu
externího souboru ActionScript do specifického umístění a v daném rozsahu skriptu, pokud zde byl zadán přímo.
V jazyce Flex MXML značka <mx:Script> umožňuje specifikovat zdrojový atribut, který identifikuje externí
soubor ActionScript, který se má v tomto okamžiku v aplikaci načíst. Například následující značka načte externí
soubor ActionScript pojmenovaný Box.as:
<mx:Script source="Box.as" />
• Definice třídy ActionScript: definice třídy ActionScript, včetně definicí metody a vlastnosti.
Když definujete třídu, můžete zpřístupnit kód ActionScript v třídě vytvořením instance třídy a použitím jejích
vlastností, metod a události, podobně jako v případě vestavěných tříd ActionScript. To vyžaduje dvě část:
• Použití příkazu import pro specifikování úplného názvu třídy, aby kompilátor jazyka ActionScript věděl, kde
jej má nalézt. Pokud chcete například použít třídu MovieClip v kódu ActionScript, musíte nejprve importovat
tuto třídu pomocí úplného názvu, včetně balíku a třídy:
import flash.display.MovieClip;
Alternativně můžete importovat balík, který obsahuje třídu MovieClip, což je ekvivalent zapsání samostatného
příkazu import pro každou třídu v balíku.
import flash.display.*;
Jediné výjimky z pravidla, že třída musí být importována v případě, že se na tuto třídu odkazujete ve svém kódu,
jsou třídy nejvyšší úrovně, které nejsou v balíku definované.
Poznámka: V aplikaci Flash jsou pro skripty připojené ke snímku v časové ose vestavěné třídy (v balících flash.*)
automaticky importovány. Když však zapisujete vlastní třídy, nebo když pracujete s vývojovými součástmi
aplikace Flash (balíky fl.*) nebo když pracujete ve vývojovém prostředí Flex, budete muset explicitně importovat
jakoukoliv třídu a zapsat tak kód, který vytváří instance dané třídy.
• Zapište kód, který specificky odkazuje na název třídy (obvykle deklarování proměnné s danou třídu jako
datovým typem a vytváření instance třídy pro uložení proměnné). Odkazováním na jiný název třídy v kódu
ActionScript sdělujete kompilátoru, aby načetl definici dané třídy. Například v případě uvedené externí třídy
nazvané Box způsobí tento příkaz vytvoření nové instance třídy Box.
var smallBox:Box = new Box(10,20);
Když se kompilátor poprvé setká s odkazem na třídu Box, vyhledá načtený zdrojový kód a lokalizuje definici
třídy Box.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 25
Začínáme s ActionScriptem
Výběr správného nástroje
V závislosti na potřebách projektu a dostupných zdrojích můžete použít jeden z několika nástrojů (nebo více nástrojů
ve vzájemném spojení) pro zápis a editování kódu ActionScript.
Vývojový nástroj Flash
Kromě svých schopností vytváření grafiky a animace aplikace Adobe Flash CS4 Professional zahrnuje nástroje pro
práci s kódem ActionScript, buď připojeným k prvkům v souboru FLA nebo v externím souboru ActionScript.
Vývojový nástroj Flash je ideální pro projekty vyžadující mnoho animací nebo videa nebo kde potřebujte vytvořit
většinu grafiky sami, obzvláště v projektech s minimální interakcí uživatele nebo funkcí vyžadující ActionScript.
Dalším důvodem pro použití vývojového nástroje Flash pro vytvoření projektů ActionScript je případ, kdy preferujete
vizuální prvky a zapisování kódu v jedné aplikaci. Můžete také používat vývojový nástroj Flash v případě, že chcete
použít předem vytvoření součásti uživatelského rozhraní, ale prioritou projektu je menší velikost souboru SWF nebo
snazší vizuální změny vzhledu.
Aplikace Adobe Flash CS4 Professional zahrnuje dva nástroje pro zápis kódu ActionScript:
• Panel Akce: dostupný při práci na souboru FLA. tento panel umožňuje zapisovat kód ActionScript připojený je
snímkům v časové ose.
• Okno Skript: okno Skript je vyhrazeným textovým editorem pro práci s kódem v jazyce ActionScript (soubory .as).
Flex Builder
Vývojové prostředí Adobe Flex Builder je špičkovým nástrojem pro vytváření projektů Flex. Kromě vizuálního
rozvržení a editačních nástrojů MXML nabízí Flex Builder také plně vybavený editor jazyka ActionScript, takže jej lze
použít pro vytváření projektů výhradně s Flex nebo ActionScript. Aplikace Flex mají několik výhod, včetně bohaté
sady předem vytvořených ovládacích prvků uživatelského rozhraní, flexibilních ovládacích prvků dynamického
uspořádání a vestavěných mechanismů pro práci s externími datovými zdroji a spojováním externích dat s prvky
uživatelského rozhraní. V důsledku dodatečného kódu, který tyto funkce zajišťuje, však aplikace Flex mohou mít větší
soubory SWF a nemohou mít zcela změněn vzhled tak snadno, jako tomu je u jejich protějšků ve Flash.
Vývojové prostředí Flex Builder používejte v případě, že vytváříte plně vybavené, bohaté internetové aplikace Flex
pracující s daty a chcete upravovat kód ActionScript, kód MXML a rozvrhnout aplikaci vizuálně, to vše v jediném
nástroji.
Editor jazyka ActionScript od jiných výrobců
Protože soubory ActionScript (.as) jsou uloženy jako jednoduché textové soubory, všechny programy schopné
editování prostého textu lze použít k psaní souborů ActionScript. Kromě produktů ActionScript od Adobe existuje
několik textových editorů třetích stran, se specifickými schopnostmi práce s kódem ActionScript. Soubor MXML nebo
třídy ActionScript můžete zapisovat pomocí kteréhokoliv textového editoru. Poté můžete vytvořit aplikaci SWF (buď
aplikaci výhradně Flex nebo ActionScript) z těchto souboru pomocí aplikace Flex SDK, který zahrnuje třídy Flex a také
kompilátor Flex. Alternativně mnoho vývojářů používá pro zapisování tříd ActionScript editor jazyka ActionScript od
třetí strany, v kombinaci s vývojovým nástrojem Flash pro vytváření grafického obsahu.
Použití editoru jazyka ActionScript od třetí strany můžete zvolit za následujících podmínek:
• Upřednostňujete zapisování kódu ActionScript v samostatném programu, ve spojení s navrhováním vizuálních
prvků v aplikaci Flash.
• Používáte aplikaci pro programování v jiném jazyce, než ActionScript (například vytváření stránek HTML nebo
vytváření aplikací v jiném programovacím jazyce), a chcete používat stejnou aplikaci pro zápis kódu v jazyce
ActionScript.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 26
Začínáme s ActionScriptem
• Chcete vytvořit projekty pouze ActionScript nebo Flex pomocí aplikace Flex SDK, bez vynaložení nákladů na
vývojová prostředí Flash nebo Flex Builder.
Některé vhodné editory programového kódu se specifickou podporou jazyka ActionScript zahrnují:
• Adobe Dreamweaver® CS4
• ASDT
• FDT
• FlashDevelop
• PrimalScript
• SE|PY
Proces vývoje kódu v jazyce ActionScript
Bez ohledu na to, zda jsou vaše projekty ActionScript malé nebo velké, použití procesu pro návrh a vývoj aplikace vám
pomůže pracovat efektivnější a účinněji. Následující kroky popisují základní proces vývoje aplikace pomocí
ActionScript 3.0:
1 Navrhněte aplikaci.
Před započetím vývoje byste měli aplikaci vhodným způsobem popsat.
2 Sestavte kód ActionScript 3.0.
Kód ActionScript můžete vytvořit pomocí aplikací Flash, Flex Builder, Dreamweaver nebo textového editoru.
3 Vytvořte soubor aplikace Flash nebo Flex, který spustí váš kód.
Ve vývojovém nástroji Flash toto vyžaduje vytvořené nového souboru FLA? nastavení publikování, přidání součástí
uživatelského rozhraní do aplikace a odkazování na kód ActionScript. Ve vývojovém prostředí Flex zahrnuje
vytvořené nového souboru aplikace definování a přidání součástí uživatelského rozhraní pomocí MXML a
odkazování na kód ActionScript.
4 Publikujte a otestujte svou aplikaci ActionScript.
Sem náleží spuštění aplikace z vývojového prostředí Flash nebo Flex a zkontrolování, zda vše pracuje podle potřeby.
Povšimněte si, že není nutné postupovat těmito kroky v přesně uvedeném pořadí, nebo dokončit jeden krok před
započetím jiného. Například můžete navrhnout jednu obrazovku aplikace (krok 1) a pak vytvořit grafiku, tlačítka atd
(krok 3) a až poté napsat kód v jazyce ActionScript (krok 2) a provést otestování (krok 4). Nebo můžete navrhnout
část, pak přidat jedno tlačítko nebo prvek rozhraní, zapsat kód v jazyce ActionScript pro každý tento prvek a otestovat
v daném provedení. I když je vhodné si pamatovat tyto čtyři fáze procesu vývoje, při skutečném vývoji je obvykle
efektivnější pohybovat se zpět a dopředu mezi fázemi vývoje podle potřeby.
Vytváření vlastních tříd
Proces vytváření tříd pro použití ve vašich projektech může vypadat skličující. Obtížnější části vytvoření třídy je však
její návrh - identifikace metod, vlastností a událostí, které bude třída zahrnovat.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 27
Začínáme s ActionScriptem
Strategie vytváření třídy
Téma objektově orientovaného návrhu je komplexní. Celé kariéry mnoha osob byly věnovány akademickému studiu
a profesionální praxi v této disciplíně. Existuje však několik doporučovaných přístupů. které mohou v začátcích
pomoci.
1 Přemýšlejte o úloze, kterou bude instance této třídy hrát v dané aplikaci. Obecně objekty slouží jedné z těchto tří
úloh:
• Objekt Value: tyto objekty slouží primárně jako kontejnery dat - tj. mají pravděpodobně několik vlastnost a
méně metod (někdy také nemají žádnou). Obecně se jedná o kódové vyjádření jasně definovaných položek,
například třída Song (reprezentující jednu skutečnou píseň) nebo třída Playlist (reprezentující koncepční
skupinu písní) v aplikaci hudebního přehrávače.
• Objekt Display: tyto objekty se ve skutečnosti zobrazují na obrazovce. Mezi příklady náleží prvky uživatelského
rozhraní, například rozvírací seznam nebo odečtení stavu, grafické prvky, jako jsou příšery ve video hře atd.
• Struktura aplikace: tyto objekty hrají širokou škálu podpůrných úloh v logice a zpracování prováděném aplikací.
Příklady zahrnují objekt provádějící jisté výpočty v biologické simulaci; objekt odpovědný za synchronizování
hodnot mezi otočným ovladačem a odečtenou hodnotou hlasitosti v hudebním přehrávači; objekt spravující
pravidla ve video hře; nebo objekt načítající uložené obrázky do kreslicí aplikace.
2 Rozhodněte se o specifické funkčnosti, kterou třída musí mít. Různé typy funkcí se často stávají metodami třídy.
3 Pokud má třída sloužit jako objekt hodnoty, rozhodněte se, která data budou instance zahrnovat. Tyto položky jsou
vhodnými kandidáty pro vlastnosti.
4 Protože třída je navrhována specificky pro váš projekt, nejdůležitější je poskytnout funkčnost, kterou vyžaduje vaše
aplikace. Mohlo by pomoci, pokud si sami odpovíte na následující otázky:
• Jaké části informací bude aplikace ukládat, sledovat a zpracovávat? Rozhodnutí zde pomůže identifikovat
všechny objekty a vlastnosti hodnot, které budete potřebovat.
• Jaké soubory akcí budete muset provádět - například, kdy se aplikace poprvé načte, kdy je klepnuto na specifické
tlačítko, kdy se film přestane přehrávat atd.? Toto jsou vhodní kandidáti na metody (nebo vlastnosti, pokud
„akce“ zahrnují pouze změnu jednotlivých hodnot).
• Pro kteroukoliv danou akci, jaké informace bude třída muset znát, aby tuto akci provedla? Tyto kusy informací
se stávají parametry metody.
• Když aplikace pokračuje v činnosti, aby vykonala svou práci, jaké věci se změní ve vaší třídě, o kterých budou
jiné části této aplikace muset vědět? Toto jsou vhodní kandidáti na události.
5 Pokud existuje stávající objekt, který je podobný vámi požadovanému objektu, kromě toho, že mu chybí další
funkce, které chcete přidat, zvažte vytvoření podtřídy (třídy postavené na funkčnosti stávající třídy, namísto
definování zcela nové funkce). Například, pokud chcete vytvořit třídu, která bude vizuálním objektem na
obrazovce, budete muset použít chování jednoho stávajícího objektu zobrazení (například Sprite nebo MovieClip)
jako základ pro svou třídu. V takovém případě MovieClip (nebo Sprite) budou základní třídou a vaše třída tuto
třídu bude rozšiřovat. Další informace o vytváření podtřídy, viz „Zdědění“ na stránce 106.
Zápis kódu pro třídu
Jakmile máte plán návrhu třídy, nebo alespoň představu, které informace bude muset sledovat a jaké akce bude muset
provádět, je vlastní syntaxe zápisu třídy velmi přímočará.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 28
Začínáme s ActionScriptem
Zde jsou minimální kroky, které byste měli vytvořit ve vlastní třídě ActionScript:
1 Otevřete nový textový dokument v programu specifickém pro jazyk ActionScript, například Flex Builder nebo
Flash, v obecném programovacím nástroji, jako Dreamweaver, nebo jiném programu umožňujícím práci s
dokumenty v prosté textové podobě.
2 Zadejte příkaz class a definujte název třídy. To provedete zadáním slov public class a pak názvu třídy,
následovaným levou a pravou složenou závorkou, která bude obsahovat obsah třídy (definice metody a vlastnosti).
Například:
public class MyClass
{
}
Slovo public označuje, že třída může být přístupná z jiného libovolného kódu. Jiné alternativy naleznete v kapitole
„Atributy jmenného prostoru pro ovládání přístupu“ na stránce 93.
3 Zadejte příkaz package a označte název balíku, ve kterém lze vaši třídu nalézt. Syntaxe je slovo package,
následované levou a pravou složenou závorkou (ve které je uveden blok příkazu class). Například chcete změnit
kód v předchozím kroku na tento:
package mypackage
{
public class MyClass
{
}
}
4 Definujte každou vlastnost ve třídě pomocí příkazu var v těle třídy; syntaxe je shodná, jsou použijete pro
deklarování kterékoliv proměnné (s přidáním modifikátoru public). Například přidání těchto řádek mezi levou a
pravou složenou závorku definice třídy vytvoří vlastnosti pojmenované textVariable, numericVariable a
dateVariable:
public var textVariable:String = "some default value";
public var numericVariable:Number = 17;
public var dateVariable:Date;
5 Definujte každou metodu ve třídě pomocí stejné syntaxe, kterou použijete pro definování funkce. Například:
• Chcete-li vytvořit metodu myMethod(), zadejte:
public function myMethod(param1:String, param2:Number):void
{
// do something with parameters
}
• Chcete-li vytvořit konstruktor (speciální metoda, která je volaná jako součást procesu vytváření instance třídy),
vytvoření metody, jejíž název odpovídá přesně názvu třídy:
public function MyClass()
{
// do stuff to set initial values for properties
// and otherwise set up the object
textVariable = "Hello there!";
dateVariable = new Date(2001, 5, 11);
}
Pokud nezahrnete metodu konstruktoru do své třídy, kompilátor automaticky vytvoří ve vaší třídě prázdný
konstruktor (bez parametrů a příkazů).
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 29
Začínáme s ActionScriptem
Existuje několik dalších prvků třídy, které můžete definovat. Tyto prvky jsou častěji zapojené.
• Zpřístupňovače jsou speciální přechody mezi metodou a vlastností. Když zapisujete kód pro definování třídy,
zapisujete zpřístupňovač jak metodu, takže můžete provádět několik akcí (spíše než čtení nebo přiřazení
hodnoty, což jediné můžete provádět, když definuje vlastnost). Nicméně když vytváříte instanci své třídy,
zacházíte se zpřístupňovačem jako s vlastností - pouze používáte název k načtení nebo přiřazení hodnoty. Další
informace, viz „Získání a nastavení metod mechanismů přístupu“ na stránce 99.
• Události v jazyce ActionScript nejsou definované pomocí specifické syntaxe. Místo toho definujete události ve
třídě pomocí funkce třídy EventDispatcher, abyste měli přehled o posluchačích události a mohli je informovat
o událostech. Další informace o vytváření událostí ve vlastních třídách naleznete v kapitole „Zpracování
událostí“ na stránce 243.
Příklad: Vytváření základních aplikací
Externí zdrojový soubor v jazyce ActionScript můžete vytvořit s příponou .as ve vývojovém prostředí Flash, Flex
Builder, Dreamweaver, nebo v kterémkoliv textovém editoru.
ActionScript 3.0 lze používat v několika vývojových prostředích, včetně vývojového prostředí Flash nebo Flex Builder.
Tato část prochází kroky vytváření a zlepšení jednoduchých aplikací v kódu ActionScript 3.0 pomocí vývojového
nástroje Flash nebo Flex Builder. Vytvořená aplikace představuje jednoduchý vzor použití externích souborů třídy
ActionScript 3.0 v aplikacích Flash a Flex. Vzory platí pro všechny ostatní vzorové aplikace v této příručce.
Návrh aplikace ActionScript
Před započetím vytváření aplikace byste o ní měli mít jistou představu.
Vyjádření návrhu může být jednoduché, jako pojmenování aplikace a stručné popsání jejího účelu, nebo tak
komplikované, jako soubor dokumentů požadavků obsahující mnoho schématu unifikovaného modelovacího jazyka
UML. Tato příručce nepopisuje disciplínu návrhu softwaru podrobně, ale je důležité mít na paměti, že návrh aplikace
je základním krokem při vývoje aplikace v jazyce ActionScript.
Naším prvním příkladem aplikace ActionScript bude standardní aplikace „Hello World“, jejíž návrh je velmi
jednoduchý.
• Aplikace se bude jmenovat HelloWorld.
• Zobrazí textové pole se slovy „Hello World!“
• Aby ji bylo možné snadno opakovaně použít, použije jednu objektově orientovanou třídu pojmenovanou Greeter,
kterou bude možné použít z dokumentu Flash nebo aplikace Flex.
• Po vytvoření základní verze aplikace přidáte novou funkci, která vyzve uživatele k zadání jména a nechá aplikací
zkontrolovat jméno podle seznamu známých uživatelů.
Se stručným definováním můžete začít vytvářet aplikaci samotnou.
Vytváření projektu Hello World a třídy Greeter
Návrh aplikace Hello World říká, že by kód měl být snadno opakovaně použitelný. S tímto úmyslem aplikace použije
jednu objektově orientovanou třídu pojmenovanou Greeter, který je použita v aplikaci vytvořené ve vývojovém
prostředí Flex nebo ve vývojovém nástroji Flash.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 30
Začínáme s ActionScriptem
Chcete-li vytvořit třídu Greeter ve vývojovém nástroji Flash:
1 Ve vývojovém nástroji Flash zvolte Soubor > Nový.
2 V dialogovém okně Nový dokument zvolte soubor ActionScript a klepněte na tlačítko OK.
Zobrazí se nové editační okno ActionScript.
3 Vyberte Soubor > Uložit. Vyberte složku pro uložení aplikace, pojmenujte soubor ActionScript Greeter.as a
klepněte na tlačítko OK.
Pokračujte se „Zapisování kódu do třídy Greeter“ na stránce 30.
Zapisování kódu do třídy Greeter
Třída Greeter definuje objekt, Greeter, který budete moci použít v aplikaci HelloWorld.
Chcete-li zapsat kód do třídy Greeter:
1 Zadejte do nového souboru následující kód:
package
{
public class Greeter
{
public function sayHello():String
{
var greeting:String;
greeting = "Hello World!";
return greeting;
}
}
}
Třída Greeter zahrnuje jednu metodu sayHello(), která vrací řetězec říkající „Hello World!“.
2 Vyberte Soubor > Uložit a uložte tento soubor ActionScript.
Třída Greeter je nyní připravena k použití v aplikaci.
Vytváření aplikace, která používá kód ActionScript
Třída Greeter, kterou jste vytvořili, definuje samostatný soubor softwarových funkcí, ale nereprezentuje kompletní
aplikaci. Chcete-li třídu použít, musíte vytvořit dokument Flash nebo aplikaci Flex.
Aplikace HelloWorld vytvoří novou instanci třídy Greeter. Zde je popis, jak připojíte třídu Greeter ke své aplikaci.
Chcete-li vytvořit aplikaci ActionScript pomocí vývojového nástroje Flash:
1 Zvolte Soubor > Nový.
2 V dialogovém okně Nový dokument zvolte Dokument Flash a klepněte na tlačítko OK.
Zobrazí se nové okno aplikace Flash.
3 Vyberte Soubor > Uložit. Zvolte stejnou složku, která obsahuje soubor třídy Greeter.as, pojmenujte dokumentu
Flash HelloWorld.fla a klepněte na tlačítko OK.
4 V paletě Nástroje Flash vyberte nástroj Text a přetažením přes plochu definujte nové textové pole, asi 300
obrazových bodů široké a 100 obrazových bodů vysoké.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 31
Začínáme s ActionScriptem
5 V panelu Vlastnosti s textovým polem stále vybraným na ploše, nastavte typ textu na „Dynamický text“ a zadejte
mainText jako název instance textového pole.
6 Klepněte na první snímek v hlavní časové ose.
7 V panelu Akce zadejte následující skript:
var myGreeter:Greeter = new Greeter();
mainText.text = myGreeter.sayHello();
8 Uložte soubor.
Pokračujte v části „Publikování a testování aplikace ActionScript“ na stránce 31.
Publikování a testování aplikace ActionScript
Vývoj softwaru je iterační proces. Napíšete část kódu, pokusíte se jej zkompilovat a upravíte kód tak, až je zkompilován
čistě. Spustíte zkompilovanou aplikaci, otestujete, zda plní zamýšlené funkce a pokud ne, upravíte kód znovu, až je vše
v pořádku. Vývojová prostředí Flash a Flex Builder nabízejí mnoho způsobů, jak publikovat, testovat a ladit aplikace.
Zde jsou uvedeny některé základní kroky pro testování aplikace HelloWorld v každém prostředí.
Chcete-li publikovat a testovat aplikaci ActionScript pomocí vývojového nástroje Flash:
1 Publikujte svou aplikaci a sledujte chyby kompilace. Ve vývojovém nástroji Flash zvolte Ovládání > Testovat film
a zkompilujte kód v jazyce ActionScript a spusťte aplikaci HelloWorld.
2 Pokud se v okně Výstup během testování aplikace zobrazí nějaké chyby, odstraňte příčiny chyb v souboru
HelloWorld.fla nebo HelloWorld.as a pak se pokuste aplikaci otestovat znovu.
3 Pokud žádné chyby během kompilace nenastanou, zobrazí se okno přehrávače Flash Player s aplikací Hello World.
Právě jste vytvořili jednoduchou, objektově orientovanou aplikaci, která využívá kódu ActionScript 3.0. Pokračujte v
části „Zlepšení aplikace HelloWorld“ na stránce 31.
Zlepšení aplikace HelloWorld
Chcete-li aplikaci poněkud vylepšit a učinit zajímavější, měli byste se nyní dotázat na jméno uživatele a ověřit jej vůči
předdefinovanému seznamu jmen.
Nejprve aktualizujte třídu Greeter a přidejte novou funkci. Pak aktualizujte aplikaci, aby novou funkci použila.
Aktualizace souboru Greeter.as:
1 Otevřete soubor Greeter.as.
2 Změňte obsah souboru tak, aby byl následující (nové a změněné řádky jsou zobrazeny tučným písmem).
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 32
Začínáme s ActionScriptem
package
{
public class Greeter
{
/**
* Defines the names that should receive a proper greeting.
*/
public static var validNames:Array = ["Sammy", "Frank", "Dean"];
/**
* Builds a greeting string using the given name.
*/
public function sayHello(userName:String = ""):String
{
var greeting:String;
if (userName == "")
{
greeting = "Hello. Please type your user name, and then press
the Enter key.";
}
else if (validName(userName))
{
greeting = "Hello, " + userName + ".";
}
else
{
greeting = "Sorry " + userName + ", you are not on the list.";
}
return greeting;
}
/**
* Checks whether a name is in the validNames list.
*/
public static function validName(inputName:String = ""):Boolean
{
if (validNames.indexOf(inputName) > -1)
{
return true;
}
else
{
return false;
}
}
}
}
Třída Greeter má nyní několik nových vlastností:
• Pole validNames uvádí seznam s platnými uživatelskými jmény. Pole se inicializuje tak, aby po načtení třídy
Greeter otevřelo seznam tří jmen.
• Metoda sayHello() nyní přijme uživatelské jméno a změní pozdrav na základě některých podmínek. Pokud je
userName prázdný řetězec (""), vlastnosti greeting je nastaven na zobrazení výzvy uživateli, aby zadal jméno.
Pokud je uživatelské jméno platné, pozdrav bude "Hello, userName." Nakonec, pokud není ani jedna z těchto
dvou podmínek, proměnná greeting se nastaví na "Sorry userName, you are not on the list."
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 33
Začínáme s ActionScriptem
• Metoda validName() vrátí hodnotu true, pokud je nalezeno inputName v poli validNames, nebo hodnotu
false, pokud nalezeno není. Příkaz validNames.indexOf(inputName) kontroluje každý řetězec v poli
validNames proti řetězci inputName. Metoda Array.indexOf() vrací polohu indexu první instance objektu v
poli, nebo hodnotu -1, pokud objekt v poli nalezen není.
Dále budete muset upravit soubor Flash nebo Flex, který odkazuje na tuto třídu ActionScript.
Chcete-li změnit aplikaci pomocí vývojového nástroje Flash:
1 Otevřete soubor HelloWorld.fla.
2 Změňte skript ve snímku 1 tak, aby prázdný řetězec ("") byl předán metodě sayHello() třídy Greeter:
var myGreeter:Greeter = new Greeter();
mainText.text = myGreeter.sayHello("");
3 Vyberte nástroj Text v paletě Nástroje a pak vytvořte dva nové textové soubory na ploše, vedle sebe a přímo pod
stávajícím textovým polem mainText.
4 V prvním novém textovém poli zadejte text User Name:, který bude sloužit jako jmenovka.
5 Zvolte další nové textové pole a v Inspektoru vlastností zvolte InputText jako typ textového pole. Jako typ řádky
zvolte jednotlivou řádku. Jako název instance zadejte textIn.
6 Klepněte na první snímek v hlavní časové ose.
7 V panelu Akce přidejte na konec stávajícího skriptu následující řádky:
mainText.border = true;
textIn.border = true;
textIn.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function keyPressed(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.ENTER)
{
mainText.text = myGreeter.sayHello(textIn.text);
}
}
Nový kód přidá následující funkci:
• První dva řádky jednoduše definují okraje dvou textových polí.
• Vstupní textové pole, například pole textIn, nastavilo události, které může odeslat. Metoda
addEventListener() umožňuje definovat funkci, která se spustí, když nastane typ události. V tomto případě
je touto události stisknutí klávesy.
• Uživatelská funkce keyPressed() kontroluje, zda stisknutou klávesou byla klávesa Enter. Pokud ani, funkce
zavolá metodu sayHello() objektu myGreeter a předá text z textového pole textIn jako parametr. Tato
metoda vrací řetězec pozdravu na základě předané hodnoty. Vrácený řetězec je pak přiřazen vlastnosti text
textového pole mainText.
Celý skript pro snímek 1 je následující:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 34
Začínáme s ActionScriptem
var myGreeter:Greeter = new Greeter();
mainText.text = myGreeter.sayHello("");
mainText.border = true;
textIn.border = true;
textIn.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function keyPressed(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.ENTER)
{
mainText.text = myGreeter.sayHello(textIn.text);
}
}
8 Uložte soubor.
9 Zvolte Ovládání > Testovat film a spusťte aplikaci.
Když spustíte aplikaci, budete vyzváni k zadání uživatelského jména. Pokud je platné (Sammy, Frank nebo Dean),
aplikace zobrazí hlášení s potvrzením „Hello“.
Spuštění následných příkladů
Nyní, když jste vyvinuli a spustili aplikaci „Hello World“ v kódu ActionScript 3.0, měli byste mít základní znalosti
potřebné pro spuštění dalších příkladů kódu uvedených v této příručce.
Testování příkladů kódu v této kapitole
Během používání této příručky můžete vyzkoušet příklady kódu, které jsou použity k ilustrování některých témat.
Testování může zahrnovat zobrazování hodnot proměnných v jistých místech programu, nebo sledování či interakci
s obsahem na obrazovce. Pro testování vizuálního obsahu nebo interakce budou popsány potřebné prvky předem nebo
v příslušném kódu - je nutné pouze vytvořit dokument s popsanými prvky a kód tak otestovat. V případě, že chcete
sledovat hodnotu proměnné v daném místě programu, existuje několik způsobů, kterým toho můžete dosáhnout.
Jedním způsobem je použití ladicího programu, například toho, který je součástí vývojového prostředí Flex Builder
nebo Flash. Pro jednoduché testování může být však snazší vytisknout hodnoty proměnných a snadno je tak zobrazit.
Následující kroky vám pomohou vytvořit dokument aplikace Flash, který můžete použít pro testování kódu a
zobrazení hodnot proměnných:
Chcete-li vytvořit dokument aplikace Flash pro testování příkladů v kapitole:
1 Vytvořte nový dokument Flash a uložte jej na pevný disk.
2 Chcete-li zobrazit testované hodnoty v textovém poli na ploše, aktivujte nástroj Text a vytvořte na ploše nové
dynamické textové pole. Nejužitečnější bude široké a vysoké textové pole s typem řádky nastaveným na možnost
Víceřádková a se zapnutým okrajem. V Inspektoru vlastnosti pojmenujte instanci textového pole (například
„outputText“). Chcete-li zapsat hodnoty do textového pole, budete muset do kódu příkladu (popsáno níže) přidat
kód, který volá metodu appendText().
3 Alternativně můžete do kódu přidat volání funkce trace() (popsáno níže) a zobrazit tak výsledky příkladu.
4 Chcete-li daný příklad otestovat, zkopírujte kód do panelu Akce; pokud je to nutné, přidejte volání funkce trace()
nebo přidejte hodnotu do textového pole pomocí metody appendText().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 35
Začínáme s ActionScriptem
5 V hlavní nabídce zvolte Ovládání > Testovat film, vytvořte soubor SWF a zobrazte výsledky.
Protože tento přístup je určen pro zobrazení hodnot proměnných, existují dva způsob, jak při zkoušení příkladů
snadno zobrazit hodnoty proměnných: zapište hodnoty do instance textového pole na ploše, nebo použijte funkci
trace() k vytištění hodnot do panelu Výstup.
• Funkce trace(): funkce trace() jazyka ActionScript zapíše hodnoty kteréhokoliv parametru jí předaného
(proměnné nebo literálové výrazy) do panelu Výstup. Mnoho z příkladů kódu v této příručce již obsahuje volání
funkce trace(), takže tyto příklady kódu budete muset pouze zkopírovat do dokumentu a otestovat projekt.
Pokud chcete použít funkci trace() k otestování hodnoty proměnné v kódu, který funkci ještě neobsahuje, pouze
přidejte volání trace() do kódu a předejte proměnnou jako parametr. Například, pokud se setkáte s kódem, jako
je tento v této kapitole,
var albumName:String = "Three for the money";
můžete jej zkopírovat do panelu Akce, pak přidat volání funkce trace(), jako je toto, a otestovat výsledek v kódu:
var albumName:String = "Three for the money";
trace("albumName =", albumName);
Když spustíte program, vytiskne se tento řádek:
albumName = Three for the money
Každé volání funkce trace() může použít několik parametrů, které jsou všechny zřetězeny do jedné vytištěné
řádky. Zalomení řádku je přidána na konec každého volání funkce trace(), takže samostatná volání trace() se
vytisknou na samostatný řádek.
• Textové pole na ploše: pokud dáváte přednost nepoužití funkce trace(), můžete přidat dynamické textové pole na
plochu pomocí nástroje Text a zapsat hodnoty do tohoto pole a zobrazit tak výsledky výpisu kódu. Metoda
appendText() třídy TextField může být použita k přidání hodnoty String na konec obsahu textového pole. Chceteli přistupovat k textovému poli pomocí jazyka ActionScript, musíte mu dát název instance v Inspektoru vlastností.
Pokud má například vaše textové pole název instance outputText, měl by být použit následující kód ke kontrole
hodnoty proměnné albumName:
var albumName:String = "Three for the money";
outputText.appendText("albumName = ");
outputText.appendText(albumName);
Tento kód zapíše následující text do textového pole pojmenovaného outputText:
albumName = Three for the money
Jak je vidět na příklad, metoda appendText() přidá text do stejné řádky jako předchozí obsah, takže lze do stejné
řádky textu přidat několik hodnot, pomocí několika volání appendText(). Chcete-li nuceně zobrazit text na
následujícím řádku, můžete přidat znak nové řádky ("\n"):
outputText.appendText("\n"); // adds a line break to the text field
Na rozdíl od funkce trace(), metoda appendText() přijímá jako parametr pouze jedinou hodnotu. Tato hodnota
musí být řetězcem (buď instance String nebo literálový řetězec). Chcete-li vytisknout hodnotu neřetězcové
proměnné, musíte nejprve převést hodnotu na řetězec. Nejsnazším způsobem, jak toto provést, je zavolat metodu
toString():
var albumYear:int = 1999;
outputText.appendText("albumYear = ");
outputText.appendText(albumYear.toString());
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 36
Začínáme s ActionScriptem
Práce s příklady na konci kapitoly
Jako tato kapitola, tak i většina ostatních v této příručce obsahuje na konci významné příklady, které spojují
dohromady mnoho konceptů v kapitole popisovaných. Avšak na rozdíl od příkladu Hello World v této kapitole, tyto
příklady nejsou prezentovány ve formě výukového příkladu krok za krokem. Odpovídající kód jazyka ActionScript 3.0
v každém příkladu bude zvýrazněn a popsán, ale pokyny pro spuštění příkladů ve specifickém vývojovém prostředí
uvedeny nebudou. Soubory s příklady distribuované s touto příručkou budou zahrnovat všechny soubory, které
potřebujete ke kompilaci a spuštění příkladů ve vybraném vývojovém prostředí
37
Kapitola 4: Jazyk ActionScript a jeho
syntaxe
Jazyk ActionScript 3.0 je tvořen jádrem jazyka ActionScript a programovacím rozhraním aplikace Adobe Flash Player
API. Základní jazyk je částí jazyka ActionScript, která definuje syntaxi jazyka i datové typy na nejvyšší úrovni. Jazyk
ActionScript 3.0 poskytuje programatický přístup k přehrávači Flash Player.
Tato kapitola poskytuje stručný úvod k jádru jazyka ActionScript a jeho syntaxi. Po prostudování této kapitoly byste
měli získat základní porozumění způsobu práce s datovými typy a proměnnými, jak používat správnou syntaxi a jak
ovládat tok dat v programu.
Přehled jazyka
Objekty ležící v jádru jazyka ActionScript 3.0 - tvoří základní stavební bloky. Každá proměnná, kterou deklarujete,
každá zapsaná funkce a každá vytvořená instance třídy je objektem. Program jazyka ActionScript 3.0 můžete
považovat za skupinu objektů provádějících úlohy, reagujících na události a komunikujících navzájem mezi sebou.
Programátoři seznámení s objektově orientovaným programováním (OOP) v jazyce Java nebo C++ mohou považovat
objekty za moduly, obsahující dva typy členů: data uložená v členských proměnných nebo vlastnostech, a chování
přístupné prostřednictvím metod. Jazyk ActionScript 3.0 definuje objekty podobným ale trochu odlišným způsobem.
V jazyce ActionScript 3.0 jsou objekty jednoduše sbírkou vlastností. Tyto vlastnosti jsou kontejnery, které uchovávají
nejenom data, ale také funkce nebo jiné objekty. Pokud je funkce tímto způsobem připojená k objektu, nazývá se
metodou.
Zatímco definice jazyka ActionScript 3.0 se může programátorům jazyků Java nebo C++ zdát poněkud podivná, v
praxi definování typů objektů s třídami ActionScript 3.0 bude velmi podobná způsobu, kterým jsou definovány třídy
v jazyce Java nebo C++. Rozdíl mezi dvěma definicemi objektu je důležitý při projednávání objektového modelu
ActionScript a dalších pokročilých témat, ale ve většině jiných situací znamená termín vlastnosti proměnné členy tříd,
což je protiklad metod. Referenční příručka jazyka ActionScript 3.0 a jeho součástí například používá termín vlastnosti
pro popis proměnných nebo vlastností příjemce. Používá termín metody k popisu funkcí, které jsou součástí třídy.
Jedním drobným rozdílem mezi třídou ActionScript a třídami v jazycích Java nebo C++ je to, že v jazyce ActionScript
nejsou třídy pouhými abstraktními entitami. Třídy ActionScript jsou vyjádřeny objekty třídy, které ukládají vlastnosti
třídy a metody. To umožňuje používat techniky, které se mohou zdát programátorům jazyků Java a C++ podivné,
například zahrnutí příkazů nebo spustitelného kódu na horní úrovni třídy nebo balíku.
Dalším rozdílem mezi třídami ActionScript a jazyka Java nebo C++ je v tom, že každá třída ActionScript má něco, co
se nazývá prototypovýobjekt. V předchozích verzích jazyka ActionScript sloužily prototypové objekty spojené do
řetězců prototypů jako základy dědičnosti celé hierarchie třídy. V jazyce ActionScript 3.0 však prototypové objekty
hrají jenom malou úlohu v systému dědičnosti. Prototypový objekt může být i nadále užitečný, nicméně jako
alternativa statickým vlastnostem a metodám, pokud chcete sdílet vlastnost a její hodnotu mezi všemi instancemi
třídy.
V minulosti programátoři ActionScript mohli přímo manipulovat s prototypovým řetězcem se zvláštními
vestavěnými prvky jazyka. Nyní, když jazyk poskytuje zralejší implementaci programovacího rozhraní založeného na
třídách, mnoho z těchto speciálních prvků jazyka, například __proto__ a __resolve, již není jeho součástí. Kromě
toho optimalizace mechanismu vnitřní dědičnosti, která poskytuje významné zvýšení výkonů aplikace Flash Player a
Adobe AIR, zabraňuje přímému přístupu k mechanismu dědičnosti.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 38
Jazyk ActionScript a jeho syntaxe
Objekty a třídy
V jazyce ActionScript 3.0 je každý objekt definovaný svou třídou. Třída může být šablonu nebo modrotiskem typu
objektu. Definice třídy mohou zahrnovat proměnné a konstanty, které uchovávají datové hodnoty, a metody, které
jsou funkcemi obsahujícími chování spojené s danou třídou. Hodnoty uložené ve vlastnostech mohou být primitivní
hodnoty nebo jiné objekty. Primitivní hodnoty jsou čísla, řetězce a booleovské hodnoty.
Jazyk ActionScript obsahuje několik vestavěných tříd, které jsou součástí jádra jazyka. Některé z těchto vestavěných
tříd, například čísla, booleovské hodnoty a řetězce, představují primitivní hodnoty dostupné v jazyce ActionScript.
Jiné, např. třídy Array, Math a XML, definují složitější objekty.
Všechny třídy, vestavěné nebo definované uživatelem, jsou odvozeny od třídy Object. Pro programátory s předchozí
zkušenosti s jazykem ActionScript, je důležité poznamenat, že datový typ Object již není výchozím typem, i když jsou
všechny třídy od něj odvozeny. V jazyce ActionScript 2.0 byly následující dva řádky kódu shodné protože neexistovala
anotace typu znamenající, že proměnná by byla typu Object:
var someObj:Object;
var someObj;
Jazyk ActionScript 3.0 však zavádí koncept proměnných bez typu, které mohou být označeny následujícími dvěma
způsoby:
var someObj:*;
var someObj;
Proměnné bez typu nejsou stejné, jako proměnné typu Object. Klíčovým rozdílem je to, že proměnné bez typu mohou
uchovávat speciální hodnotu undefined, zatímco proměnná typu Object tuto hodnotu uchovávat nemůže.
Můžete definovat své vlastní třídy a to pomocí klíčového slova class. vlastnosti třídy deklarujete třemi způsoby:
konstanty mohou být definovány klíčovým slovem const, proměnné mohou být definovány klíčovým slovem var a
vlastnosti getter a setter mohou být definovány použitím atributu get a set v deklarování metody. Metody můžete
deklarovat klíčovým slovem function.
Instanci třídy můžete vytvořit pomocí operátoru new. Následující příklad vytváří instanci třídy Date nazvanou
myBirthday.
var myBirthday:Date = new Date();
Balíčky a jmenné prostory
Balíčky a jmenné prostory jsou související koncepty. Balíčky umožňují spojit definice tříd způsobem, který usnadňuje
sdílení kódu a minimalizuje konflikty pojmenování. Jmenné prostory umožňují řídit viditelnost identifikátorů,
například názvů vlastnosti a metody, a mohou být použity v kódu bez ohledu na to, zda je umístěn vně nebo uvnitř
balíčku. Balíčky umožňují organizovat soubory tříd, jmenné prostory umožňují zpracovat viditelnost jednotlivých
vlastností a metod.
Balíčky
Balíčky v jazyce ActionScript 3.0 jsou implementovány s jmennými prostory, ale nejsou jejich synonymem. Když
deklarujete balíček, implicitně vytváříte speciální typ jmenného prostoru, který je zaručeně znám v okamžiku
kompilace. Jmenné prostory, když jsou vyjádřeny explicitně, nejsou nutně známy v čase kompilace.
Následující příklad používá instrukci package k vytvoření jednoduchého balíčku obsahujícího jednu třídu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 39
Jazyk ActionScript a jeho syntaxe
package samples
{
public class SampleCode
{
public var sampleGreeting:String;
public function sampleFunction()
{
trace(sampleGreeting + " from sampleFunction()");
}
}
}
Název třídy je v tomto příkladu SampleCode. Protože třída je uvnitř vzorového balíčku, kompilátor automaticky
kvalifikuje název třídy v okamžiku kompilace do plně platného názvu: samples.SampleCode. Kompilátor také
kvalifikuje názvy všech vlastností nebo metod, takže sampleGreeting a sampleFunction() se stanou
samples.SampleCode.sampleGreeting a samples.SampleCode.sampleFunction().
Mnoho vývojářů, obzvláště pokud mají zkušenosti s programováním v jazyce Java, volí umístění pouze tříd na horní
úrovni balíčku. Jazyk ActionScript 3.0 však podporuje nejenom třídy na horní úrovni balíčku, ale také proměnné,
funkce a také příkazy. Pokročilým použitím této funkce je definování jmenného prostoru na horní úrovni balíčku tak,
aby byl k dispozici všem třídám v daném balíčku. Povšimněte si však, že na horním úrovni balíčku jsou povoleny pouze
dva specifikátory přístupu, public a internal. Na rozdíl od jazyka Java, který umožňuje deklarovat vnořené třídy
jako soukromé, jazyk ActionScript 3.0 nepodporuje ani vnořené, ani soukromé třídy.
Mnoha jinými způsoby jsou však balíčky jazyka ActionScript 3.0 podobné balíčkům v programovacím jazyce Java. Jak
jste mohli vidět na předchozím příkladu, zcela platné reference balíčku jsou vyjádřeny pomocí operátoru tečka (.),
stejně jako v jazyce Java. Balíčky můžete použít k organizování kódu do intuitivní hierarchické struktury pro použití
jinými programátory. To usnadňuje sdílení kódu a umožňuje vytvářet vlastní balíčky pro sdílení s ostatními a používat
balíčky vytvořené jinými programátory ve vlastním kódu.
Používání balíčků rovněž pomáhá zajistit, aby použité názvy identifikátorů byly unikátní a nebyly ve střetu s jinými
názvy identifikátorů. Ve skutečnosti by někdo mohl říci, že se jedná o primární výhodu balíčků. Například dva
programátoři, kteří si přejí sdílet svůj kód navzájem, mohou vytvořit třídu nazvanou SampleCode. Bez balíčků by to
vedlo ke konfliktu názvů a jediným řešením by bylo přejmenování jedné ze tříd. Díky balíčkům je však konflikt názvů
snadno odstranitelný a to vložením jedné, nebo lépe obou tříd do balíčku s unikátními názvy.
Můžete také zahrnout integrované tečky do názvů svých balíčků a vytvořit tak vnořené balíčky. To umožňuje vytvářet
hierarchické organizování balíčků. Dobrým příkladem je balík flash.xml v jazyce ActionScript 3.0. Balík flash.xml je
vložen do balíku flash.
Balíček flash.xml obsahuje dřívější syntaktický analyzátor XML, který byl použit v předchozích verzích jazyka
ActionScript. Jedním z důvodů, proč je nyní umístěn v balíčku flash.xml je to, že název starší třídy XML je v konfliktu
s názvem nové třídy XML, která implementuje XML pro funkci specifikace ECMAScript (E4X) dostupnou v
ActionScript 3.0.
I když přesunutí starší třídy XML do balíčku je dobrým prvním krokem, většina uživatelů starších tříd XML importuje
balíček flash.xml, který vygeneruje stejný konflikt názvů, pokud nepoužijete vždy plně kvalifikovaný název starší třídy
XML (flash.xml.XML). Aby bylo možné se vyhnout této situaci, je starší třída XML nyní pojmenovaná
XMLDocument, jak je vidět na následujícím příkladu.
package flash.xml
{
class XMLDocument {}
class XMLNode {}
class XMLSocket {}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 40
Jazyk ActionScript a jeho syntaxe
Většina jazyka ActionScript 3.0 je organizována v rámci balíku flash. Například balíček flash.display obsahuje seznam
zobrazení API, a balíček flash.events obsahuje nový model událostí.
Vytváření balíčků
Jazyk ActionScript 3.0 poskytuje významnou flexibilitu způsobu, kterým je možné organizovat balíčky, třídy a
zdrojové soubory. Předchozí jazyk ActionScript povoloval pouze jednu třídu na zdrojový soubor a vyžadoval, aby
název zdrojového souboru odpovídal názvu třídy. Jazyk ActionScript 3.0 umožňuje zahrnout více tříd do jednoho
zdrojového souboru, avšak pouze jedna třída v každém souboru může být zpřístupněna kódu, který je pro daný soubor
externí. Jinými slovy pouze jedna třída v každém souboru může být deklarována uvnitř deklarace balíčku. Musíte
deklarovat všechny dodatečné třídy vně definice balíčku, což tyto třídy zneviditelní pro kód vně tohoto zdrojového
souboru. Název třídy deklarované uvnitř definice balíčku musí odpovídat názvu zdrojového souboru.
Jazyk ActionScript 3.0 také poskytuje vyšší stupeň flexibility způsobu deklarování balíčků. V předchozích verzích
ActionScript balíčky představovaly pouze adresáře, ve kterých byly umístěny zdrojové soubory, a nebylo nutné
deklarovat balíčky příkazem package, spíše se název balíčku zahrnul jako součást plně kvalifikovaného názvu třídy ve
vaší deklaraci třídy. I když balíčky stále vyjadřují adresáře v jazyku ActionScript 3.0, mohou obsahovat více než třídy.
V jazyku ActionScript 3.0 použijete příkaz package k deklarování balíčku, což znamená, že můžete také deklarovat
proměnné, funkce a jmenné prostory na horní úrovni balíčku. Na horní úrovni balíčku můžete také zahrnout
spustitelné příkazy. Pokud deklarujete proměnné, funkce nebo jmenné prostory na horní úrovni balíčku, jediným
atributem dostupným na této úrovni je public a internal a pouze jedna deklarace na úrovni balíčku na soubor může
použít atribut public, bez ohledu na to, zda je tato deklarace třídou, proměnnou, funkcí nebo jmenným prostorem.
Balíčky jsou užitečné pro organizování kódu a zabránění konfliktů názvů. Nezaměňujte koncept balíčků s
nesouvisejícím konceptem dědičnosti třídy. Dvě třídy spočívající ve stejném balíčku budou mít společný jmenný
prostor, ale nejsou nutné spojené navzájem mezi sebou jiným způsobem. Podobně, vnořené prostory nemají žádný
sémantický vztah s nadřazeným balíčkem.
Importování balíčků
Pokud chcete použít třídu uvnitř balíčku, musíte importovat balíček nebo jeho specifickou třídu. To je odlišné od
jazyka ActionScript 2.0, kde importování tříd bylo volitelné.
Například zvažte příklad s třídou SampleCode výše v této kapitole. Pokud třída spočívá v balíčku pojmenovaném
samples, musíte použít jeden z následujících příkladů před použitím třídy SampleCode:
import samples.*;
nebo
import samples.SampleCode;
Obecně příkazy import by měly být co nejspecifičtější. Pokud plánujete použít pouze třídu SampleCode z balíčku
samples, měli byste importovat pouze třídu SampleCode, spíše než celý balíček, ke kterému náleží. Importování celého
balíčku může vést k neočekávaným konfliktům názvů.
Musíte také umístit zdrojový kód, který definuje balíček nebo třídu do classpath. Třída classpath představuje
uživatelem definovaný seznam cest místních adresářů, který stanoví, kde bude kompilátor vyhledávat importované
balíčky a třídy. Třída classpath je někdy nazývána cesta sestavení nebo cesta zdroje.
Po správném importování třídy nebo balíčku použijete buď plně kvalifikovaný název třídy (samples.SampleCode)
nebo pouze název třídy samotné (SampleCode).
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 41
Jazyk ActionScript a jeho syntaxe
Plně kvalifikované názvy jsou užitečné v případě, že identicky pojmenované třídy, metody nebo vlastnosti vedou k
nejednoznačnému kódu, ale jejich správa může být obtížná, pokud jsou použity pro všechny identifikátory. Například
použití plně kvalifikovaného názvu vede k rozvláčnému kódu, když konkretizujete instanci třídy SampleCode:
var mySample:samples.SampleCode = new samples.SampleCode();
Když se zvýší úroveň třídy vnořeného balíčku, čitelnost kódu se sníží. V případě, kdy si jste jisti, že nejednoznačné
identifikátory nebudou problémem, můžete kód pro čtení zjednodušit pomocí jednoduchých identifikátorů.
Například konkretizace nové instance třídy SampleCode je mnohem méně rozvláčná, pokud použijete pouze
identifikátor třídy:
var mySample:SampleCode = new SampleCode();
Pokud se pokusíte použít názvy identifikátorů bez předchozího importování příslušného balíčku nebo třídy,
kompilátor nebude schopen nalézt definice třídy. Na druhou stranu, pokud importujete balíček nebo třídu, jakýkoliv
pokus o definování názvu vedoucí ke konfliktu s importovaným názvem, povede je generování chyby.
Když je vytvořen balíček, výchozí specifikátor přístupu pro všechny členy daného balíčku je internal, což znamená,
že standardně jsou členové balíčku viditelné pouze ostatním členům tohoto balíčku. Pokud chcete, aby třída byla
dostupná kódu vně balíčku, musíte deklarovat tuto třídu jako public. Například následující balíček obsahuje dvě
třídy, SampleCode a CodeFormatter:
// SampleCode.as file
package samples
{
public class SampleCode {}
}
// CodeFormatter.as file
package samples
{
class CodeFormatter {}
}
Třída SampleCode je viditelná vně balíčku, protože je deklarovaná jako třída public. Třída CodeFormatter je nicméně
viditelná pouze v rámci samotného balíčku. Pokud se pokusíte přistupovat k třídě CodeFormatter mimo vzorový
balíček, vygenerujete chybu, jak je vidět na následujícím příkladu:
import samples.SampleCode;
import samples.CodeFormatter;
var mySample:SampleCode = new SampleCode(); // okay, public class
var myFormatter:CodeFormatter = new CodeFormatter(); // error
Pokud chcete obě třídy zpřístupnit vně balíčku, musíte je obě deklarovat jako public. Nemůžete použít atribut public
pro deklarování balíčku.
Plně kvalifikované názvy jsou užitečné pro vyřešení konfliktů názvů, které mohou při použití balíčků nastat. Takový
scénář může nastat, pokud importujete dva balíčky definující třídy se stejným identifikátorem. Například zvažte
následující balíček, který také obsahuje třídu pojmenovanou SampleCode:
package langref.samples
{
public class SampleCode {}
}
Pokud importujete obě třídy následujícím způsobem, vytvoříte konflikt názvů při odkazování na třídu SampleCode:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 42
Jazyk ActionScript a jeho syntaxe
import samples.SampleCode;
import langref.samples.SampleCode;
var mySample:SampleCode = new SampleCode(); // name conflict
Kompilátor nemá žádnou možnost zjistit, kterou třídu SampleCode použít. Chcete-li vyřešit tento konflikt, musíte
využít plně kvalifikovaného názvu každé třídy, a to následujícím způsobem:
var sample1:samples.SampleCode = new samples.SampleCode();
var sample2:langref.samples.SampleCode = new langref.samples.SampleCode();
Poznámka: Programátoři se znalostí C++ často zaměňují příkaz import s příkazem #include. Instrukce #include je
nutná v C++ proto, že kompilátory C++ zpracovávají postupně jeden soubor za druhým, a nebudou vyhledávat v dalších
souborech definice třídy, pokud je soubor záhlaví explicitně zahrnut. Jazyk ActionScript 3.0 mí instrukci include, ale
není navržen pro importování tříd a balíčků. Chcete-li importovat třídy nebo balíčky do jazyka ActionScript 3.0, musíte
použít příkaz import a vložit zdrojový soubor obsahující balíček do cesty třídy.
Jmenné prostory
Jmenné prostory umožňují ovládat viditelnost vlastností a metod, které vytvoříte. Na specifikátory řízení přístupu
public, private, protected, a internal můžete nahlížet jako na vestavěné jmenné prostory. Pokud tyto
předdefinované specifikátory řízení přístupu nevyhovují vašim požadavkům, můžete vytvořit vlastní jmenné prostory.
Pokud jste seznámeni se jmennými prostory XML, většina těchto informací pro vás nebude nová, i když syntaxe a
podrobnosti o implementování jazyka ActionScript se mírně odlišuje od těch v XML. Pokud jste nikdy dříve
nepracovali s jmennými prostory, koncept samotný je přímý, ale implementace má specifickou terminologii, kterou
se musíte naučit.
Chcete-li porozumět funkci jmenných prostorů, je dobré znát, že název vlastnosti nebo metody vždy obsahuje dvě
části: identifikátor a jmenný prostor. Identifikátor je to, co obvykle považujete za název. Například identifikátory v
následující definici třídy jsou sampleGreeting a sampleFunction():
class SampleCode
{
var sampleGreeting:String;
function sampleFunction () {
trace(sampleGreeting + " from sampleFunction()");
}
}
Kdykoliv definice nejsou předcházeny atributem jmenného prostoru, jejich názvy jsou kvalifikovány výchozím
jmenným prostorem internal, což znamená, že jsou viditelné pouze volajícím ve stejném balíčku. Pokud je
kompilátor nastaven do přísného režimu, vydá výstrahu, že jmenné prostory internal platí pro každý identifikátor
bez atributu jmenného prostoru. Aby byl identifikátor dostupné všude, musíte specificky uvést v předponě název
identifikátoru s atributem public. V předchozím příkladu kódu obě třídy sampleGreeting a sampleFunction()
mají hodnotu jmenného prostoru internal.
Existují tři základní kroky, které je nutné při používání jmenných prostorů používat. Nejprve musíte definovat jmenný
prostor pomocí klíčového slova namespace. Například následující kód definuje jmenný prostor version1:
namespace version1;
Za druhé použijete jmenný prostor namísto specifikátoru řízení přístupu v deklaraci vlastnosti nebo metody.
Následující příklad vkládá funkci pojmenovanou myFunction() do jmenného prostoru version1:
version1 function myFunction() {}
Za třetí, jakmile použijete jmenný prostor, můžete na něj odkazovat instrukcí use nebo kvalifikováním názvu
identifikátoru jmenným prostorem. Následující příklad odkazuje na funkci myFunction() pomocí instrukce use:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 43
Jazyk ActionScript a jeho syntaxe
use namespace version1;
myFunction();
Můžete také použít kvalifikovaný název pro odkazování na funkci myFunction(), jak je vidět na následujícím
příkladu:
version1::myFunction();
Definování jmenných prostorů
Jmenné prostory obsahují jednu hodnotu, Univerzální identifikátor zdroje (URI - Uniform Resource Identifier), která
se někdy nazývá název jmenného prostoru. URI umožňuje zajistit, aby definice jmenného prostoru byla jedinečná.
Vytváříte jmenný prostor deklarováním definice jmenného prostoru jedním ze dvou způsobů. Můžete buď definovat
jmenný prostor s explicitní URI, jako byste definovali jmenný prostor XML, nebo můžete URI vynechat. Následující
příklad ukazuje, jak lze jmenný prostor definovat pomocí URI:
namespace flash_proxy = "http://www.adobe.com/flash/proxy";
URI slouží jako unikátní identifikační řetězec pro daný jmenný prostor. Pokud vynecháte URI, jako v následujícím
příkladu, kompilátor vytvoří jedinečný vnitřní identifikační řetězec na místě URI. K tomuto vnitřnímu
identifikačnímu řetězci nemáte přístup.
namespace flash_proxy;
Jakmile definujete jmenný prostor, s URI nebo bez, tento jmenný prostor nelze předefinovat ve stejném rozsahu.
Pokus o definování jmenného prostoru, jak bylo uvedeno výše ve stejném rozsahu, vede k chybám kompilátoru.
Pokud je jmenný prostor definován v balíčku nebo třídě, jmenný prostor nemůže být viditelný pro kód vně tohoto
balíčku nebo třídy, pokud není použit příslušný specifikátor řízení přístupu. Například následující kód zobrazuje
flash_proxy jmenný prostor definovaný v balíčku flash.utils. V následujícím příkladu chybějící specifikátor řízení
přístupu znamená, že jmenný prostor flash_proxy bude viditelný pouze pro kód v balíčku flash.utils a nebude
viditelný pro kód vně tohoto balíčku:
package flash.utils
{
namespace flash_proxy;
}
Následující kód využívá atribut public pro zviditelnění jmenného prostoru flash_proxy pro kód vně balíčku:
package flash.utils
{
public namespace flash_proxy;
}
Použití jmenných prostor
Použití jmenných prostor znamená vložení definice do jmenného prostoru. Definice, které lze vložit do jmenného
prostoru zahrnují funkce, proměnné a konstanty (třídu do vlastního jmenného prostoru vložit nelze).
Zvažte například funkci deklarovanou pomocí jmenného prostoru řízení přístupu public. Pomocí atributu public v
definici funkce vloží funkci do veřejného jmenného prostoru, což ji zpřístupní pro veškerý kód. Jakmile definujete
jmenný prostor, můžete použít jmenný prostor, který jste definovali a to stejným způsobem, jako byste použili atribut
public a definice bude dostupná pro kód, který může odkazovat na váš vlastní jmenný prostor. Pokud například
definujete jmenný prostor example1, můžete přidat metodu nazvanou myFunction() pomocí example1 jako
atributu, jak je vidět na následujícím příkladu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 44
Jazyk ActionScript a jeho syntaxe
namespace example1;
class someClass
{
example1 myFunction() {}
}
Deklarování metody myFunction() pomocí jmenného prostoru example1 jako atributu znamená, že metoda náleží
jmennému prostoru example1.
Při použití jmenného prostoru byste měli mít na paměti následující:
• Můžete použít pouze jeden jmenný prostor pro každou deklaraci.
• Neexistuje žádný způsob, jak aplikovat atribut jmenného prostoru pro více než jednu definici najednou. Jinými
slovy, pokud chcete použít svůj jmenný prostor na deset různých funkcí, musíte přidat jmenné prostory jako atribut
k jedné z deseti definic funkcí.
• Pokud použijete pouze jmenný prostor, nemůžete také uvést specifikátor řízení přístupu, protože jmenné prostory
a specifikátory řízení přístupu se vzájemně vylučují. Jinými slovy, nemůžete deklarovat funkci nebo vlastnosti jako
public, private, protected nebo internal kromě použití jmenného prostoru.
Odkazování jmenných prostory
Není nutné explicitně definovat odkaz na jmenný prostor, když použijete metodu nebo vlastnost deklarovanou
pomocí kteréhokoliv jmenného prostoru řízení přístupu, například public, private, protected a internal. Tak
tomu je proto, že přístup k těmto speciálním jmenným prostorům je řízen kontextem. Například definice vložené do
jmenného prostoru private jsou automaticky dostupné kódu ve stejné třídě. Pro vámi definované jmenné prostory
nicméně taková citlivost na kontext neexistuje. Chcete-li použít metodu nebo vlastnosti, kterou jste vložili do vlastního
jmenného prostoru, musíte jmenný prostor odkazovat.
Jmenný prostor můžete odkazovat s použitím instrukce use namespace nebo můžete kvalifikovat název se jmenným
prostorem pomocí symbolu kvalifikátoru názvu (::). Odkazování jmenného prostoru pomocí instrukce use
namespace „otevře” jmenný prostor, takže jej lze použít pro všechny identifikátory, které nejsou kvalifikované. Pokud
jste například definovali jmenný prostor example1, můžete přistupovat k názvům v tomto jmenném prostoru pomocí
use namespace example1:
use namespace example1;
myFunction();
Můžete otevřít více než jeden jmenný prostor najednou. Jakmile otevřete jmenný prostor s use namespace, zůstane
otevřený v celém bloku kódu, ve kterém byl otevřen. Neexistuje žádný způsob, jak explicitně jmenný prostor uzavřít.
Pokud budete mít otevřený více než jeden jmenný prostor, zvyšuje se tak pravděpodobnost konfliktu názvů. Pokud
dáváte přednost neotevírání jmenného prostoru, můžete se vyhnout instrukci use namespace kvalifikováním názvu
metody nebo vlastnosti s jmenným prostorem a symbolem kvalifikátoru jména. Například následující kód znázorňuje,
jak lze kvalifikovat název myFunction() pomocí jmenného prostoru example1:
example1::myFunction();
Použití jmenného prostoru
Ve třídě flash.utils.Proxy, která je součástí jazyka ActionScript 3.0, můžete nalézt reálný příklad jmenného prostoru,
který je použit k zabránění konfliktům názvů. Třída Proxy, která je náhradou za Object.__resolve z jazyka
ActionScript 2.0 umožňuje sledovat odkazy k nedefinovaným vlastnostem nebo metodám předtím, než se vyskytne
chyba. Všechny metody třídy Proxy spočívají v jmenném prostoru flash_proxy, aby se zabránilo konfliktu názvů.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 45
Jazyk ActionScript a jeho syntaxe
Pro lepší porozumění použití jmenného prostoru flash_proxy je nutné porozumět použití třídy Proxy. Funkce třídy
Proxy je dostupná pouze třídám které z ní pocházejí. Jinými slovy, pokud chcete používat metody třídy Proxy na
objekt, musí definice třídy objektu rozšiřovat třídu Proxy. Pokud chcete například sledovat pokusy volání
nedefinované metody, rozšířili byste třídu Proxy a pak potlačili metodu callProperty() třídy Proxy.
Můžete si pamatovat, že implementování jmenného prostoru je obvykle proces složený ze tří kroků definování, použití
a pak odkazování jmenného prostoru. Protože nikdy explicitně nevoláte metody třídy Proxy, jmenný prostor
flash_proxy je pouze definován a použit, ale nikdy není referencován. ActionScript 3.0, definuje jmenný prostor
flash_proxy a použije jej na třídu Proxy. Kód musí pouze aplikovat jmenný prostor flash_proxy na třídy, které
rozšiřují třídu Proxy.
Jmenný prostor flash_proxy je definován v balíčku flash.utils způsobem obdobný následujícímu:
package flash.utils
{
public namespace flash_proxy;
}
Jmenný prostor je aplikován na metody třídy Proxy, jak je znázorněno v následujícím výňatku z třídy Proxy:
public class Proxy
{
flash_proxy function callProperty(name:*, ... rest):*
flash_proxy function deleteProperty(name:*):Boolean
...
}
jak ukazuje následující kód, musíte nejprve importovat třídu Proxy a pak jmenný prostor flash_proxy. Musíte pak
deklarovat svou třídu tak, aby rozšiřovala třídu Proxy (v případě, že kompilujete v přísném režimu, musíte také přidat
atribut dynamic). Když potlačíte metodu callProperty(), musíte použít jmenný prostor flash_proxy.
package
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
dynamic class MyProxy extends Proxy
{
flash_proxy override function callProperty(name:*, ...rest):*
{
trace("method call intercepted: " + name);
}
}
}
Pokud vytvoříte instanci třídy MyProxy a zavoláte nedefinovanou metodu, například metodu testing() volanou v
následujícím příkladu, objekt Proxy sleduje volání metody a vykonává příkazy uvnitř potlačené metody
callProperty() (v tomto případě jednoduchý příkaz trace()).
var mySample:MyProxy = new MyProxy();
mySample.testing(); // method call intercepted: testing
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 46
Jazyk ActionScript a jeho syntaxe
Existují dvě výhody, proč mít metody třídy Proxy uvnitř jmenného prostoru flash_proxy. První, mít samostatné
jmenné prostory redukuje nepořádek ve veřejném rozhraní jakékoliv třídy, která rozšiřuje třídu Proxy. (Existuje asi
tucet metod v třídě Proxy, které můžete potlačit, všechny nejsou navrženy pro přímé volání. Jejich umístění do
veřejného jmenného prostoru může být matoucí.) Druhá, použití jmenného prostoru flash_proxy zabraňuje
konfliktu názvů v případě, že vaše podtřída Proxy obsahuje metody instance s názvy odpovídajícími metodám třídy
Proxy. Můžete například chtít pojmenovat jednu z vlastních metod callProperty(). Následující kód je přijatelný,
protože vaše verze metody callProperty() je v jiném jmenném prostoru.
dynamic class MyProxy extends Proxy
{
public function callProperty() {}
flash_proxy override function callProperty(name:*, ...rest):*
{
trace("method call intercepted: " + name);
}
}
Jmenné prostory mohou být také užitečné v případě, že chcete zajistit přístup k metodám nebo vlastnostem způsobem,
který nelze uskutečnit se čtyřmi specifikátory řízení přístupu (public, private, internal a protected). Například
můžete mít několik pomocných meto, které jsou rozprostřeny v několika balíčcích. Chcete například všechny tyto
metody zpřístupnit všem svým balíčkům, ale nechcete je mít veřejně přístupné. To uskutečníte tak, že vytvoříte nový
jmenný prostor a použijete jej jako vlastní speciální specifikátor řízení přístupu.
Následující příklad používá uživatelem definovaný jmenný prostor k seskupení dvou funkcí, které spočívají v různých
balíčcích. Jejich seskupením do stejného jmenného prostoru můžete obě funkce zviditelnit ve třídě nebo balíčku
pomocí jediného příkazu use namespace.
Tento příklad používá čtyři soubory k demonstrování této techniky. Všechny soubory musí být v cestě pro třídu. První
soubor, myInternal.as, se použije pro definování jmenného prostoru myInternal. Protože soubor je v balíčku
pojmenovaném podle příkladu, musíte umístit soubor do složky pojmenované podle příkladu. Jmenný prostor je
označen jako public, takže jej lze importovat do ostatních balíčků.
// myInternal.as in folder example
package example
{
public namespace myInternal = "http://www.adobe.com/2006/actionscript/examples";
}
Druhý a třetí soubor, Utility.as a Helper.as, definují třídy obsahující metody, které by měly být dostupné pro ostatní
balíčky. Třída Utility je v balíčku example.alpha, což znamená, že soubor by měl být umístěn dovnitř složky
pojmenované alpha, která je podsložkou složky v příkladu. Třída Helper je v balíčku example.beta, což znamená, že
soubor by měl být umístěn dovnitř složky pojmenované beta, která je podsložkou složky v příkladu. Oba tyto balíčky,
example.alpha i example.beta, musí importovat jmenný prostor před jeho použitím.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 47
Jazyk ActionScript a jeho syntaxe
// Utility.as in the example/alpha folder
package example.alpha
{
import example.myInternal;
public class Utility
{
private static var _taskCounter:int = 0;
public static function someTask()
{
_taskCounter++;
}
myInternal static function get taskCounter():int
{
return _taskCounter;
}
}
}
// Helper.as in the example/beta folder
package example.beta
{
import example.myInternal;
public class Helper
{
private static var _timeStamp:Date;
public static function someTask()
{
_timeStamp = new Date();
}
myInternal static function get lastCalled():Date
{
return _timeStamp;
}
}
}
Čtvrtý soubor, NamespaceUseCase.as, je hlavní třídou aplikaci a měl by být příbuzným složky příkladu. V aplikaci
Adobe Flash CS4 Professional tato třída bude použita jako třída dokumentu pro FLA. Třída NamespaceUseCase
rovněž importuje jmenný prostor myInternal a používá jej pro zavolání statických metod, které spočívají v jiných
balíčcích. Příklad používá statické metody pouze pro zjednodušení kódu. Statické a instanční metody mohou být
vloženy do jmenného prostoru myInternal.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 48
Jazyk ActionScript a jeho syntaxe
// NamespaceUseCase.as
package
{
import flash.display.MovieClip;
import example.myInternal; // import namespace
import example.alpha.Utility;// import Utility class
import example.beta.Helper;// import Helper class
public class NamespaceUseCase extends MovieClip
{
public function NamespaceUseCase()
{
use namespace myInternal;
Utility.someTask();
Utility.someTask();
trace(Utility.taskCounter); // 2
Helper.someTask();
trace(Helper.lastCalled); // [time someTask() was last called]
}
}
}
Proměnné
Proměnné umožňují uložit hodnoty, které v programu používáte. Pro deklarování proměnné musíte použít příkaz var
s názvem proměnné. V jazyce ActionScript 2.0 se použití příkazu var vyžaduje pouze v případě, že používáte anotace
type. V jazyce ActionScript 3.0 je použití příkazu var vyžadováno vždy. Například následující řádek jazyka
ActionScript deklaruje proměnnou pojmenovanou i:
var i;
Pokud vynecháte příkaz var když proměnnou deklarujete, zobrazí se chyba kompilátoru v přísném režimu a chyba
spuštění v režimu standardní. Například následující řádek kódu způsobí chybu v případě, že proměnná i nebyla
definována dříve:
i; // error if i was not previously defined
Pro spojení proměnné s datovým typem musíte toto učinit, když deklarujete proměnnou. Deklarování proměnné bez
označení jejího typu je povoleno, ale způsobí výstrahu kompilátoru v přísném režimu. Typ proměnné definujete
připojením dvojtečky (:) za název a typem proměnné. Například následující kód deklarujete proměnnou i typu int:
var i:int;
Můžete přiřadit hodnotu proměnné pomocí operátoru (=). Například následující kód deklarujete proměnnou i a
přiřazuje jí hodnotu 20:
var i:int;
i = 20;
Patrně bude pohodlnější přiřadit hodnotu proměnné ve stejný okamžik, když deklarujete proměnnou, jako v
následujícím příkladu:
var i:int = 20;
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 49
Jazyk ActionScript a jeho syntaxe
Technika přiřazování hodnoty proměnné v době její deklarace je běžně použita nejenom pro přiřazování primitivních
hodnot, jako jsou celočíselné hodnoty a řetězce, ale také při vytváření pole nebo konkretizaci instance třídy.
Následující příklad zobrazuje pole, které má deklarovanou a přiřazenou hodnotu pomocí jedné řádky kódu.
var numArray:Array = ["zero", "one", "two"];
Můžete vytvořit instanci třídy pomocí operátoru new. Následující příklad vytváří instanci pojmenovanou
CustomClass a přiřazuje referenci nově vytvořené instanci třídy proměnné pojmenované customItem:
var customItem:CustomClass = new CustomClass();
Pokud máte pro deklarován více než jednu proměnnou, můžete deklarovat všechny v jedné řádce pomocí operátoru
čárka (,) a proměnné tak oddělit. Například následující kód deklarujete tři proměnné v jedné řádce kódu:
var a:int, b:int, c:int;
Můžete také přiřadit hodnoty každé proměnné ve stejné řádce kódu. Například následující kód deklaruje tři proměnné
(a, b a c) a přiřazuje každé hodnotu:
var a:int = 10, b:int = 20, c:int = 30;
I když můžete použít operátor čárka pro seskupení deklarace proměnných do jednoho příkazu, může to snížit čitelnost
kódu.
Porozumění rozsahu proměnných
Rozsah proměnné představuje oblast kódu, kde může být proměnná zpřístupněna lexikálním odkazem. Globální
proměnná je taková, která je definovaná ve všech oblastech kódu, zatímco lokální proměnná je taková, která je
definována pouze v jedné části kódu. V jazyce ActionScript 3.0 mají proměnné vždy přiřazen rozsah funkce nebo třídy,
ve které jsou deklarované. Globální proměnná je taková, kterou definujete vně funkce nebo definice třídy. Například
následující kód vytváří globální proměnnou strGlobal jejím deklarováním vně veškerých funkcí. Příklad ukazuje, že
globální proměnná je k dispozici uvnitř a vně definice funkce.
var strGlobal:String = "Global";
function scopeTest()
{
trace(strGlobal); // Global
}
scopeTest();
trace(strGlobal); // Global
Místní proměnou deklarujete pomocí proměnné uvnitř definice funkce. Nejmenší oblast kódu, pro kterou lze
definovat místní proměnnou, je definice funkce. Místní proměnná deklarovaná v rámci funkce bude existovat pouze
v této funkci. Pokud například deklarujete proměnnou pojmenovanou str2 v rámci funkce nazvané localScope(),
tato proměnná nebude vně funkce dostupná.
function localScope()
{
var strLocal:String = "local";
}
localScope();
trace(strLocal); // error because strLocal is not defined globally
Pokud název proměnné použité jako místní proměnná bude již deklarován jako globální proměnná, místní definice
skryje (nebo vytvoří stín) globální definici, když bude místní proměnná v jejím rozsahu. Globální proměnná se stále
vyskytuje vně funkce. Například následující kód vytváří globální řetězcovou proměnnou pojmenovanou str1 a pak
vytváří místní proměnou stejného názvu uvnitř funkce scopeTest(). Příkaz trace uvnitř funkce odesílá na výstup
místní hodnotu proměnné, ale příkaz trace vně funkce odesílá na výstup globální hodnotu proměnné.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 50
Jazyk ActionScript a jeho syntaxe
var str1:String = "Global";
function scopeTest ()
{
var str1:String = "Local";
trace(str1); // Local
}
scopeTest();
trace(str1); // Global
Proměnné jazyka ActionScript, na rozdíl od proměnných v C++ a Java, nemají rozsah blok-úroveň. Blok kódu je
skupinou příkazů mezi levou složenou závorkou ( { ) a pravou složenou závorkou ( } ). V některých programovacích
jazycích, například C++ a Java, proměnné deklarované uvnitř bloku kódu nejsou dostupné vně tohoto bloku. Toto
omezení je nazváno rozsah blok-úroveň a v jazyce ActionScript neexistuje. Pokud deklarujete proměnnou uvnitř
bloku kódu, tato proměnná nebude dostupná pouze v tomto bloku kódu, ale také v ostatních částech funkce, ke které
blok kódu náleží. Například následující funkce obsahuje proměnné, které jsou definované v různých rozsazích bloku.
Všechny proměnné jsou dostupné prostřednictvím funkce.
function blockTest (testArray:Array)
{
var numElements:int = testArray.length;
if (numElements > 0)
{
var elemStr:String = "Element #";
for (var i:int = 0; i < numElements; i++)
{
var valueStr:String = i + ": " + testArray[i];
trace(elemStr + valueStr);
}
trace(elemStr, valueStr, i); // all still defined
}
trace(elemStr, valueStr, i); // all defined if numElements > 0
}
blockTest(["Earth", "Moon", "Sun"]);
Zajímavým dopadem neexistence rozsahu blok-úroveň je to, že můžete číst proměnnou nebo do ní zapisovat předtím,
než je deklarovaná, pokud je deklarovaný před ukončením funkce. Tak tomu je díky technice nazvané zvedání, což
znamená, že kompilátor přesouvá všechny deklarace proměnných na horní stranu funkce. Například následující kód
je zkompilován i v případě, že se počáteční funkce trace() pro proměnnou num vyskytuje před deklarováním
proměnné num:
trace(num); // NaN
var num:Number = 10;
trace(num); // 10
Kompilátor však "nezvedne" žádné příkazy přiřazení. To vysvětluje, proč počáteční trace() proměnné num vede k NaN
(není číslo), což je výchozí hodnota proměnných datového typu Number. To znamená, že můžete přiřadit hodnoty
proměnným ještě před jejich deklarováním, jak je vidět v následujícím příkladu:
num = 5;
trace(num); // 5
var num:Number = 10;
trace(num); // 10
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 51
Jazyk ActionScript a jeho syntaxe
Výchozí hodnoty
Výchozí hodnota je hodnota, kterou proměnná obsahuje před nastavením její hodnoty. Proměnnou inicializujete, když
poprvé nastavíte její hodnotu. Pokud deklarujete proměnou, ale nenastavíte její hodnotu, tato proměnná bude
neinicializovaná. Hodnota neinicializované proměnné závisí na datovém typu. Následující tabulka popisuje výchozí
hodnoty proměnných organizované podle datového typu:
Typ dat
Výchozí hodnota
Boolean
false
int
0
Number
NaN
Object
null
String
null
uint
0
Není deklarováno (ekvivalent anotaci typu *)
undefined
Všechny ostatní třídy, včetně uživatelem definovaných tříd.
null
Pro proměnné typu Number je výchozí hodnota NaN (není číslo), což je speciální hodnota definovaná standardem
IEEE-754 pro vyjádření hodnoty, která nepředstavuje číslo.
Pokud deklarujete proměnnou, ale nikoliv její datový typ, bude platit výchozí datový typ *, což ve skutečnosti
znamená, že proměnná je bez typu. Pokud také neinicializujete proměnnou bez typu pomocí hodnoty, její výchozí
hodnota je undefined.
Pro datové typy jiné, než Boolean, Number, int a uint je výchozí hodnota kterékoliv proměnné null. To platí pro
všechny třídy definované jazykem ActionScript 3.0, stejně jako pro všechny vlastní třídy, které vytvoříte.
Hodnota null není platnou hodnotou pro proměnné typu Boolean, Number, int nebo uint. Pokud se pokusíte přiřadit
hodnotu null takové proměnné, hodnota je převedena na výchozí hodnotu pro daný datový typ. Pro proměnné typu
Object můžete přiřadit hodnotu null. Pokud se pokusíte přiřadit hodnotu undefined proměnné typu Object,
hodnota je převedena na null.
Pro proměnné typu Number existuje speciální funkce horní úrovně pojmenovaná isNaN(), která vrací booleovskou
hodnotu true v případě, že proměnná není číslem, jinak vrací hodnotu false.
Typy dat
Datový typ definuje soubor hodnot. Například datový typ booleovská hodnota je souborem přesně dvou hodnot: true
a false. Kromě datového typu booleovská hodnota jazyk ActionScript 3.0 definuje několik běžně používaných
datových typů, například String, Number a Array. Můžete definovat vlastní datové typy pomocí tříd nebo rozhraní a
definovat tak vlastní soubor hodnot. Všechny hodnoty v jazyce ActionScript 3.0, ať už primitivní nebo komplexní, jsou
objekty.
Primitivní hodnota je hodnota náležející jednomu z následujících datových typů: booleovský, int, Number, String a
uint. Práce s primitivními hodnotami je obvykle rychlejší než s komplexními hodnotami, protože jazyk ActionScript
ukládá primitivní hodnoty speciálním způsobem, které umožňuje optimalizaci paměti a rychlosti.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 52
Jazyk ActionScript a jeho syntaxe
Poznámka: Pro čtenáře se zájmem o technické podrobnosti jazyk ActionScript ukládá primitivní hodnoty interně jako
nezměnitelné objekty. Ve skutečnosti to, že jsou uloženy jako nezměnitelné objekty znamená, že předání odkazem je
efektivně shodné jako předání hodnotou. To snižuje využití paměti a zvyšuje rychlost vykonávání, protože odkazy jsou
obvykle výrazně menší než hodnoty samotné.
Komplexní hodnota je hodnota, která není primitivní. Datové typy definující komplexní hodnoty zahrnují: Array,
Date, Error, Function, RegExp, XML a XMLList.
Mnoho programovacích jazyků odlišuje mezi primitivními hodnotami a jejich objekty obalu. Například jazyk Java má
primitivní hodnotu int a třídu java.lang.Integer, která jí obaluje. Primitivní hodnoty Java nejsou objekty, ale jejich
obaly ano, což činí primitivní hodnoty užitečné pro jedny operace a objekty obalu vhodnější pro jiné operace. V jazyku
ActionScript 3.0 primitivní hodnoty a jejich objekty obalu jsou z praktických účelů nerozlišitelné. Všechny hodnoty, i
primitivní hodnoty, jsou objekty. Aplikace Flash Player a Adobe AIR pracují s těmito primitivními typy jako se
speciálními případy, které se chovají jako objekty, ale nevyžaduje normální doplňky související s vytvářením objektů.
To znamená, že následující dva řádky kódu jsou shodné:
var someInt:int = 3;
var someInt:int = new int(3);
Všechny primitivní a komplexní datové typy uvedené výše jsou definovány třídami jádra jazyka ActionScript 3.0.
Třídy jádra umožňují vytvářet objekty pomocí liberálových hodnot namísto pomocí operátoru new. Například můžete
vytvořit pole pomocí literálové hodnoty nebo konstruktoru třídy Array, a to takto:
var someArray:Array = [1, 2, 3]; // literal value
var someArray:Array = new Array(1,2,3); // Array constructor
Kontrola typu
Kontrola typu může nastat buď v čase kompilace nebo v čase spuštění. Staticky zadávané jazyky, například C++ a Java,
provádějí kontrolu typu v okamžiku kompilace. Dynamicky zadávané jazyky, například Smalltalk a Python, provádějí
kontrolu typu v okamžiku spuštění. Jako dynamicky zadávaný má jazyk ActionScript 3.0 kontrolu typu během
spouštění, ale podporuje také kontrolu během kompilace díky speciálnímu režimu kompilátoru, nazvanému přísný
režim. V přísném režimu kontrola typu nastává v čase kompilace i spuštění, ale ve standardním režimu pouze v čase
spuštění.
Dynamicky zadávané jazyky nabízejí vynikající flexibilitu když svůj kód strukturujete, ale za cenu toho, že se chyby
typu projeví až v době spuštění. Staticky zadávané jazyky hlásí chyby typu v době kompilace, ale za cenu toho, že
vyžaduje známost informace typu v čase kompilace.
Kontrola typu v čase kompilace
Kontrola typu v čase kompilace je často vhodnější u větších projektů, protože s rostoucí velikostí projektu se obvykle
důležitost flexibility datového typu snižuje, na rozdíl od odstranění chyb typu, která je nutná co nejdříve. Proto je
standardně kompilátor jazyka ActionScript v aplikaci Adobe Flash CS4 Professional a Adobe Flex Builder nastaven na
spouštění v přísném režimu.
Pro zajištění kontroly typu v čase kompilace vyžaduje, aby kompilátor znal informace o datovém typu pro proměnné
nebo výrazy ve vašem kódu. Chcete-li explicitně deklarovat datový typ pro proměnnou, přidejte operátor dvojtečku
(:) následovanou datovým typem jako příponou názvu proměnné. Chcete-li připojit k datovému typu parametr,
použijte operátor dvojtečku následovanou datovým typem. Například následující kód přidává informaci o datovém
typu k parametru xParam a deklaruje proměnnou myParam s explicitním datovým typem:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 53
Jazyk ActionScript a jeho syntaxe
function runtimeTest(xParam:String)
{
trace(xParam);
}
var myParam:String = "hello";
runtimeTest(myParam);
V přísném režimu kompilátor jazyka ActionScript hlásí neshody typu jako chyby kompilátoru. Například následující
kód deklaruje parametr funkce xParam typu Object, ale později se pokusí přiřadit hodnoty typu String a Number
tomuto parametru. To v přísném režimu vede k chybě kompilátoru.
function dynamicTest(xParam:Object)
{
if (xParam is String)
{
var myStr:String = xParam; // compiler error in strict mode
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam; // compiler error in strict mode
trace("Number: " + myNum);
}
}
I v přísném režimu se můžete selektivně rozhodnout pro kontrolu v čase kompilace a to ponecháním pravé straně
přiřazovacího příkazu nezadané. Můžete označit proměnnou nebo výraz jako bez typu buď vynecháním anotace typu
nebo pomocí speciální anotace typu hvězdičky (*). Například pokud bude parametr xParam v předchozím příkladu
modifikován tak, aby již neměl anotaci typu, kód bude zkompilován v přísném režimu:
function dynamicTest(xParam)
{
if (xParam is String)
{
var myStr:String = xParam;
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam;
trace("Number: " + myNum);
}
}
dynamicTest(100)
dynamicTest("one hundred");
Kontrola typu v době spuštění
Kontrola typu v době spuštění nastává v jazyce ActionScript 3.0 bez ohledu na to, zda kompilaci provádíte v přísném
nebo standardním režimu. Zvažte situaci, ve které je hodnota 3 předána jako argument funkci, která očekává pole. V
přísném režimu kompilátor vygeneruje chybu, protože hodnota 3 není kompatibilní s datovým typem Array. Pokud
přísný režim vypnete a spustíte standardní režim, kompilátor nebude neshodu typu signalizovat, ale kontrola s
okamžiku spuštění aplikace Flash Player a Adobe AIR povede k signalizaci chyby spuštění.
Následující příklad zobrazuje funkci pojmenovanou typeTest(), která očekává argument Array, avšak předána je
hodnota 3. To způsobí chybu v okamžiku spuštění ve standardním režimu, protože hodnota 3 není členem datového
typu (Array) deklarovaných pro parametr.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 54
Jazyk ActionScript a jeho syntaxe
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum:Number = 3;
typeTest(myNum);
// run-time error in ActionScript 3.0 standard mode
Mohou také nastat situace, kde se zobrazí chyba dat při spuštění, i když pracujete v přísném režimu. To je možné v
případě použití přísného režimu, ale rozhodnete se nepoužívat kontrolu v okamžiku kompilace pomocí proměnné bez
stanoveného typu. Když použijete proměnnou bez stanoveného typu, neeliminujete kontrolu typu, ale spíše ji
odkládejte na dobu spuštění. Pokud například proměnná myNum v předchozím příkladu nemá deklarovaný datový typ,
kompilátor nemůže detekovat neshodu typu, ale aplikace Flash Player a Adobe AIR vygenerují chybu v době spuštění,
protože porovnají hodnotu v době spuštění myNum, která je nastavena na 3 jako důsledek příkazu přiřazení, s typem
xParam, který je nastaven na datový typ Array.
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum = 3;
typeTest(myNum);
// run-time error in ActionScript 3.0
Kontrola typu v době spuštění rovněž umožňuje flexibilnější použití dědičnosti, než kontrola v době kompilace.
Odložením kontroly typu na dobu spuštění ve standardním režimu umožňuje odkazovat vlastnosti podtřídy i v
případě povýšení. Povýšení nastává v případě, že použijete základní třídu k deklarování typu instance třídy, ale ke
konkretizaci použijete podtřídu. Můžete například vytvořit třídu pojmenovanou ClassBase, která může být rozšířena
(třídy s atributem final nemohou být rozšířeny):
class ClassBase
{
}
Poté vytvoříte podtřídu pro ClassBase pojmenovanou ClassExtender, která má jednu vlastnost pojmenovanou
someString, a to takto:
class ClassExtender extends ClassBase
{
var someString:String;
}
Pomocí obou tříd můžete vytvořit instanci třídy, která je deklarovaná pomocí datového typu ClassBase, ale
konkretizována je pomocí konstruktoru ClassExtender. Povýšení je považováno za bezpečnou operaci, protože
základní třída neobsahuje žádné vlastnosti nebo metody, které nejsou v podtřídě.
var myClass:ClassBase = new ClassExtender();
Podtřída však neobsahuje vlastnosti nebo metody, které nemá základní třída. Například třída ClassExtender obsahuje
vlastnost someString, která ve třídě ClassBase neexistuje. V jazyce ActionScript 3.0 ve standardním režimu můžete
odkazovat tuto vlastnost pomocí instance myClass bez generování chyby v době kompilace, jak je vidět na
následujícím příkladu:
var myClass:ClassBase = new ClassExtender();
myClass.someString = "hello";
// no error in ActionScript 3.0 standard mode
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 55
Jazyk ActionScript a jeho syntaxe
Operátor is
Operátor is, který je v případě ActionScript 3.0 nový, umožňuje testovat, zda je proměnná nebo výraz členem daného
datového typu. V předchozí verzi jazyka ActionScript operátor instanceof zajišťovat tutéž funkci, ale v ActionScript
3.0 operátor instanceof by neměl být k testování členství v datovém typu používán. Operátor is by měl být použit
namísto operátoru instanceof pro ruční kontrolu typu, protože výraz x instanceof y pouze kontroluje
prototypový řetězec x, zda-li existuje y (a v ActionScript 3.0 prototypový řetězec neposkytuje kompletní obraz o
hierarchii dědičnosti).
Operátor is prověřuje správnou hierarchii dědičnosti a lze jej použít ke kontrole nejenom zda je objekt instancí
specifické třídy, ale také ke kontrole, zda je objekt instancí třídy, která implementuje specifické rozhraní. Následující
příklad vytváří instanci třídy Sprite pojmenovanou mySprite a používá operátor is k testování, zda je mySprite
instancí tříd Sprite a DisplayObject a zda implementuje rozhraní IEventDispatcher:
var mySprite:Sprite = new Sprite();
trace(mySprite is Sprite); // true
trace(mySprite is DisplayObject);// true
trace(mySprite is IEventDispatcher); // true
Operátor is kontroluje hierarchii dědičnosti a správně hlásí, že mySprite je kompatibilní s třídami Sprite a
DisplayObject (třída Sprite je podtřídou třídy DisplayObject). Operátor is rovněž kontroluje, zda je mySprite
odvozená z některých tříd, které implementují rozhraní IEventDispatcher. Protože třída Sprite je odvozená z třídy
EventDispatcher, která implementuje rozhraní IEventDispatcher, operátor is správně hlásí, že mySprite
implementuje stejné rozhraní.
Následující příklad zobrazuje stejné testy z předchozího příkladu, avšak s operátorem instanceof namísto is.
Operátor instanceof správně identifikuje, že mySprite je instancí Sprite nebo DisplayObject, ale vrací false, když
je použit pro testování, zda mySprite implementuje rozhraní IEventDispatcher.
trace(mySprite instanceof Sprite); // true
trace(mySprite instanceof DisplayObject);// true
trace(mySprite instanceof IEventDispatcher); // false
Operátor as
Operátor as, který je v jazyce ActionScript 3.0 nový, rovněž umožňuje kontrolovat, zda je výraz členem daného
datového typu. Na rozdíl od operátoru is nevrací operátor as booleovskou hodnotu. Místo toho operátor as vrací
hodnotu výrazu, namísto true a hodnotu null namísto false. Následující příklad ukazuje výsledky použití operátoru
as místo operátoru is v jednoduchém případě kontroly, zda je instance Sprite členem datových typů DisplayObject,
IEventDispatcher a Number.
var mySprite:Sprite = new Sprite();
trace(mySprite as Sprite); // [object Sprite]
trace(mySprite as DisplayObject); // [object Sprite]
trace(mySprite as IEventDispatcher); // [object Sprite]
trace(mySprite as Number);
// null
Když použijete operátor as, operand na pravé straně musí být datovým typem. Pokus použít výraz jiný, než datový typ
na pravé straně povede k chybě.
Dynamické třídy
Dynamické třídy definují objekt, který může být změně v době spuštění přidáním nebo změnou vlastností a metod.
Třída, která není dynamická, například String, je zapouzdřenou třídou. Nemůžete přidávat vlastnosti nebo metody do
zapouzdřené třídy v době spuštění.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 56
Jazyk ActionScript a jeho syntaxe
Dynamické třídy vytváříte pomocí atributu dynamic při deklarování třídy. Například následující kód vytváří
dynamickou třídu pojmenovanou Protean:
dynamic class Protean
{
private var privateGreeting:String = "hi";
public var publicGreeting:String = "hello";
function Protean()
{
trace("Protean instance created");
}
}
Pokud následovně konkretizujete instanci třídy Protean, můžete k ní přidat vlastnosti nebo metody vně definice třídy.
Například následující kód vytváří instanci třídy Protean a přidává vlastnost pojmenovanou aString a vlastnost
pojmenovanou aNumber do instance:
var myProtean:Protean = new Protean();
myProtean.aString = "testing";
myProtean.aNumber = 3;
trace(myProtean.aString, myProtean.aNumber); // testing 3
Vlastnosti přidané do instance dynamické třídy jsou entity spuštění, takže jakákoliv kontrola typu je prováděna v době
spuštění. Nemůžete přidat anotaci typu k vlastnosti, kterou přidáváte tímto způsobem.
Můžete také přidat metodu instanci myProtean definování funkce a připojením funkce k vlastnosti instance
myProtean. Následující kód přesouvá příkaz trace do metody pojmenované traceProtean():
var myProtean:Protean = new Protean();
myProtean.aString = "testing";
myProtean.aNumber = 3;
myProtean.traceProtean = function ()
{
trace(this.aString, this.aNumber);
};
myProtean.traceProtean(); // testing 3
Metody takto vytvořené nemají přístup k žádným soukromým vlastnostem nebo metodám třídy Protean. Kromě toho,
i reference na veřejné vlastnosti nebo metody třídy Protean musí být kvalifikovaná buď klíčový slovem this nebo
názvem třídy. Následující příklad ukazuje metodu traceProtean() pokoušející se o přístup k soukromé a veřejné
proměnné třídy Protean.
myProtean.traceProtean = function ()
{
trace(myProtean.privateGreeting); // undefined
trace(myProtean.publicGreeting); // hello
};
myProtean.traceProtean();
Popisy typů dat
Primitivní datové typy zahrnují Boolean, int, Null, Number, String, uint a void. Třídy jádra ActionScript rovněž
definují následující komplexní datové typy: Object, Array, Date, Error, Function, RegExp, XML a XMLList.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 57
Jazyk ActionScript a jeho syntaxe
Datový typ Boolean
Datový typ Boolean je tvořen dvěma hodnotami: true (pravda) a false (nepravda). Pro booleovskou hodnotu nejsou
platné žádné jiné hodnoty. Výchozí hodnota booleovské proměnné, která byla deklarovaná, avšak neinicializována, je
false.
Datový typ int
Datový typ int je uložen interně jako 32bitová celočíselná hodnota a je tvořena souborem celých čísel od
-2 147 483 648 (-231) do 2 147 483 647 (231 - 1) včetně. Předchozí verze jazyka ActionScript nabízely pouze datový typ
Number, který byl používán pro celočíselné hodnoty a hodnoty s desetinnou čárkou. V jazyce ActionScript 3.0 nyní
máte přístup k nízko úrovňovým typům pro 32bitové celočíselné hodnoty se znaménkem nebo bez něj. Pokud
proměnné nebude používat desetinná čísla, použití datového typu int místo Number by mělo být rychlejší a účinnější.
Pro celočíselné hodnoty mimo rozsah minimální a maximální hodnoty int použijte datový typ Number, který dokáže
pracovat s hodnotami mezi kladnou a zápornou hodnotu 9 007 199 254 740 992 (53bitová celočíselná hodnota).
Výchozí hodnota pro proměnné, které jsou typu int, je 0.
Datový typ null
Datový typ null obsahuje pouze jednu hodnotu, null. Toto je výchozí hodnota pro datový typ String a všechny třídy,
které definují komplexní datové typy, včetně třídy Object. Žádný jiný primitivní datový typ, například Boolean,
Number, int a uint, neobsahuje hodnotu null. Aplikace Flash Player a Adobe AIR převedou hodnotu null na
vhodnou výchozí hodnotu v případě, že se pokusíte o přiřazení hodnoty null proměnným typu Boolean, Number, int
nebo uint. Nemůžete použít tento datový typ jako anotaci typu.
Datový typ Number
V jazyce ActionScript 3.0 datový typ Number může zastupovat celočíselné hodnoty, celočíselné hodnoty bez
znaménka a desetinná čísla. Pro maximalizaci výkonu byste měli používat datový typ Number pouze pro celočíselné
hodnoty vyšší, než mohou uložit 32bitové typy int a uint nebo pro desetinná čísla. Chcete-li uložit desetinné číslo,
uveďte v čísle desetinnou čárku. Pokud desetinnou čárku vynecháte, číslo bude uloženo jako celočíselná hodnota.
Datový typ Number využívá 64bitový formát s dvojitou přesností, jak je specifikováno standardem IEEE pro binární
aritmetiku s plovoucí desetinou čárkou (IEEE-754). Tento standard určuje, jak mají být desetinná čísla uložena
pomocí 64 dostupných bitů. Jeden bit se používá k označení, zda je číslo kladné nebo záporné. Jedenáct bitů se používá
pro exponent, který je uložen jako základ 2. Zbývajících 52 bitů se používá pro uložení mantisy (také significand), což
je číslo umocněné exponentem.
Použitím některých bitů k uložení exponentu může datový typ Number uložit desetinná čísla významně větší, než
pokud by byly všechny bity použity pro mantisu. Pokud například datový typ Number používá všech 64 bitů k uložení
mantisy, může uložit číslo až o hodnotě 265 - 1. Použitím 11 bitů k uložení exponentu může datový typ Number zvýšit
svou mantisu na mocninu 21023.
Maximální a minimální hodnoty, které může typ Number vyjadřovat, jsou uloženy ve statických vlastnostech třídy
Number nazvaných Number.MAX_VALUE a Number.MIN_VALUE.
Number.MAX_VALUE == 1.79769313486231e+308
Number.MIN_VALUE == 4.940656458412467e-324
I když tento rozsah čísel je enormní, cenou za tento rozsah je přesnost. Datový typ Number používá 52 bitů k uložení
mantisy s tím výsledkem, že čísla vyžadující k přesnému vyjádření více než 52 bitů, například zlomek 1/3, jsou pouze
přibližné aproximace. Pokud aplikace vyžaduje absolutní přesnost s desetinnými čísly, musíte použít software
implementující aritmetiku s desetinnými čísly v desítkové soustavě, jako protiklad aritmetiky desetinných čísel v
soustavě binární.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 58
Jazyk ActionScript a jeho syntaxe
Když uložíte celočíselné hodnoty jako datový typ Number, použije se pouze 52 bitů mantisy. Datový typ Number
použije těchto 52 bitů a speciální skrytý bit k vyjádření celočíselné hodnoty od 9 007 199 254 740 992 (-253) do 9 007
199 254 740 992 (253).
Aplikace Flash Player a Adobe AIR používají NaN hodnotu nejenom jako výchozí hodnotu pro proměnné typu Number,
ale také jako výsledek každé operace, která by měla vrátit číslo, ale nečiní tak. Pokud se například pokusíte vypočítat
druhou odmocninu záporného čísla, výsledek bude NaN. Jiné speciální hodnoty Number zahrnují kladné nekonečno a
záporné nekonečno.
Poznámka: Výsledkem dělení 0 je pouze NaN v případě, že dělitel je také 0. Dělení 0 dává ve výsledku infinity, pokud
je dělenec kladný, nebo -infinity, pokud je dělenec záporný.
Datový typ String
Datový typ String představuje posloupnost 16bitových znaků. Data String jsou uložena interně jako znaky Unicode,
pomocí formátu UTF-16. Data String jsou nezměnitelné hodnoty, stejně jako v programovacím jazyce Java. Operace
s hodnotou String vrací novou instanci řetězce. Výchozí hodnota proměnné deklarované datovým typem String je
null. Hodnota null není stejná, jako prázdný řetězec (""), i když obě vyjadřují nepřítomnost jakéhokoliv znaku.
Datový typ uint
Datový typ uint je uložen vnitřně jako 32bitová celočíselná hodnota bez znaménka a je tvořena souborem
celočíselných hodnot od 0 do 4 294 967 295 (232 - 1) včetně. Datový typ uint použijte pro zvláštní okolnosti, které volají
po nezáporných celočíselných hodnotách. Datový typ uint musíte například použít k vyjádření hodnot obrazového
bodu, protože datový typ unit má vnitřní bit pro znaménko a nehodí se pro manipulaci s hodnotami barev. Pro
celočíselné hodnoty větší než maximální hodnota uint použijte datový typ Number, který dokáže pracovat až s
53bitovými celočíselnými hodnotami. Výchozí hodnota pro proměnné, které jsou typu uint je 0.
Datový typ void
Datový typ void obsahuje pouze jednu hodnotu, undefined. V předchozích verzích jazyka ActionScript byla hodnota
undefined výchozí pro instance třídy Object. V jazyce ActionScript 3.0 je výchozí hodnota pro instance Object null.
Pokud se pokusíte přiřadit hodnotu undefined k instanci třídy Object, aplikace Flash Player nebo Adobe AIR převede
hodnotu na null. Hodnotu undefined můžete přiřadit pouze k proměnným, které nemají stanoven typ. Proměnné
bez typu jsou ty, které nemají anotaci typu, nebo používají symbol hvězdičky (*) jako anotaci typu. Můžete použít void
pouze jako anotaci vráceného typu.
Datový typ Object
Datový typ Object je definován třídou Object. Třída Objekt slouží jako základní třída pro všechny definice tříd v jazyce
ActionScript. Datový typ Object ve verzi ActionScript 3.0 se odlišuje od předchozích verzí třemi způsoby. První,
datový typ Object již není výchozím pro proměnné bez anotace typu. Druhý, datový typ Object již nezahrnuje hodnotu
undefined, která byla výchozí hodnotou pro instance Object. Třetí, v jazyce ActionScript 3.0 je výchozí hodnota
instance třídy Object null.
V předchozích verzích jazyka ActionScript byla proměnná bez anotace typu automaticky definována jako datový typ
Object. Tak tomu již v jazyce ActionScript 3.0 není, protože zde se využívá proměnná skutečně bez definovaného typu.
Proměnné bez anotace typu jsou nyní považovány za proměnné bez typu. Pokud dáváte přednost čtenářům objasnit
ve svém kódu, že vaším záměrem je ponechat proměnnou bez definice typu, můžete použít nový symbol hvězdičky (*)
pro anotaci typu, což je shodné jako byste anotaci typu vynechali. Následující příklad ukazuje dva shodné příkazy,
které deklarují proměnnou bez typu x:
var x
var x:*
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 59
Jazyk ActionScript a jeho syntaxe
Pouze proměnné bez typu mohou uchovávat hodnoty undefined. Pokud se pokusíte přiřadit hodnotu undefined pro
proměnnou mající datový typ, aplikace Flash Player nebo Adobe AIR převedou hodnotu undefined na výchozí
hodnotu daného datového typu. Pro instance datového typu Object je výchozí hodnota null, což znamená, že
přehrávač Flash Player nebo Adobe AIR převede hodnotu undefined na null, pokud se pokusíte převést hodnotu
undefined na instanci Object.
Převody typu
Převod typu nastává v případě, že hodnota je transformované do hodnoty odlišného datového typu. Převody typu
mohou být buď implicitní nebo explicitní. Implicitní převod, také nazývaný vynucený, je někdy proveden aplikací Flash
Player nebo Adobe AIR v době spuštění. Například, pokud je hodnota 2 přiřazena proměnné datového typu Boolean,
aplikace Flash Player nebo Adobe AIR převedou hodnotu 2 na booleovskou hodnotu true dříve, než hodnotu přiřadí
proměnné. Explicitní převod, nazývaný obsazování, nastává v případě, že kód vydává instanci kompilátoru, aby s
proměnnou jednoho datového typu zacházel, jako by náležela jinému datovému typu. Když se procesu účastní
primitivní hodnoty, obsazování ve skutečnosti převede hodnoty z jednoho datového typu na jiný. Chcete-li obsadit
objekt jiným datovým typem, vložte jej do závorek a předsaďte název nového typu. Například následující kód přebírá
booleovskou hodnotu a obsahuje ji celočíselnou hodnotou:
var myBoolean:Boolean = true;
var myINT:int = int(myBoolean);
trace(myINT); // 1
Implicitní převody
Implicitní převody nastávají v době spuštění v mnoha kontextech:
• Během příkazu přiřazení
• Když jsou hodnoty předány jako argumenty funkce
• Když jsou hodnoty vráceny z funkcí
• Ve výrazech využívajících jisté operátory, například přidání operátoru (+)
Pro uživatelem definované typy uspějí implicitní převody tam, kde je převáděná hodnota instancí cílové třídy nebo
třídy, které je odvozena od své cílové třídy. Pokud je implicitní převod neúspěšný, je signalizována chyba. Například
následující kód obsahuje úspěšný i neúspěšný implicitní převod.
class A {}
class B extends A {}
var objA:A = new A();
var objB:B = new B();
var arr:Array = new Array();
objA = objB; // Conversion succeeds.
objB = arr; // Conversion fails.
Pro primitivní typy jsou implicitní převody zpracovávány zavoláním stejného vnitřního převodního algoritmu,
které jsou zavolány explicitními převodními funkcemi. Následující kapitola popisuje tyto převody primitivních
typů podrobně.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 60
Jazyk ActionScript a jeho syntaxe
Explicitní převody
Je užitečné používat explicitní převody nebo obsazování, když kompilujete kód v přísném režimu, protože se mohou
vyskytovat okamžiky, kdy nechcete, aby neshoda typu vygenerovala chybu v době kompilace. Tak tomu může být v
případě, že vynucení převede vaše hodnoty správně v době spuštění. Například při práci s daty přijatým z formuláře
se můžete spolehnout na vynucení a převést jisté řetězcové hodnoty na numerické hodnoty. Následující kód
vygeneruje chybu v době kompilace, ale kód bude ve standardním režimu pracovat správně:
var quantityField:String = "3";
var quantity:int = quantityField; // compile time error in strict mode
Pokud chcete pokračovat v přísném režimu, ale chcete převést řetězec na celočíselnou hodnotu, můžete použít
explicitní převod a to takto:
var quantityField:String = "3";
var quantity:int = int(quantityField); // Explicit conversion succeeds.
Obsazení do int, uint a Number
Můžete obsadit kterýkoliv datový typ jedním ze tří typů čísel: int, uint a Number. Pokud aplikace Flash Player nebo
Adobe AIR nedokáží číslo z nějakého důvodu převést, bude pro datové typy int a uint přiřazena výchozí hodnota 0 a
pro datový typ Number pak hodnota NaN. Pokud převedete na číslo booleovskou hodnotu, z hodnoty true se stane
hodnota 1 a z false bude 0.
var myBoolean:Boolean = true;
var myUINT:uint = uint(myBoolean);
var myINT:int = int(myBoolean);
var myNum:Number = Number(myBoolean);
trace(myUINT, myINT, myNum); // 1 1 1
myBoolean = false;
myUINT = uint(myBoolean);
myINT = int(myBoolean);
myNum = Number(myBoolean);
trace(myUINT, myINT, myNum); // 0 0 0
Řetězcové hodnoty obsahující pouze číslice mohou být úspěšně převedeny do jednoho z číselných typů. Číselný typ
může také převést řetězce, které vypadají jako záporná číselná hodnota nebo šestnáctková hodnota (například 0x1A).
Proces převodu ignoruje prázdné znaky na začátku a na konci v hodnotě řetězce. Můžete také obsadit řetězce, které
vypadají jako desetinná čísla a to pomocí Number(). Zahrnutí desetinné čárky způsobuje, že uint() a int() vrátí
celočíselnou hodnotu a zkrátí se desetinná hodnota a znaky za ní následující. Například následující hodnoty řetězce
mohou obsadit čísla.
trace(uint("5")); // 5
trace(uint("-5")); // 4294967291. It wraps around from MAX_VALUE
trace(uint(" 27 ")); // 27
trace(uint("3.7")); // 3
trace(int("3.7")); // 3
trace(int("0x1A")); // 26
trace(Number("3.7")); // 3.7
Hodnoty řetězce obsahující nečíselné znaky vrátí 0, když jsou obsazeny s int() nebo uint() a NaN, když jsou
obsazeny Number(). Proces převodu ignoruje prázdné znaky na začátku a na konci, ale vrací 0 nebo NaN, pokud má
řetězec prázdný znak oddělující dvě čísla.
trace(uint("5a")); // 0
trace(uint("ten")); // 0
trace(uint("17 63")); // 0
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 61
Jazyk ActionScript a jeho syntaxe
V jazyce ActionScript 3.0 funkce Number() již nepodporuje oktálová čísla, nebo čísla s osmičkovým základem. Pokud
řetězec s nulou na začátku předáte v jazyce ActionScript 2.0 funkci Number(), číslo bude interpretováno jako oktálové
číslo a převedeno na desítkovou hodnotu. V případě funkce Number() v jazyce ActionScript 3.0 tomu tak není, zde se
první nula ignoruje. Například následující kód vygeneruje jiný výstup při kompilování v různých verzích jazyka
ActionScript:
trace(Number("044"));
// ActionScript 3.0 44
// ActionScript 2.0 36
Obsazení není nutné, pokud hodnota jednoho číselného typu bude přiřazena proměnné s jiným číselným typem. I v
přísném režimu jsou číselné typy implicitně převáděny na jiné číselné typy. To znamená, že v některých případech se
mohou vyskytnout neočekávané hodnoty, pokud je překročen rozsah typu. Následující příklady jsou všechny
kompilovány v přísném režimu, ačkoliv některé generují neočekávané hodnoty:
var myUInt:uint = -3; // Assign int/Number value to uint variable
trace(myUInt); // 4294967293
var myNum:Number = sampleUINT; // Assign int/uint value to Number variable
trace(myNum) // 4294967293
var myInt:int = uint.MAX_VALUE + 1; // Assign Number value to uint variable
trace(myInt); // 0
myInt = int.MAX_VALUE + 1; // Assign uint/Number value to int variable
trace(myInt); // -2147483648
Následující tabulka uvádí souhrn výsledků obsazení do datového typu Number, int nebo uint z jiného datového typu.
Datový typ nebo hodnota Výsledek převodu do Number, int nebo uint
Booleovská hodnota
Pokud je hodnota true, pak 1; jinak 0.
Date
Vnitřní vyjádření objektu Date, což je počet milisekund od půlnoci 1. ledna 1970 univerzálního času.
null
0
Objekt
Pokud je instance null a převedená na Number, pak NaN; jinak 0.
String
Číslo, pokud aplikace Flash Player nebo Adobe AIR mohou převést řetězec na číslo; jinak NaN pokud je
převedeno na Number, nebo 0, pokud je převedeno na int nebo uint.
undefined
Pokud převedeno na Number, pak NaN; pokud převedeno na int nebo uint, tak 0.
Obsazení do Booleovské hodnoty
Obsazení do Booleovské hodnoty z kteréhokoliv číselného datového typu int, unit a Number) vede k hodnotě false,
pokud je číselná hodnota 0, a v ostatních případech k hodnotě true. Pro datový typ Number hodnota NaN také vede k
false. Následující příklad ukazuje výsledky obsazení čísel -1, 0 a 1:
var myNum:Number;
for (myNum = -1; myNum<2; myNum++)
{
trace("Boolean(" + myNum +") is " + Boolean(myNum));
}
Výstup příklad ukazuje, že ze tří čísel pouze 0 vrací hodnotu false:
Boolean(-1) is true
Boolean(0) is false
Boolean(1) is true
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 62
Jazyk ActionScript a jeho syntaxe
Obsazení do Booleovské hodnoty z hodnoty String vrací false v případě, že řetězec je null nebo prázdný řetězec ("").
V opačném případě vrací true.
var str1:String; // Uninitialized string is null.
trace(Boolean(str1)); // false
var str2:String = ""; // empty string
trace(Boolean(str2)); // false
var str3:String = " "; // white space only
trace(Boolean(str3)); // true
Obsazení do Booleovské hodnoty z instance třídy Object vrací false, pokud je instance null; jinak vrací true:
var myObj:Object; // Uninitialized object is null.
trace(Boolean(myObj)); // false
myObj = new Object(); // instantiate
trace(Boolean(myObj)); // true
Booleovská proměnná je v přísném režimu zpracovávána zvláštním způsobem v tom, že booleovské proměnné můžete
přiřadit hodnoty kteréhokoliv datového typu bez obsazování. Implicitní vynucení ze všech datových typů do
booleovského datového typu nastává i v přísném režimu. Jinými slovy na rozdíl od téměř všech ostatních datových
typů obsazení do booleovské hodnoty není nutné k tomu, abyste se vyhnuli chybám přísného režimu. Následující
příklad jsou všechny kompilovány v přísném režimu a chovají se v době spuštění podle očekávání.
var myObj:Object = new Object(); // instantiate
var bool:Boolean = myObj;
trace(bool); // true
bool = "random string";
trace(bool); // true
bool = new Array();
trace(bool); // true
bool = NaN;
trace(bool); // false
Následující tabulka uvádí souhrn výsledků obsazení do datového typu Boolean z jiných datových typů.
Datový typ nebo hodnota
Výsledky převodu do booleovské hodnoty
String
false, pokud je hodnota null nebo prázdný řetězec (""); jinak true.
null
false
Number, int nebo uint
false, pokud je hodnota NaN nebo 0; jinak true.
Objekt
false, pokud je instance null; jinak true.
Obsazení do String
Obsazení do datového typu String z kteréhokoliv číselného datového typu vrací řetězcové vyjádření čísla. Obsazení do
datového typu String z booleovské hodnoty vrací řetězec"true", pokud je hodnota true, a řetězec "false", pokud je
hodnota false.
Obsazení do datového typu String z instance třídy Object vrací řetězec "null", pokud je instance null. Jinak obsazení
do datového typu String z třídy Object vrací řetězec "[object Object]".
Obsazení do datového typu String z instance třídy Array vrací řetězec tvořený seznamem všech prvků pole, oddělených
čárkou. Například následující datový typ String vrací jeden řetěze obsahující všechny tři prvky pole:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 63
Jazyk ActionScript a jeho syntaxe
var myArray:Array = ["primary", "secondary", "tertiary"];
trace(String(myArray)); // primary,secondary,tertiary
Obsazení do datového typu String z instance třídy date vrací řetězec vyjadřující datum, které instance obsahuje.
Například následující příklad vrací vyjádření instance třídy date (výstup ukazuje výsledek pro pacifický letní čas):
var myDate:Date = new Date(2005,6,1);
trace(String(myDate)); // Fri Jul 1 00:00:00 GMT-0700 2005
Následující tabulka uvádí souhrn výsledků obsazení do datového typu String z jiných datových typů.
Datový typ nebo hodnota
Výsledky převodu do řetězce
Array
Řetězec obsahující všechny prvky pole.
Boolean
"true" nebo "false"
Date
Řetězcové vyjádření objektu Date.
null
"null"
Number, int nebo uint
Řetězcové vyjádření čísla.
Object
Pokud je instance null, "null"; jinak "[object Object]".
Syntaxe
Syntaxe jazyka definuje soubor pravidel, které musí být dodrženy při zapisování spustitelného kódu.
Rozlišování velkých a malých písmen
Jazyk ActionScript 3.0 využívá rozlišování velkých a malých písmen. Identifikátory, které se liší pouze velkým/malým
písmem, jsou považovány za odlišné identifikátory. Například následujíc kódy vytváří dvě různé proměnné
var num1:int;
var Num1:int;
Tečková syntaxe
Operátor tečka (.) poskytuje způsob přístupu k vlastnosti a metodě objektu. Pomocí tečkové syntaxe můžete
odkazovat na vlastnost třídy nebo metodu pomocí názvu instance, za kterým následující operátor tečka a název
vlastnosti nebo metody. Například zvažte následující definici třídy:
class DotExample
{
public var prop1:String;
public function method1():void {}
}
Pomocí tečkové syntaxe můžete přistupovat k vlastnosti prop1 a metodě method1() pomocí instance vytvořené
následujícím kódem:
var myDotEx:DotExample = new DotExample();
myDotEx.prop1 = "hello";
myDotEx.method1();
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 64
Jazyk ActionScript a jeho syntaxe
Tečkovou syntaxi můžete použít při definování balíčků. Operátor tečka můžete použít k odkazování na vnořené
balíčky. Například třída EventDispatcher spočívá uvnitř balíčku pojmenovaném events, který je vnořen do balíčku
pojmenovaného flash. Pomocí výrazu následujícího můžete odkazovat na balíček events:
flash.events
Pomocí následujícího výrazu můžete také odkazovat na třídu EventDispatcher:
flash.events.EventDispatcher
Lomítková syntaxe
Lomítková syntaxe není v jazyce ActionScript 3.0 podporována. Lomítková syntaxe byla používána v dřívějších verzích
jazyka ActionScript pro označení cesty filmového klipu nebo proměnné.
Literály
Literál je hodnota zobrazující se přímo ve vašem kódu. Následující příklady jsou všechno literály:
17
"hello"
-3
9.4
null
undefined
true
false
Literály mohou být také seskupeny do složených literálů. Literálová pole jsou uložena mezi závorkami ([]) a k
oddělení prvků pole používají čárku.
Literálové pole lze použít pro inicializaci pole. Následující příklady zobrazují dvě pole, která jsou inicializována
pomocí literálových polí. Můžete použít příkaz new a předat složený literál jako parametr do konstruktoru třídy
Array,ale můžete také přiřadit literálové hodnoty přímo, když konkretizujete instance následujících klíčových tříd
ActionScript: Object, Array, String, Number, int, uint, XML, XMLList a Boolean.
// Use new statement.
var myStrings:Array = new Array(["alpha", "beta", "gamma"]);
var myNums:Array = new Array([1,2,3,5,8]);
// Assign literal directly.
var myStrings:Array = ["alpha", "beta", "gamma"];
var myNums:Array = [1,2,3,5,8];
Literály mohou být také použity pro inicializaci generického objektu. Generický objekt je instancí třídy Object.
Literálové objekty jsou uvedeny ve složených závorkách ({}) a k oddělení vlastností objektu používají čárku. Každá
vlastnost je deklarovaná znakem dvojtečky (:), která odděluje název vlastnosti od její hodnoty.
Generický objekt můžete vytvořit pomocí příkazu new a předat literálový objekt jako parametr do konstruktoru třídy
Object, nebo můžete přiřadit literálový objekt přímo instanci, kterou deklarujete. Následující příklad ukazuje dva
alternativní způsoby vytváření nového generického objektu a inicializace objektu s třemi vlastnostmi (propA, propB a
propC), každá z těchto hodnot je nastavena na 1, 2 a 3:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 65
Jazyk ActionScript a jeho syntaxe
// Use new statement and add properties.
var myObject:Object = new Object();
myObject.propA = 1;
myObject.propB = 2;
myObject.propC = 3;
// Assign literal directly.
var myObject:Object = {propA:1, propB:2, propC:3};
Další informace viz „Základy řetězců“ na stránce 138, „Základní informace o regulárních výrazech“ na stránce 202 a
„Inicializace proměnných XML“ na stránce 230.
Středníky
Středník (;) můžete použít k ukončení příkazu. Alternativně, pokud středník vynecháte, kompilátor bude
předpokládat, že každá řádka kódu představuje jeden příkaz. Protože mnoho programátorů je zvyklých na středník
jako znak ukončení příkazu, může být snazší kód číst, pokud jej budete používat k ukončení příkazů konzistentně.
Použití středníku k ukončení příkazu umožňuje vložení více než jednoho příkazu do jedné řádky, ale to však může kód
znepřehlednit.
Závorky
Závorky (()) můžete v jazyce ActionScript 3.0 použít třemi způsoby. Za prvé, závorky můžete použít pro změnu
pořadí operací ve výrazu. Operace seskupené uvnitř závorek jsou vždy vykonávány jako první. Například závorky jsou
použité pro změnu pořadí operací v následujícím kódu:
trace(2 + 3 * 4); // 14
trace((2 + 3) * 4); // 20
Za druhé, závorky můžete použít s čárkou (,) pro vyhodnocení řady výrazů a vrácení výsledků konečného výrazu, jak
je vidět na následujícím příkladu:
var a:int = 2;
var b:int = 3;
trace((a++, b++, a+b)); // 7
Za třetí, závorky můžete použít jako funkce nebo metody, jak je vidět na následujícím příkladu, které předají hodnotu
String funkci trace():
trace("hello"); // hello
Poznámky
Kód jazyka ActionScript 3.0 podporuje dva typy komentářů: jednořádkový a víceřádkový. Tyto mechanismy
komentářů jsou podobné jazykům C++ a Java. Kompilátor bude ignorovat text, který je označen jako komentář.
Jednořádkové komentáře začínají dopředným lomítkem (//) a pokračují na konec řádky. Například následující kód
obsahuje jednořádkový komentář:
var someNumber:Number = 3; // a single line comment
Víceřádkový komentář začíná dopředným lomítkem a hvězdičkou(/*) a končí hvězdičkou a dopředným lomítkem
(*/).
/* This is multiline comment that can span
more than one line of code. */
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 66
Jazyk ActionScript a jeho syntaxe
Klíčová slova jsou vyhrazená slova
Vyhrazená slova jsou slova, která nemůžete použít jako identifikátory v kódu, protože jsou vyhrazena pro použití
jazykem ActionScript. Vyhrazená slova zahrnují lexikální klíčová slova, která jsou vyňata z jmenného prostoru
programu kompilátorem. Kompilátor nahlásí chybu, pokud lexikální klíčová slova použijete jako identifikátor.
Následující tabulka uvádí seznam lexikálních klíčových slov jazyka ActionScript 3.0.
as
break
case
catch
class
const
continue
default
delete
do
else
extends
false
finally
for
function
if
implements
import
in
instanceof
interface
internal
is
native
new
null
package
private
protected
public
return
super
switch
this
throw
to
true
try
typeof
use
var
void
while
with
Existuje malá sada klíčových slov, nazvaných syntaktická klíčová slova, které mohou být použity jako identifikátory,
ale mají v jistém kontextu speciální význam. Následující tabulka uvádí seznam syntaktických klíčových slov jazyka
ActionScript 3.0.
each
get
set
namespace
include
dynamic
final
native
override
static
Existuje také několik identifikátorů, které jsou někdy odkazovány jako budoucí vyhrazená slova. Tyto identifikátory
nejsou jazykem ActionScript 3.0 vyhrazeny, ale některé z nich mohou být použita jako klíčová slova softwarem, který
jazyk ActionScript 3.0 obsahuje. Může být možné mnoho z těchto identifikátorů ve vašem kódu použít, ale společnost
Adobe doporučuje je nepoužívat, protože se mohou jako klíčová slova objevit v následujících verzích jazyka.
abstract
boolean
byte
cast
char
debugger
double
enum
export
float
goto
intrinsic
long
prototype
short
synchronized
throws
to
transient
type
virtual
volatile
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 67
Jazyk ActionScript a jeho syntaxe
Konstanty
Jazyk ActionScript 3.0 podporuje příkaz const, který můžete použít k vytváření konstant. Konstanty jsou vlastnosti s
pevnou hodnotu, kterou nelze změnit. Konstantě můžete přiřadit hodnotu pouze jednou a přiřazení musí být
provedeno v blízkosti deklarace konstanty. Pokud je například konstanta deklarována jako člen třídy, můžete přiřadit
hodnotu této konstantě pouze jako součást deklarace nebo uvnitř konstruktoru třídy.
Následující kód deklarujete dvě konstanty. První konstanta MINIMUM, má hodnotu přiřazenou jako součást příkazu
deklarace. Druhá konstanta, MAXIMUM, má hodnotu přiřazenou v konstruktoru. Povšimněte si, že tento příklad se
kompiluje pouze ve standardním režimu, protože v přísném režimu umožňuje přiřazení hodnoty konstanty pouze v
době inicializace.
class A
{
public const MINIMUM:int = 0;
public const MAXIMUM:int;
public function A()
{
MAXIMUM = 10;
}
}
var a:A = new A();
trace(a.MINIMUM); // 0
trace(a.MAXIMUM); // 10
Pokud se pokusíte přiřadit počáteční hodnotu konstantě jiným způsobem, dojde k chybě. Pokud se například pokusíte
nastavit počáteční hodnotu MAXIMUM vně třídy, dojde k chybě v době spuštění.
class A
{
public const MINIMUM:int = 0;
public const MAXIMUM:int;
}
var a:A = new A();
a["MAXIMUM"] = 10; // run-time error
Jazyk ActionScript 3.0 definuje široké rozpětí konstant, které můžete použít. Na základě konvence konstanty v jazyce
ActionScript používají všechna velká písmena, se slovy oddělenými podtržítkem (_). Například definice třídy
MouseEvent používá tuto konvenci pojmenování pro své konstanty, každá z nich vyjadřuje událost související se
vstupem od myši:
package flash.events
{
public class MouseEvent extends Event
{
public static const CLICK:String = "click";
public static const DOUBLE_CLICK:String = "doubleClick";
public static const MOUSE_DOWN:String = "mouseDown";
public static const MOUSE_MOVE:String = "mouseMove";
...
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 68
Jazyk ActionScript a jeho syntaxe
Operátory
Operátory jsou speciální funkce, které mohou mít jeden nebo více operandů a vrací hodnotu. Operand je hodnota,
obvykle literál, proměnná nebo výraz, kterou operátor používá jako vstup. Například v následujícím kódu doplnění
(+) a násobení (*) operátorů je použito s třemi literálovými operandy (2, 3, a 4) a vrací hodnotu. Hodnota je pak
použita operátorem přiřazení (=) k přiřazení vrácené hodnoty, 14, proměnné sumNumber.
var sumNumber:uint = 2 + 3 * 4; // uint = 14
Operátory mohou být ternární, binární nebo unární. Unární operátor má jediný operand. Například přírůstkový
operátor (++) je unárním operátorem, protože má jenom jeden operand. Binární operátor má dva operandy.
Například operátor dělení (/) má dva operandy. Ternární operátor má tři operandy. Například operátor podmínky
(?:) má tři operandy.
Některé operátory jsou přetížené, což znamená, že se chovají odlišně v závislosti na typu nebo počtu operandu,, které
jsou jim předané. Operátor sčítání (+) je příkladem přetíženého operátoru, který se chová odlišně v závislosti na
datovém typu operandu. Pokud jsou oba operandy čísly, operátor sčítání vrací součet hodnot. Pokud jsou oba
operandy řetězce, operátor sčítání vrací zkrácení obou operandů. Následující příklad kódu ukazuje, jak se operátor
chová odlišně v závislosti na operandech:
trace(5 + 5); // 10
trace("5" + "5"); // 55
Operátory se mohou také chovat odlišně na základě počtu operandů jim předaných. Operátor odčítání (-) je unární i
binární operátor. Pokud je předán pouze jediný operand, operátor odčítání neguje operand a vrací výsledek. Po
předání dvou operandů operátor odčítání vrací rozdíl mezi operandy. Následující příklad ukazuje operátor odčítání,
použitý nejprve jako unární, pak jako binární operátor.
trace(-3); // -3
trace(7 - 2); // 5
Přednost a asociativita operátorů
Přednost a asociativita operátorů stanoví pořadí, ve kterém jsou operátory zpracovány. I když může vypadat přirozené
všem, kteří jsou seznámeni s aritmetikou, že kompilátor zpracovává násobení (*) před sčítáním (+), vyžaduje
kompilátor specifické instrukce o tom, které operátory má zpracovat jako první. Takové pokyny jsou souhrnně
popisovány jako přednost operátorů. V jazyce ActionScript definuje výchozí operátor přednost, kterou můžete změnit
pomocí závorek (()). Například následující kód mění výchozí přednost z předchozího příklad tak, aby donutil
kompilátor zpracovat operátor sčítání před operátorem násobení:
var sumNumber:uint = (2 + 3) * 4; // uint == 20
Můžete se setkat se situacemi, ve kterých mají dva nebo více operátorů stejnou přednost a jsou uvedeny ve stejném
výrazu. V těchto případech kompilátor používá pravidlo asociativity ke stanovení, který operátor má být zpracován
jako první. Všechny binární operátor, kromě operátorů přiřazení, jsou asociativní zleva, což znamená, že operátory
vlevo jsou zpracovány před operátory vpravo. Operátory přiřazení a podmínkové operátory (?:) jsou zprava
asociativní, což znamená, že operátory vpravo jsou zpracovány před operátory vlevo.
Například uvažujme operátory menší než (<) a větší než (>), které mají stejnou přednost. Pokud jsou oba operátory
použity ve stejném výrazu, operátor na levé straně je zpracován jako první, protože oba operátory jsou asociativní
zleva. To znamená, že následující dva příkazy poskytnou stejný výsledek:
trace(3 > 2 < 1); // false
trace((3 > 2) < 1); // false
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 69
Jazyk ActionScript a jeho syntaxe
Operátor větší než je zpracován jako první, což vede k hodnotě true, protože operand 3 je větší než operand 2.
Hodnota true je pak předána operátoru menší než společně s operandem 1. Následující kód představuje tento
mezistav:
trace((true) < 1);
Operátor menší než převádí hodnotu true na numerickou hodnotu 1 a porovnává tuto numerickou hodnotu s
druhým operandem 1 a vrací hodnotu false (hodnota 1 není menší než 1).
trace(1 < 1); // false
Pomocí operátoru závorka můžete změnit výchozí asociativitu zleva. Kompilátoru můžete vydat pokyn zpracovat
operátor menší než nejprve jeho umístěním do závorek i s jeho operandy. Následující příklad používá operátor
závorka k dosažení jiného výsledku pomocí stejných čísel, jako v předchozím příkladu:
trace(3 > (2 < 1)); // true
Operátor menší než je zpracován jako první, což vede k hodnotě false, protože operand 2 není menší než operand 1.
Hodnota false je pak předána operátoru větší než společně s operandem 3. Následující kód představuje tento
mezistav:
trace(3 > (false));
Operátor větší než převede hodnotu false na numerickou hodnotu 0 a porovná tuto numerickou hodnotu s druhým
operandem 3 a vrátí hodnotu true (hodnota 3 je větší než 0).
trace(3 > 0); // true
Následující tabulka uvádí operátory pro jazyk ActionScript 3.0 v pořadí snižující se přednosti. Každá řádka v tabulce
obsahuje operátory stejné přednosti. Každý řádka operátorů má vyšší přednost, než řádka následující v tabulce za ní.
Skupina
operátory
Primární operátory
[] {x:y} () f(x) new x.y x[y] <></> @ :: ..
Příponové operátory
x++ x--
Unární operátory
++x --x + - ~ ! delete typeof void
Multiplikativní operátory
* / %
Aditivní
+ -
Bitové operátory posunutí
<< >> >>>
Relační operátory
< > <= >= as in instanceof is
Rovnost
== != === !==
Bitový operátor AND
&
Bitový operátor XOR
^
Bitový operátor OR
|
Logické AND
&&
Logické OR
||
Podmínečný
?:
Přiřazení
= *= /= %= += -= <<= >>= >>>= &= ^= |=
Čárka
,
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 70
Jazyk ActionScript a jeho syntaxe
Primární operátory
Primární operátory zahrnují ty, které jsou použity pro vytvoření literálů Array a Object, seskupení výrazů, volání
funkcí, konkretizaci instancí třídy a pro přístup k vlastnostem.
Všechny primární operátory uvedené v následující tabulce mají stejnou přednost. Operátory, které jsou součástí
specifikace E4X, jsou označeny poznámkou (E4X).
Operátor
Provedená operace
[]
Inicializace pole
{x:y}
Inicializace objektu
()
Seskupení výrazů
f(x)
Volání funkce
new
Volání konstruktoru
x.y x[y]
Přístup k vlastnostem
<></>
Inicializace objektu XMLList (E4X)
@
Přistupuje k atributu (E4X)
::
Kvalifikuje název (E4X)
..
Přistupuje k dceřinému prvku XML (E4X)
Příponové operátory
Příponové operátory vezmou jeden operand a provedou zvýšení nebo snížení jeho hodnoty. I když tyto operátory jsou
unárními operátory, jsou klasifikovány samostatně od zbytku unárních operátorů, díky jejich vyšší přednosti a
zvláštnímu chování. Když je použít příponový operátor jako součást větší výrazu, hodnota výrazu je vrácena před
zpracováním příponového operátoru. Například následující kód zobrazuje, jak je vracena hodnota xNum++ před svým
zvýšením:
var xNum:Number = 0;
trace(xNum++); // 0
trace(xNum); // 1
Všechny příponové operátory uvedené v následující tabulce mají stejnou přednost.
Operátor
Provedená operace
++
Zvýšení hodnoty (přípona)
--
Snížení hodnoty (přípona)
Unární operátory
Unární operátory pracující s jedním operandem. Operátory zvýšení hodnoty (++) a snížení hodnoty (--) v této
skupině jsou předponovéoperátory, což znamená, že se ve výrazu zobrazují před operandem. Předponové operátory se
liší od svých protějšků, příponových operátorů, a to v tom, že operace zvýšení nebo snížení hodnoty je dokončena
předtím, než je vrácena hodnota celkového výrazu. Například následující kód zobrazuje, jak je vracena hodnota
++xNum po svém zvýšení:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 71
Jazyk ActionScript a jeho syntaxe
var xNum:Number = 0;
trace(++xNum); // 1
trace(xNum); // 1
Všechny unární operátory uvedené v následující tabulce mají stejnou přednost.
Operátor
Provedená operace
++
Zvýšení hodnoty (předpona)
--
Snížení hodnoty (předpona)
+
Unární operátor +
-
Unární operátor - (negace)
!
Logický operátor NOT
~
Bitový operátor NOT
delete
Odstraňuje vlastnost
typeof
Vrací typ informace
void
Vrací nedefinovanou hodnotu
multiplikativní operátory
Multiplikativní operátory vezmou dva operandy a provedou s nimi násobení, dělení nebo výpočty s operandem
modulu.
Všechny multiplikativní operátory uvedené v následující tabulce mají stejnou přednost.
Operátor
Provedená operace
*
Násobení
/
Dělení
%
Modulo
Aditivní operátory
Aditivní operátory vezmou dva operandy a provedou sčítání nebo odčítání. Všechny aditivní operátory uvedené v
následující tabulce mají stejnou přednost.
Operátor
Provedená operace
+
Sčítání
-
Odčítání
Bitové operátory posunutí
Bitové operátory posunutí vezmou dva operandy a provedou s nimi posunutí bitů prvního operandu v rozsahu
specifikovaném druhým operandem. Všechny bitové operátory posunutí uvedené v následující tabulce mají stejnou
přednost.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 72
Jazyk ActionScript a jeho syntaxe
Operátor
Provedená operace
<<
Bitové posunutí vlevo
>>
Bitové posunutí vpravo
>>>
Bitové posunutí vpravo, bez znaménka
Relační operátory
Relační operátory vezmou dva operandy a provedou porovnání jejich hodnot a vrátí booleovskou hodnotu. Všechny
relační operátory uvedené v následující tabulce mají stejnou přednost.
Operátor
Provedená operace
<
Menší než
>
Větší než
<=
Menší než nebo se rovná
>=
Větší než nebo rovno
as
Kontrola datového typu
in
Kontrola vlastností objektu
instanceof
Kontrola řetězu prototypu
is
Kontrola datového typu
Operátory rovnosti
Operátory rovnosti vezmou dva operandy a provedou porovnání jejich hodnot a vrátí booleovskou hodnotu. Všechny
relační operátory uvedené v následující tabulce mají stejnou přednost.
Operátor
Provedená operace
==
Rovnost
!=
Nerovnost
===
Přesná rovnost
!==
Přesná nerovnost
Bitové logické operátory
Bitové logické operátory vezmou dva operandy a provedou s nimi logické operace na úrovni bitů. Bitové logické
operátory se odlišují svou předností a jsou uvedeny v následující tabulce v pořadí snižující se přednosti:
Operátor
Provedená operace
&
Bitový operátor AND
^
Bitový operátor XOR
|
Bitový operátor OR
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 73
Jazyk ActionScript a jeho syntaxe
Logické operátory
Logické operátory vezmou dva operandy a vrátí booleovskou hodnotu. Logické operátory se odlišují svou předností a
jsou uvedeny v následující tabulce v pořadí snižující se přednosti:
Operátor
Provedená operace
&&
Logické AND
||
Logické OR
Podmínečný operátor
Podmínečný operátor je ternární operátor, což znamená, že pracuje se třemi operandy. Podmínečný operátor je
rychlou metodou aplikace podmíněného příkazu if..else.
Operátor
Provedená operace
?:
Podmínečný
Operátory přiřazení
Operátory přiřazení vezmou dva operandy a přiřadí hodnotu jednomu z nich, na základě hodnoty druhého operandu.
Všechny operátory přiřazení uvedené v následující tabulce mají stejnou přednost.
Operátor
Provedená operace
=
Přiřazení
*=
Přiřazení násobení
/=
Přiřazení dělení
%=
Přiřazení modulo
+=
Přiřazení sčítání
-=
Přiřazení odčítání
<<=
Přiřazení bitového posunutí vlevo
>>=
Přiřazení bitového posunutí vpravo
>>>=
Přiřazení bitového posunutí vpravo, bez znaménka
&=
Přiřazení bitového operátoru AND
^=
Přiřazení bitového operátoru XOR
|=
Přiřazení bitového operátoru OR
Podmíněné příkazy
Jazyk ActionScript 3.0 poskytuje tři základní podmíněné příkazy, které můžete používat pro ovládání chodu
programu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 74
Jazyk ActionScript a jeho syntaxe
if..else
Podmíněný příkaz if..else umožňuje testovat podmínku a vykonávat blok kódu v případě, že podmínka existuje,
nebo vykonávat alternativní blok kódu, pokud podmínka neexistuje. Například následující kód testuje, zda hodnota x
přesahuje 20, a vygeneruje funkci trace() v případě, že ano, nebo vygeneruje jinou funkci trace(), pokud ne:
if (x > 20)
{
trace("x is > 20");
}
else
{
trace("x is <= 20");
}
Pokud nechcete vykonat alternativní blok kódu, můžete použít příkaz if bez příkazu else.
if..else if
Pomocí podmíněného příkazu if..else if můžete testovat více než jednu podmínku. Například následující kód
testuje nejenom, zda hodnota x přesahuje 20, ale také, zda hodnota x je záporná:
if (x > 20)
{
trace("x is > 20");
}
else if (x < 0)
{
trace("x is negative");
}
Pokud je příkaz if nebo else následován pouze jedním příkazem, příkaz nevyžaduje vložení do závorek. Například
následující kód nepoužívá závorky:
if (x > 0)
trace("x
else if (x <
trace("x
else
trace("x
is positive");
0)
is negative");
is 0");
Společnost Adobe však doporučuje používat závorky vždy, protože pokud budou později příkazy přidány do
podmíněného příkazu bez závorek, může se vyskytnout neočekávané chování. Například v následujícím kódu se
hodnota positiveNums zvyšuje o 1 bez ohledu na to, zda je podmínka vyhodnocena true:
var x:int;
var positiveNums:int = 0;
if (x > 0)
trace("x is positive");
positiveNums++;
trace(positiveNums); // 1
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 75
Jazyk ActionScript a jeho syntaxe
switch
Příkaz switch je užitečný v případě, že máte několik cest vykonání kódu, které závisí na stejném podmíněném výrazu.
Poskytuje funkci podobnou dlouhé řadě příkazů if..else if, ale snáze se čte. Namísto testování podmínky s
ohledem na booleovskou hodnotu, příkaz switch vyhodnocuje výraz a používá výsledek ke stanovení, který blok kódu
je nutné vykonat. Bloky kódu začíná příkazem case a končí příkazem break. Například následující příkazy switch
vytisknou den v týdnu na základě čísla dne, vráceného metodou Date.getDay():
var someDate:Date = new Date();
var dayNum:uint = someDate.getDay();
switch(dayNum)
{
case 0:
trace("Sunday");
break;
case 1:
trace("Monday");
break;
case 2:
trace("Tuesday");
break;
case 3:
trace("Wednesday");
break;
case 4:
trace("Thursday");
break;
case 5:
trace("Friday");
break;
case 6:
trace("Saturday");
break;
default:
trace("Out of range");
break;
}
Opakování
Opakování příkazu umožňuje provádět specifické bloky kódu opakovaně pomocí řady hodnot nebo proměnných.
Společnost Adobe doporučuje vždy uzavřít blok kódu do závorek ({}). I když můžete závorky vynechat v případě, že
kód obsahuje pouze jeden příkaz, tento postup se nedoporučuje ze stejného důvodu, jako se nedoporučuje pro
podmíněné příkazy: zvyšuje pravděpodobnost, že posléze přidané příkazy budou neúmyslně vyloučeny z bloku kódu.
Pokud později přidáte příkaz, který chcete zahrnout do bloku kódu, ale zapomenete přidat potřebné závorky, příkaz
nebude vykonán jako součást opakování cyklu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 76
Jazyk ActionScript a jeho syntaxe
for
Opakování (cyklus) for umožňuje iterovat proměnnou ve specifickém rozsahu hodnot. Do příkazu for musíte zadat
tři výrazy: proměnnou, která je nastavena na počáteční hodnotu, podmíněný příkaz, který stanoví, když cyklus končí,
a výraz, který mění hodnotu proměnné po každém cyklu. Například následující příkaz se bude opakovat pětkrát.
Hodnota proměnné i začíná na hodnotě 0 a končí na hodnotě 4 a výstup bude tvořen čísly 0 až 4, každý na vlastní
řádce.
var i:int;
for (i = 0; i < 5; i++)
{
trace(i);
}
příkaz for..in
Příkaz for..in iteruje vlastnosti objektu, nebo prvky pole. Například můžete použít cyklus for..in a iterovat
vlastnosti generického objektu (vlastnosti objektu nejsou žádným specifickým způsobem řazeny, takže se mohou
zobrazovat ve zdánlivě náhodném pořadí):
var myObj:Object = {x:20, y:30};
for (var i:String in myObj)
{
trace(i + ": " + myObj[i]);
}
// output:
// x: 20
// y: 30
Iterovat můžete také prvky pole:
var myArray:Array = ["one", "two", "three"];
for (var i:String in myArray)
{
trace(myArray[i]);
}
// output:
// one
// two
// three
Co však nemůžete dělat, je iterování vlastností objektu v případě, že se jedná o instanci uživatelem definované třídy,
pokud třída není dynamickou třídou. I s instancemi dynamických tříd budete moci iterovat pouze vlastnosti, které jsou
přidávané dynamicky.
for each..in
Příkaz for each..in iteruje položky sbírky, což mohou být značky v objektu XML nebo XMLList, hodnoty
uchovávané vlastnostmi objektu, nebo prvky pole. Například následující výňatek ukazuje, že můžete použít cyklus for
each..in k iterování vlastností generického objektu, ale na rozdíl od cyklu for..in iterační proměnná v cyklu for
each..in obsahuje hodnotu uchovávanou vlastností namísto názvu vlastnosti:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 77
Jazyk ActionScript a jeho syntaxe
var myObj:Object = {x:20, y:30};
for each (var num in myObj)
{
trace(num);
}
// output:
// 20
// 30
Můžete iterovat objekty XML nebo XMLList, jak ukazuje následující příkaz:
var myXML:XML = <users>
<fname>Jane</fname>
<fname>Susan</fname>
<fname>John</fname>
</users>;
for each (var item in myXML.fname)
{
trace(item);
}
/* output
Jane
Susan
John
*/
Můžete také iterovat prvky pole, jak ukazuje následující příkaz:
var myArray:Array = ["one", "two", "three"];
for each (var item in myArray)
{
trace(item);
}
// output:
// one
// two
// three
Nemůžete iterovat vlastnosti objektu, pokud je objekt instancí zapouzdřené třídy. Ani pro instance dynamických tříd
nemůžete iterovat žádnou pevnou vlastnosti, která je vlastností definovanou jako součást definice třídy.
while
Příkaz cyklu while je podobný příkazu if, který se opakuje, dokud má podmínka hodnotu true. Například
následující kód produkuje stejný výstup, jako příklad cyklu for:
var i:int = 0;
while (i < 5)
{
trace(i);
i++;
}
Jednou z nevýhod používání cyklu while místo cyklu for je to, že nekonečné cykly se zapisují snáze s cykly while.
Příklad kódu cyklu for se nezkompiluje v případě, že vynecháte výraz, který zajistí zvýšení hodnoty proměnné
counter, ale příklad cyklu while se zkompiluje, pokud tento krok vynecháte. Bez výrazu, který zajistí zvýšení hodnoty
i se cyklus stane nekonečným.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 78
Jazyk ActionScript a jeho syntaxe
do..while
Příkaz cyklu do..while je cyklem while, který zaručuje, že blok kódu je vykonán alespoň jednou, protože podmínka
je kontrolována po vykonání bloku kódu. Následující kód zobrazuje jednoduchý příklad cyklu do..while, který
generuje výstup i v případě, že podmínka není splněna:
var i:int = 5;
do
{
trace(i);
i++;
} while (i < 5);
// output: 5
Funkce
Funkce jsou bloky kódu, které provádějí specifické úlohy a mohou být v programu použity opakovaně. V jazyce
ActionScript 3.0 existují dva typy funkcí: metody a uzavřené funkce. To, zda je funkce nazvaná metodou nebo
uzavřenou funkcí, závisí na kontextu, ve kterém je funkce definována. Funkce se nazývá metoda, pokud ji definujete
jako součást definice třídy nebo ji připojíte k instanci objektu. Funkce se nazývá uzavřenou funkcí, pokud je
definována jiným způsobem.
Funkce byly v jazyce ActionScript vždy extrémně důležité. V jazyce ActionScript 1.0 klíčové slovo class neexistovalo,
takže „třídy“ byly definovány funkcemi konstruktoru. I když klíčové slovo class byl od té doby do jazyka přidáno,
dobré porozumění funkcím je i nadále důležité, pokud chcete plně využít to, co jazyk nabízí. To může být výzvou
programátorům, kteří očekávají, že se funkce ActionScript budou chovat podobně, jako funkce v jazycích jako C++
nebo Java. Ačkoliv základní definice funkce a její volání by nemělo pro zkušené programátory představovat žádnou
výzvu, některé pokročilejší vlastnosti funkcí jazyka ActionScript vyžadují podrobnější vysvětlení.
Základní koncepty funkcí
Tato část popisuje základní definice funkce a techniky jejího volání.
Volání funkcí
Funkci voláte pomocí jejího identifikátoru, následovaného operátorem závorky (()). Operátor závorky použijete k
uzavření parametrů funkce, které chcete funkci odeslat. Například v celé této knize se používá funkce trace(), která
je funkcí horní úrovně v jazyce ActionScript 3.0.
trace("Use trace to help debug your script");
Pokud voláte funkci bez parametrů, musíte použít prázdný pár závorek. Můžete například použít metodu
Math.random(), která nepoužije žádný parametr, a vygenerovat náhodné číslo:
var randomNum:Number = Math.random();
Definování vlastních funkcí
Existují dva způsoby, jak definovat funkci v jazyce ActionScript 3.0: můžete použít příkaz funkce nebo výraz funkce.
Vybraná technika závisí na tom, zda dáváte přednost statickému nebo dynamickému stylu programování. Definujte
funkce s příkazy, pokud preferujete statický, nebo přísný režim programování. Definujte funkce s výrazy, pokud k
tomu máte specifický důvod. Výrazy funkce jsou častěji používaný v dynamickém, nebo standardním režimu
programování.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 79
Jazyk ActionScript a jeho syntaxe
Příkazy funkce
Příkazy funkce jsou upřednostňovanou technikou definování funkcí v přísném režimu. Příkazy funkce začínají
klíčovým slovem function, za kterým následuje:
• Název funkce
• Parametry, ve formě seznamu odděleného čárkami v závorkách
• Tělo funkce, tj. v jazyce ActionScript kód, který má být vykonán při zavolání funkce, uzavřené do složených závorek
Například následující kód vytváří funkci, která definuje parametr a pak zavolá funkci pomocí řetězce "hello" jako
hodnoty parametru:
function traceParameter(aParam:String)
{
trace(aParam);
}
traceParameter("hello"); // hello
Výrazy funkce
Druhým způsobem, jak deklarovat funkci, je použití příkazu přiřazení s výrazem funkce, což se také někdy nazývá
literál funkce nebo anonymní funkce. Existuje kompletnější metoda, která byla široce používána v předchozích verzích
jazyka ActionScript.
Příkaz přiřazení s výrazem funkce začíná klíčovým slovem var, po kterém následuje:
• Název funkce
• Operátor dvojtečka (:)
• Třída function pro definování datového typu
• Operátor přiřazení (=)
• Klíčové slovo function
• Parametry, ve formě seznamu odděleného čárkami v závorkách
• Tělo funkce, tj. v jazyce ActionScript kód, který má být vykonán při zavolání funkce, uzavřené do složených závorek
Například následujíc kód deklaruje funkci traceParameter pomocí výrazu funkce:
var traceParameter:Function = function (aParam:String)
{
trace(aParam);
};
traceParameter("hello"); // hello
Povšimněte si, že nespecifikujete název funkce, jako v příkazu funkce. Dalším důležitým rozdílem mezi výrazy a
příkazy funkce je to, že výraz funkce je spíše výrazem než příkazem. To znamená, že výraz funkce nemůže stát
samostatně, jako může příkaz funkce. Výraz funkce může být použit pouze jako součást příkazu, obvykle jako
příkazu přiřazení. Následující příklad ukazuje výraz funkce, přiřazený prvku pole:
var traceArray:Array = new Array();
traceArray[0] = function (aParam:String)
{
trace(aParam);
};
traceArray[0]("hello");
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 80
Jazyk ActionScript a jeho syntaxe
Výběr mezi příkazy a výrazy
Všeobecné pravidlo zní používat příkaz funkce, pokud specifické okolnosti nevyžadují použití výrazu. Příkazy funkce
jsou méně kompletní a poskytují konzistentnější spolupráci mezi přísným a standardním režimem, než výrazy funkce.
Příkazy funkce se snáze čtou, než výrazy funkce, které obsahují výrazy. Příkazy funkce činí kód stručnějším; jsou méně
matoucí, než výrazy funkce, které vyžadují použití klíčových slov var i function.
Příkazy funkce umožňují konzistentnější spolupráci mezi dvěma režimy kompilátoru, než tečková syntaxe v přísném
a standardním režimu, pokud je nutné vyvolat metodu deklarovanou pomocí příkazu funkce. To není nutné pravdivé
pro metody deklarované výrazem funkce. Například následující kód definuje třídu pojmenovanou Example dvěma
metodami: methodExpression(), která je deklarovaná výrazem funkce, a methodStatement(), která je deklarovaná
příkazem funkce. V přísném režimu nemůžete používat tečkovou syntaxi k vyvolání metody methodExpression().
class Example
{
var methodExpression = function() {}
function methodStatement() {}
}
var myEx:Example = new Example();
myEx.methodExpression(); // error in strict mode; okay in standard mode
myEx.methodStatement(); // okay in strict and standard modes
Výrazy funkce jsou vhodnější k programování, které se zaměřuje n a chování programu během jeho spuštění
(dynamické). Pokud dáváte přednost použití přísného režimu, ale rovněž potřebujte volat metodu deklarovanou
výrazem funkce, použijte jednu z dvou technik. První, můžete zavolat metodu pomocí hranatých závorek ([]) namísto
tečky (.) operátor. Následující volání metody je úspěšné v přísném i standardním režimu:
myExample["methodLiteral"]();
Druhá, můžete deklarovat celou třídu jako dynamickou třídu. I když toto umožňuje volat metodu pomocí operátoru
tečka, nevýhodou je to, že obětujete část funkčnosti přísného režimu pro všechny instance dané třídy. Například
kompilátor negeneruje chybu při pokusu o přístup k nedefinované vlastnosti instance dynamické třídy.
Existují jisté okolnosti, za kterých jsou výrazy funkce užitečné. Běžné využití výrazu funkce je pro funkce, které jsou
používány pouze jednou a pak jsou vyřazeny. Dalším, méně běžným použitím, je připojení funkce k vlastnosti
prototypu. Více informací naleznete v části „Objekt prototypu“ na stránce 118.
Existují dva drobné rozdíly mezi příkazem a výrazem funkce, které byste měli vzít v úvahu při volbě použité techniky.
První rozdíl spočívá v tom, že výrazy funkce neexistují nezávisle jako objekty, s ohledem na správu paměti a čištění
uvolněné paměti. Jinými slovy, když přiřadíte výraz funkce jinému objektu, například prvku pole nebo vlastnosti
objektu, vytvoříte pouze referenci na tento výraz funkce ve svém kódu. Pokud se pole nebo objekt, ke které je váš výraz
funkce připojen, dostane mimo rozsah, nebo je jinak nedostupný, nebudete již mít přístup k výrazu funkce. Pokud je
pole nebo objekt odstraněn, paměť použitá výrazem funkce bude připravena k čištění uvolněné paměti, což znamená,
že paměť bude moci být použita pro jiné účely.
Následující příklad ukazuje, že pro výraz funkce nebude tato funkce již dále dostupná, jakmile je odstraněna vlastnost,
ke které je výraz přiřazen. Třída Test je dynamická, což znamená, že můžete přidat vlastnosti pojmenovanou
functionExp, která uchovává výraz funkce. Funkce functionExp() může být volána operátorem tečka, ale jakmile
je vlastnost functionExp odstraněna, funkce již není přístupná.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 81
Jazyk ActionScript a jeho syntaxe
dynamic class Test {}
var myTest:Test = new Test();
// function expression
myTest.functionExp = function () { trace("Function expression") };
myTest.functionExp(); // Function expression
delete myTest.functionExp;
myTest.functionExp(); // error
Pokud na druhou stranu bude funkce nejprve definována příkazem funkce, existuje jako vlastní objekt a existuje i poté,
co odstraníte vlastnost, ke které byla funkce připojena. Operátor delete je funkční pouze pro vlastnosti objektů, takže
i volání pro odstranění funkce stateFunc() samotné nepracuje.
dynamic class Test {}
var myTest:Test = new Test();
// function statement
function stateFunc() { trace("Function statement") }
myTest.statement = stateFunc;
myTest.statement(); // Function statement
delete myTest.statement;
delete stateFunc; // no effect
stateFunc();// Function statement
myTest.statement(); // error
Druhým rozdílem mezi výrazem a příkazem funkce je to, že výraz funkce existuje v rámci rozsahu, ve kterém je
definován, včetně příkazů in, které se objevují před příkazem funkce. Výrazy funkce jsou oproti tomu definovány
pouze pro následující příkazy. Například následující kód úspěšně volá funkci scopeTest() před jejím definováním:
statementTest(); // statementTest
function statementTest():void
{
trace("statementTest");
}
Výrazy funkce nejsou dostupné před definováním, takže následující kód vede k chybě při spuštění kódu:
expressionTest(); // run-time error
var expressionTest:Function = function ()
{
trace("expressionTest");
}
Vracení hodnot z funkcí
Chcete-li, aby funkce vrátila hodnotu, použijte příkaz return následovaný výrazem nebo literálovou hodnotou,
kterou chcete vrátit. Například následující kód vrací výraz, představující parametr:
function doubleNum(baseNum:int):int
{
return (baseNum * 2);
}
Povšimněte si, že příkaz return končí funkcí, takže všechny příkazy pod příkazem return nebudou vykonány a to
následujícím způsobem:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 82
Jazyk ActionScript a jeho syntaxe
function doubleNum(baseNum:int):int {
return (baseNum * 2);
trace("after return"); // This trace statement will not be executed.
}
V přísném režimu musíte vrátit hodnotu vhodného typu, protože nevrací platnou hodnotu: Například následující kód
generuje v přísném režimu chybu, protože nevrací platnou hodnotu:
function doubleNum(baseNum:int):int
{
trace("after return");
}
Vnořené funkce
Funkce můžete vnořovat, což znamená, že funkce mohou být deklarovány uvnitř jiných funkcí. Vnořená funkce je
dostupná pouze ve své nadřazené funkci, pokud není odkaz na tuto funkci předán externímu kódu. Například
následující kód deklaruje dvě vnořené funkce uvnitř funkce getNameAndVersion():
function getNameAndVersion():String
{
function getVersion():String
{
return "10";
}
function getProductName():String
{
return "Flash Player";
}
return (getProductName() + " " + getVersion());
}
trace(getNameAndVersion()); // Flash Player 10
Když jsou vnořené funkce předány externímu kódu, jsou předány jako uzavřené funkce, což znamená, že funkce si
uchovává všechny definice, které jsou v rozsahu při definování funkce. Další informace, viz „Rozsah funkce“ na
stránce 87.
Parametry funkce
Jazyk ActionScript 3.0 poskytuje některé funkčnosti pro parametry funkcí, které mohou novým programátorům
tohoto jazyka připadat jako neobvyklé. I když princip předávání parametrů hodnotou nebo odkazem by měl být
většině programátorů znám, objekt arguments a parametr ... (zbytek) mohou být pro mnoho z nich nové.
Předávání argumentů hodnotou nebo odkazem
V mnoha programovacích jazycích je důležité porozumět odlišnosti mezi předáváním argumentů hodnotou nebo
odkazem; rozdíl může ovlivňovat způsob tvorby kódu.
Předání hodnotou znamená, že hodnota argumentu je kopírována do místní proměnné pro použití v rámci funkce.
Předání odkazem znamená, že je předán pouze odkaz na argument, místo skutečné hodnoty. Není zhotovena žádná
kopie stávajícího argumentu. Místo toho se vytvoří odkaz na proměnnou předaný jako argument a je přiřazen místní
proměnné pro použití v rámci funkce. Jako odkaz na proměnnou vně funkce umožňuje místní proměnné změnit
hodnotu původní proměnné.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 83
Jazyk ActionScript a jeho syntaxe
V jazyce ActionScript 3.0 jsou všechny argumenty předávány formou odkazu, protože všechny hodnoty jsou uloženy
jako objekty. Nicméně objekty, které náleží primitivním datovým typům, což zahrnuje Boolean, Number, int, uint a
String, mají speciální operátory, které jim umožňují chovat se, jako by byly předány hodnotou. Například následující
kód vytvoří funkci pojmenovanou passPrimitives(), která definuje dva parametry pojmenované xParam a yParam,
obojí typu int. Tyto parametry jsou podobné místním proměnným, deklarovaným uvnitř těla funkce
passPrimitives(). Když je zavolána funkce s argumenty xValue a yValue, parametry xParam a yParam jsou
inicializovány s odkazy na objekty int zastoupené xValue a yValue. Protože argumenty jsou primitivní, chovají se jako
by předaly hodnotu. I když xParam a yParam v počátku obsahují pouze odkazy na hodnotu objektů xValue a yValue,
všechny změny proměnných v těle funkce generují nové kopie hodnoty v paměti.
function passPrimitives(xParam:int, yParam:int):void
{
xParam++;
yParam++;
trace(xParam, yParam);
}
var xValue:int = 10;
var yValue:int = 15;
trace(xValue, yValue);// 10 15
passPrimitives(xValue, yValue); // 11 16
trace(xValue, yValue);// 10 15
Ve funkci passPrimitives() jsou hodnoty xParam a yParam zvýšeny, to však neovlivňuje hodnoty xValue a yValue,
jak je znázorněno v posledním výrazu trace . To by bylo pravdivé v případě, že parametry byly pojmenovány shodně
s proměnnými, xValue a yValue, protože xValue a yValue uvnitř funkce by ukazovaly do nového umístění v paměti,
které existuje odděleně od proměnných stejného názvu vně funkce.
Všechny ostatní objekty, tj. objekty nenáležící primitivním datovým typům, jsou vždy předány odkazem, což
umožňuje změnit hodnotu původní proměnné. Například následující kód vytváří objekt pojmenovaný objVar se
dvěma vlastnostmi, x a y. Objekt je předán jako argument funkci passByRef(). Protože objekt není primitivním
typem, nejenom, že je předán jako odkaz, ale také tímto odkazem zůstane. To znamená, že změny provedené v
parametru ve funkci ovlivní vlastnosti objektu vně funkce.
function passByRef(objParam:Object):void
{
objParam.x++;
objParam.y++;
trace(objParam.x, objParam.y);
}
var objVar:Object = {x:10, y:15};
trace(objVar.x, objVar.y); // 10 15
passByRef(objVar); // 11 16
trace(objVar.x, objVar.y); // 11 16
Parametr objParam odkazuje na stejný objekt, jako globální proměnná objVar. Jak je možné vidět na příkazech trace
v příkladu, změny vlastností x a y objektu objParam se odrazí v objektu objVar.
Výchozí hodnoty parametru
Novinkou v jazyce ActionScript 3.0 je schopnost deklarovat výchozí hodnoty parametru pro danou funkci. Pokud
volání funkce s výchozími hodnotami parametrů vynechá parametr s výchozími hodnotami, použije se hodnota
uvedená v definice funkce pro daný parametr. Všechny parametry s výchozími hodnotami musí být umístěny na konci
seznamu parametrů. Hodnoty přiřazené jako výchozí hodnoty musí být konstanty z času kompilace. Existence výchozí
hodnoty pro parametr efektivně činí tento parametr volitelným parametrem. Parametr bez výchozí hodnoty je
považován za vyžadovaný parametr.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 84
Jazyk ActionScript a jeho syntaxe
Například následující kód vytváří funkci se třemi parametry, dva z nich mají výchozí hodnoty. Když je funkce volaná
pouze jedním parametrem, použijí se pro parametry výchozí hodnoty.
function defaultValues(x:int, y:int = 3, z:int = 5):void
{
trace(x, y, z);
}
defaultValues(1); // 1 3 5
Objekt arguments
Když jsou funkci předány parametry, můžete použít objekt arguments pro přístup k informacím o parametrech
předaných vaší funkci. Některé důležité aspekty objektu arguments zahrnují následující:
• Objekt arguments je polem, které zahrnuje všechny parametry předané funkci.
• Vlastnost arguments.length hlásí počet parametrů předaných funkci.
• Vlastnost arguments.callee poskytuje odkaz na samotnou funkci, což je užitečné pro rekurzivní volání výrazů
funkce.
Poznámka: Objekt arguments není dostupný v případě, že některý parametr je pojmenován arguments, nebo pokud
použijete parametr ... (zbytek).
Jestliže je objekt argumentsodkazován v těle funkce, jazyk ActionScript 3.0 umožňuje, aby volání funkce
zahrnovalo více parametrů, než je definováno v definici funkce, ale vygeneruje chybu kompilátoru v přísném
režimu, pokud počet parametrů neodpovídá počtu vyžadovaných parametrů (a volitelně libovolných volitelných
parametrů). Můžete použít aspekt pole objektu arguments a přistupovat k libovolnému parametru předanému
funkci, bez ohledu na to, zda je funkce definovaná v definici funkce, nebo nikoliv. Následující příklad, který se
kompiluje pouze ve standardním režimu, používá pole arguments společně s vlastností arguments.length ke
sledování všech parametrů předaných funkci traceArgArray():
function traceArgArray(x:int):void
{
for (var i:uint = 0; i < arguments.length; i++)
{
trace(arguments[i]);
}
}
traceArgArray(1, 2, 3);
//
//
//
//
output:
1
2
3
Vlastnost arguments.callee je často používána v anonymních funkcí pro vytvoření rekurze. Můžete ji používat
ke zvýšení flexibility svého kódu. Pokud se název rekurzivní funkce změní v průběhu cyklu vývoje, nemusíte se
starat o změnu rekurzivního volání ve své funkci, pokud použijete arguments.callee místo názvu funkce.
Vlastnost arguments.callee se používá v následujícím výrazu funkce pro umožnění rekurze:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 85
Jazyk ActionScript a jeho syntaxe
var factorial:Function = function (x:uint)
{
if(x == 0)
{
return 1;
}
else
{
return (x * arguments.callee(x - 1));
}
}
trace(factorial(5)); // 120
Pokud použijete parametr ... (zbytek) ve své deklaraci funkce, objekt arguments vám nebude dostupný. Místo toho
musíte přistupovat k parametrům pomocí názvů, které pro ně deklarujete.
Měli byste být také opatrní a vyhnout se používání "arguments" jako názvu parametru, protože dojde k vytvoření
stínových objektů arguments. Pokud je například funkce traceArgArray()přepsána tak, aby byl přidán parametr
arguments, odkazy na arguments v těle funkce odkazují na parametr, spíše než na objekt arguments. Následující
kód nevytváří žádný vstup:
function traceArgArray(x:int, arguments:int):void
{
for (var i:uint = 0; i < arguments.length; i++)
{
trace(arguments[i]);
}
}
traceArgArray(1, 2, 3);
// no output
Objekt arguments v předchozí verzi jazyka ActionScript také obsahoval vlastnost pojmenovanou caller, která je
odkazem na funkci volanou stávající funkcí. Vlastnost caller není v jazyce ActionScript 3.0 zastoupena, ale pokud
potřebujete odkaz na volající funkci, můžete ji změnit tak, aby předala dodatečný parametr, který je odkazem na
sebe samotný.
Parametr ... (zbytek)
Jazyk ActionScript 3.0 zavádí novou deklaraci parametru nazvanou parametr ... (zbytek). Tento parametr umožňuje
specifikovat parametr pole, který přijímá jakýkoliv počet argumentů oddělených čárkou. Parametr může mít jakýkoliv
název, který není vyhrazeným slovem. Tato deklarace parametru musí být posledním specifikovaným parametrem.
Použití tohoto parametru činí objekt arguments nedostupným. I když parametr ... (zbytek) poskytuje stejnou
funkčnost, jako pole arguments a vlastnost arguments.length, neposkytuje funkčnost podobnou té, kterou nabízí
arguments.callee. Měli byste zajistit, že nebudete muset použít arguments.callee před použitím parametru ...
(zbytek).
Následující příklad přepisuje funkci traceArgArray() pomocí parametru ... (zbytek) namísto objektu arguments:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 86
Jazyk ActionScript a jeho syntaxe
function traceArgArray(... args):void
{
for (var i:uint = 0; i < args.length; i++)
{
trace(args[i]);
}
}
traceArgArray(1, 2, 3);
//
//
//
//
output:
1
2
3
Parametr ... (zbytek) může být také použit s ostatními parametry, pokud se jedná o poslední parametr v seznamu.
Následující příklad modifikuje funkci traceArgArray() tak, aby její první parametr x byl typu int a druhý parametr
používal parametr ... (zbytek). Výstup vynechává první hodnotu, protože první parametr již není součástí pole
vytvořeného parametrem ... (zbytek).
function traceArgArray(x: int, ... args)
{
for (var i:uint = 0; i < args.length; i++)
{
trace(args[i]);
}
}
traceArgArray(1, 2, 3);
// output:
// 2
// 3
Funkce jako objekty
Funkce v jazyce ActionScript 3.0 jsou objekty. Když vytvoříte funkci, vytváříte objekt, kterýž nemůže být předán jako
parametr jiné funkci, ale má k sobě také připojené vlastnosti a metody.
Funkce předané jako argumenty jiné funkci jsou předány formou odkazu a nikoliv hodnotou. Když předáte funkci
jako argument, použijete pouze identifikátor a nikoliv operátor závorky, který používáte k zavolání metody. Například
následující kód předává funkci pojmenovanou clickListener() jako argument metody addEventListener():
addEventListener(MouseEvent.CLICK, clickListener);
Metoda Array.sort() rovněž definuje parametr, který funkci přijímá. Příklad funkce uživatelského třídění, která je
použita jako argument pro funkci Array.sort(), viz také „Třídění pole“ na stránce 159.
I když se to může zdát novým programátorům jazyka ActionScript podivné, funkce mohou mít vlastnosti a metody,
stejně jako kterékoliv ostatní objekty. Ve skutečnosti každá funkce má vlastnost pouze ke čtení, pojmenovanou
length, která ukládá několik parametrů definovaných pro funkci. To je odlišné od vlastnosti arguments.length,
která hlásí počet argumentů odeslaných funkci. Vzpomeňte si, že v jazyce ActionScript počet argumentů odeslaných
funkci může překročit počet parametrů definovaných pro tuto funkci. Následující příklad, který se kompiluje pouze
ve standardním režimu, protože přísný režim vyžaduje přesnou shodu mezi počtem předaných argumentů a počtem
argumentů definovaných, zobrazuje rozdíl mezi dvěma vlastnostmi:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 87
Jazyk ActionScript a jeho syntaxe
// Compiles only in standard mode
function traceLength(x:uint, y:uint):void
{
trace("arguments received: " + arguments.length);
trace("arguments expected: " + traceLength.length);
}
traceLength(3, 5, 7, 11);
/* output:
arguments received: 4
arguments expected: 2 */
Ve standardním režimu můžete definovat své vlastní vlastnosti funkce jejich nadefinováním vně těla funkce.
Vlastnosti funkce mohou sloužit jako kvazi-statické vlastnosti, umožňující uložit stav proměnné, související s funkcí.
Například můžete chtít sledovat počet volání specifické funkce. Taková funkce může být užitečná v případě, že píšete
hru a chcete sledovat počet použití specifického příkazu uživatelem, i když proto můžete také použít vlastnost třídy
static. Následující příklad, který se kompiluje pouze ve standardním režimu, protože přísný režim neumožňuje
přidávat k funkci dynamické vlastnosti, vytváří vlastnost funkce mimo deklarování funkce a zajišťuje zvýšení hodnoty
vlastnosti při každém zavolání funkce:
// Compiles only in standard mode
var someFunction:Function = function ():void
{
someFunction.counter++;
}
someFunction.counter = 0;
someFunction();
someFunction();
trace(someFunction.counter); // 2
Rozsah funkce
Rozsah funkce stanoví nejenom to, kde může být program zavolán, ale také k jakým definicím může funkce
přistupovat. Stejný rozsah pravidel, který platí pro identifikátory proměnné, platí také pro identifikátory funkce.
Funkce deklarované v globálním rozsahu je přístupná prostřednictvím vašeho kódu. Například jazyk ActionScript 3.0
obsahuje globální funkce, například isNaN() a parseInt(), které jsou dostupné kdekoliv ve vašem kódu. Vnořená
funkce - funkce deklarovaná v jiné funkci - může být použita kdekoliv ve funkci, ve které byla deklarovaná.
Řetěz rozsahu
Při každém spuštění vykonávání funkce je vytvořeno několik objektů a vlastností. Za prvé je vytvořen speciální objekt
nazvaný aktivační objekt, který uloží parametr a všechny místní proměnné nebo funkce deklarované v těle funkce.
Nemůžete přistupovat k objektu aktivace přímo, protože se jedná i interní mechanismu. Za druhé je vytvořen řetěz
rozsahu, který obsahuje seznam objektů, které aplikace Flash Player nebo Adobe AIR kontroluje, zda obsahují
deklarace identifikátoru. Každá funkce, která je spouštěna, má řetěz rozsahu, který je uložen ve vnitřní vlastnosti. Pro
vnořené funkce řetěz rozsahu začíná vlastní aktivací objektu, následovanou aktivačním objektem nadřazené funkce.
Řetěz pokračuje tímto způsobem, dokud nedosáhne globálního objektu. Spustí se globální objekt, který je vytvořen v
programu v jazyce ActionScript, a obsahuje všechny globální proměnné a funkce.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 88
Jazyk ActionScript a jeho syntaxe
Uzavřené funkce
Uzavřená funkce je objektem, který obsahuje snímek funkce a jeho lexikální prostředí. Lexikální prostředí funkce
zahrnuje všechny proměnné, vlastnosti, metody a objekty v řetězu rozsahu funkce, společně s jejich hodnotami.
Uzavřené funkce jsou vytvořeny vždy při vykonání funkce, odloučeně od objektu nebo třídy. Skutečnost, že uzavřené
funkce si uchovávají rozsah, ve kterém byly definovány, vytváří zajímavé výsledky, když je funkce předána jako
argument nebo vrací hodnotu jinému rozsahu.
Například následující kód vytváří dvě funkce: foo(), která vrací vnořenou funkci pojmenovanou rectArea(), která
vypočítává plochu trojúhelníku a funkci bar(), která volá foo() a ukládá vrácenou uzavřenou funkci do proměnné
nazvané myProduct. I když funkce bar() definuje vlastní místní proměnnou x (s hodnotou 2), když je zavolána
uzavřená funkce myProduct(), uchovává proměnnou x (s hodnotou 40) definovanou ve funkci foo(). Funkce
bar() proto vrací hodnotu 160 místo 8.
function foo():Function
{
var x:int = 40;
function rectArea(y:int):int // function closure defined
{
return x * y
}
return rectArea;
}
function bar():void
{
var x:int = 2;
var y:int = 4;
var myProduct:Function = foo();
trace(myProduct(4)); // function closure called
}
bar(); // 160
Metody se chovají podobně v tom, že si uchovávají informace o lexikálním prostředí, ve kterém byly vytvořeny. Tato
charakteristika je nejznatelnější v případě, že metoda je extrahována ze své instance, což vytvoří vázanou metodu.
Hlavní rozdíl mezi uzavřenou funkcí a vázanou metodou je v tom, že hodnota klíčového slova this ve vázané metodě
vždy odkazuje na instanci, ke které byla původně připojena, zatímco v uzavřené funkci se hodnota klíčového slova
this může měnit. Další informace naleznete v části „Metody“ na stránce 96.
89
Kapitola 5: Objektově orientované
programování v jazyce ActionScript
Tato kapitola popisuje prvky jazyka ActionScript, které podporují objektově orientované programování (OOP). Tato
kapitola nepopisuje obecné principy OOP, jako je navrhování objektu, abstrakce, zapouzdření, dědičnost a
polymorfizmus. Tato kapitola je zaměřena na způsob použití těchto principů pomocí jazyka ActionScript 3.0.
Díky kmenům jazyka ActionScript jako skriptového jazyka, je podpora OOP ActionScript 3.0 volitelná. To nabízí
programátorům flexibilitu ve výběru nejlepšího přístupu pro projekty různého rozsahu a složitosti. U malých úloh
můžete zjistit, že používání jazyka ActionScript s paradigmatem procedurálního plánování je vše, co potřebujete. U
větších projektů bude díky použití principů OOP snazší váš kód pochopit, udržovat a rozšiřovat.
Základy objektově orientovaného programování
Úvod k objektově orientovanému programování
Objektově orientované programování (OOP) je způsob organizování kódu v programu jeho seskupením do objektů jednotlivé elementy, které zahrnují informace (hodnoty dat) a funkčnost. Používání přístupu orientovaného na objekt
k organizování programu vám umožňuje seskupit určité informace (například hudební informace jako je název alba,
název stopy, nebo jméno interpreta) společně s funkcí nebo akcemi spojenými s danou informací (např. „přidat stopu
k seznamu přehrávání” nebo „přehrát všechny písně od tohoto interpreta”). Tyto položky jsou zkombinovány do jedné
jediné položky, a to objektu (například „Album” nebo „MusicTrack”). Možnost seskupit tyto hodnoty a funkce
dohromady nabízí několik výhod, včetně potřeby sledovat pouze jedinou proměnnou, nikoliv několik proměnných,
společné organizace souvisejících funkcí a schopnosti strukturovat programy tak, aby lépe odpovídaly reálnému světu.
Běžné úlohy objektově orientovaného programování
V praxi má objektově orientované programování dvě části. Jednou částí jsou strategie a techniky pro navrhování
programu (často se nazývají navrhování orientované na objekt). Toto je široké téma a v této kapitole není zmíněno.
Další částí OOP jsou vlastní struktury programování, které jsou dostupné v daném programovacím jazyce pro
vytvoření programu pomocí přístupu orientovaného na objekt. Tato kapitola se věnuje následujícím běžným úlohám
v OOP:
• Definování tříd
• Vytváření vlastností, metod a přístupových mechanismů získání a nastavení (metody přístupových mechanismů)
• Ovládání přístupu ke třídám, vlastnostem, metodám a přístupovým mechanismům
• Vytváření statických vlastností a metod
• Vytváření struktur vyčíslení
• Definování a používání rozhraní
• Práce s dědičností, včetně potlačení prvků tříd
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 90
Objektově orientované programování v jazyce ActionScript
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Atribut: Charakteristika přiřazená k prvku třídy (například vlastnost nebo metoda) v definici třídy. Atributy jsou
běžně používány pro definování, zda daná vlastnost nebo metoda bude dostupná pomocí kódu v jiných částech
programu. Například private a public jsou atributy. Soukromá metoda může být vyvolána pouze kódem v rámci
třídy, zatímco veřejná metoda může být vyvolána jakýmkoliv kódem v programu.
• Třída: Definice struktury a chování objektů určitého typu (například šablony nebo modrotisku pro objekty daného
typu dat).
• Hierarchie třídy: Struktura několika souvisejících tříd určující, které třídy dělí funkčnost z jiných tříd.
• Konstruktor: Zvláštní metoda, kterou můžete definovat ve třídě, a která je vyvolána při vytvoření instance dané
třídy. Konstruktor je běžně používán pro určení výchozích hodnot nebo pro jiné provedení operací nastavení pro
daný objekt.
• Typ dat: Typ informace, kterou může určitá proměnná uchovat. Obecně znamená datový typto samé jako třída.
• Operátor tečky: Znak periody (.), který je v jazyce ActionScript (a mnoha dalších programovacích jazycích)
používán k označení, že název odkazuje na podřízený prvek objektu (například vlastnost nebo metodu). Například
ve výrazu myObject.myProperty označuje operátor tečky, že pojem myProperty odkazuje na stejnou hodnotu,
která je prvkem objektu nazvaného myObject.
• Výčet: Množina souvisejících konstantních hodnot, pro usnadnění seskupená jako vlastnosti jediné třídy.
• Dědičnost: Mechanismus OOP, který umožňuje, aby jedna definice třídy zahrnovala všechny funkce definicí
různých tříd (a obecně funkce rozšiřuje).
• Instance: Skutečný objekt vytvořený v programu.
• Jmenný prostor: V podstatě vlastní atribut umožňující lepší kontrolu nad tím, který kód má přístup k jinému kódu.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Protože
kódy uvedené v této kapitole se primárně zabývají definováním a manipulací s datovými typy, bude vyzkoušení těchto
příkladů zahrnovat vytvoření instance definované třídy, manipulaci s danou instancí pomocí jejích vlastností nebo
metod a poté zobrazení hodnot vlastností dané instance. Pro zobrazení těchto hodnot budete chtít zapsat hodnoty do
instance textového pole na ploše, nebo použít funkci trace() pro vytištění hodnoty na panel Výstup. Tyto techniky
jsou podrobně popsány v části „Testování příkladů kódu v této kapitole“ na stránce 34.
Třídy
Třída je abstraktní reprezentací objektu. Třída uchovává informace o typech dat, které objekt může mít a o chování,
které může objekt vykazovat. Užitečnost této abstrakce nemusí být zřejmá při psaní malých skriptů, které obsahují
pouze několik navzájem reagujících objektů. Se zvětšujícím se rozsahem programu se nicméně počet objektů, které je
nutné spravovat, zvětšuje a můžete zjistit, že vám třídy umožňují lepší kontrolu způsobu vytváření objektů a způsobu
jejich vzájemné interakce.
Již od jazyka ActionScript 1.0 mohli programátoři využívající jazyk ActionScript použít objekty funkce pro vytvoření
konstruktů, které se podobaly třídám. Jazyk ActionScript 2.0 přidal formální podporu tříd pomocí klíčových slov,
například class a extends. Jazyk ActionScript 3.0 nejen i nadále podporuje klíčová slova zavedená v jazyce
ActionScript 2.0, ale přidává také některé nové možnosti, například vylepšené ovládání přístupu s atributy protected
a internal a lepší ovládání dědičnosti pomocí klíčových slov final a override.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 91
Objektově orientované programování v jazyce ActionScript
Jestliže jste někdy vytvářeli třídy v programovacích jazycích jako Java, C++, nebo C#, zjistíte, že jazyk ActionScript
nabízí podobnou zkušenost. Jazyk ActionScript sdílí mnoho stejných klíčových slov a názvů atributů, například class,
extends a public a všechny tyto výrazy jsou uvedeny v následujících oddílech.
Poznámka: V této kapitole znamená pojem vlastnost jakýkoliv člen objektu nebo třídy, včetně proměnných, konstant a
metod. Dále ačkoliv jsou pojmy třída a statický často navzájem zaměňovány, v této kapitole se tyto pojmy liší. Například
v této kapitole se fráze vlastnosti třídy vztahuje na všechny členy třídy, nikoliv pouze na statické členy.
Definice třídy
Definice třídy jazyka ActionScript 3.0 používají syntaxi, která je podobná syntaxi používané v definici tříd jazyka
ActionScript 2.0. Správná syntaxe pro definici třídy vyvolá klíčové slovo class následované názvem třídy. Tělo třídy,
které je obklopeno složenými závorkami ({}), následuje za názvem třídy. Například následující kód vytvoří třídu
pojmenovanou Shape, která obsahuje jednu proměnnou pojmenovanou visible:
public class Shape
{
var visible:Boolean = true;
}
Jedna důležitá změna syntaxe zahrnuje definice třídy, které jsou uvnitř balíku. Jestliže je v jazyce ActionScript 2.0 třída
uvnitř balíku, musí být název balíku obsažen v deklaraci třídy. V jazyce ActionScript 3.0, který zahrnuje příkaz
package, musí být název balíku zahrnut do deklarace balíku namísto zahrnutí v deklaraci třídy. Například následující
deklarace třídy ukazuje, jak je třída BitmapData, která je součástí balíku flash.display, definována v jazycích
ActionScript 2.0 a ActionScript 3.0:
// ActionScript 2.0
class flash.display.BitmapData {}
// ActionScript 3.0
package flash.display
{
public class BitmapData {}
}
Atributy třídy
Jazyk ActionScript 3.0 vám umožňuje úpravu definicí třídy pomocí jednoho z následujících čtyř atributů:
Atribut
Definice
dynamic
Umožňuje přidávání vlastností k instancím v čase zpracování.
final
Nesmí být rozšířeno jinou třídou.
internal (výchozí)
Viditelné pro reference uvnitř aktuálního balíku.
public
Viditelné pro odkazy kdekoliv.
Pro každý z těchto atributů, s výjimkou atributu internal, jej musíte pro získání přiřazeného chování výslovně
zahrnout. Pokud například při definování třídy nezahrnete atribut dynamic, nebudete moct přidat vlastnosti do
instance třídy v čase zpracování. Atribut výslovně přiřadíte jeho umístěním na začátek definice třídy, dle příkladu v
následujícím kódu:
dynamic class Shape {}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 92
Objektově orientované programování v jazyce ActionScript
Všimněte si, že seznam nezahrnuje atribut nazvaný abstract. Důvodem je to, že abstraktní třídy nejsou v jazyce
ActionScript 3.0 podporovány. Všimněte si také, že seznam nezahrnuje atributy pojmenované private a protected.
Tyto atributy mají význam pouze uvnitř definice třídy a nelze je použít na samotné třídy. Jestliže nechcete, aby byla
třída mimo balík veřejně viditelná, umístěte jí dovnitř balíku a označte třídu atributem internal. Můžete také
vypustit atribut internal i public a kompilátor automaticky přidá atribut internal. Jestliže nechcete, aby byla třída
viditelná mimo zdrojový soubor, ve kterém je definována, umístěte třídu na konec svého zdrojového souboru, pod
uzavírající složenou závorkou definice balíku.
Tělo třídy
Tělo třídy, které je obklopeno složenými závorkami, je používáno pro definování proměnných, konstant a metod vaší
třídy. Následující příklad ukazuje deklaraci pro třídu přístupnosti v přehrávači Adobe Flash Player API:
public final class Accessibility
{
public static function get active():Boolean;
public static function updateProperties():void;
}
Jmenný prostor můžete definovat také uvnitř těla třídy. Následující příklad ukazuje, jak lze definovat jmenný prostor
v těle třídy, a jak je použít jako atribut metody v dané třídě:
public class SampleClass
{
public namespace sampleNamespace;
sampleNamespace function doSomething():void;
}
Jazyk ActionScript 3.0 vám umožňuje do těla třídy zahrnout nejen definice, ale také příkazy. Příkazy, které jsou uvnitř
těla třídy, ale mimo definice metody, jsou provedeny právě jednou - při první detekci definice třídy a při vytvoření
přidruženého objektu třídy. Následující příklad zahrnuje volání externí funkce hello()a příkaz trace, který vytvoří
hlášení o potvrzení při definování třídy:
function hello():String
{
trace("hola");
}
class SampleClass
{
hello();
trace("class created");
}
// output when class is created
hola
class created
V porovnání s předchozími verzemi jazyka ActionScript je v jazyce ActionScript 3.0 povoleno definovat statickou
vlastnost a vlastnost instance se stejným názvem v těle stejné třídy. Například následující kód deklaruje statickou
proměnnou nazvanou message a proměnnou instance stejného názvu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 93
Objektově orientované programování v jazyce ActionScript
class StaticTest
{
static var message:String = "static variable";
var message:String = "instance variable";
}
// In your script
var myST:StaticTest = new StaticTest();
trace(StaticTest.message); // output: static variable
trace(myST.message); // output: instance variable
Atributy vlastnosti třídy
Mluvíme-li o modelu objektu jazyka ActionScript, pojem vlastnost znamená cokoliv, co může být členem třídy, včetně
proměnných, konstant a metod. Toto se liší od způsobu použití tohoto pojmu v referenční příručce jazyka a
komponent jazyka ActionScript 3.0, kde je tento pojem požíván úžeji a zahrnuje pouze členy třídy, které jsou
proměnné nebo definované pomocí metody mechanismu získání nebo nastavení. V jazyce ActionScript 3.0 existuje
množina atributů, které lze použít s jakoukoliv vlastností třídy. Následující tabulka uvádí tuto množinu atributů.
Atribut
Definice
internal (výchozí)
Viditelné pro odkazy uvnitř stejného balíku.
private
Viditelné pro odkazy ve stejné třídě.
protected
Viditelné pro odkazy ve stejné a v odvozených třídách.
public
Viditelné pro odkazy kdekoliv.
static
Narozdíl od instancí třídy určuje, že vlastnost patří do příslušné třídy.
UserDefinedNamespace
Název vlastního jmenného prostoru definovaného uživatelem.
Atributy jmenného prostoru pro ovládání přístupu
Jazyk ActionScript 3.0 nabízí čtyři speciální atributy, které ovládají přístup k vlastnostem definovaných uvnitř třídy:
public, private, protected a internal.
Atribut public zviditelní vlastnost kdekoliv ve vašem skriptu. Například pro to, aby byla metoda dostupná pro kód
mimo svůj balík, musíte deklarovat metodu s atributem public. To platí pro jakoukoliv vlastnost, ať už je deklarována
pomocí klíčových slov var, const nebo function.
Atribut private zviditelní vlastnost pouze pro volání v rámci třídy definující danou vlastnost. Toto chování se
odlišuje od chování atributu private v jazyce ActionScript 2.0, který umožňoval přístup podtřídy k soukromé
vlastnosti v nadřazené třídě. Další důležitá změna v chování se týká přístupu v čase zpracování. V jazyce ActionScript
2.0 klíčové slovo private zakazovalo přístup pouze v čase sestavování a v čase zpracování jej šlo snadno obejít. V
jazyce ActionScript 3.0 toto již neplatí. Vlastnosti označené jako private jsou nedostupné v čase kompilace i v čase
zpracování.
Například následující kód vytvoří jednoduchou třídu pojmenovanou PrivateExample s jednou soukromou
proměnnou a poté se pokusí o přístup k soukromé proměnné z vnějšku třídy. V jazyce ActionScript 2.0 byl přístup v
čase kompilace zakázán, ale zákaz šlo snadno obejít pomocí operátoru přístupu k vlastnosti ([]), který provede
vyhledání vlastnosti v čase zpracování, nikoliv v čase kompilace.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 94
Objektově orientované programování v jazyce ActionScript
class PrivateExample
{
private var privVar:String = "private variable";
}
var myExample:PrivateExample = new PrivateExample();
trace(myExample.privVar);// compile-time error in strict mode
trace(myExample["privVar"]); // ActionScript 2.0 allows access, but in ActionScript 3.0, this
is a run-time error.
V jazyce ActionScript 3.0 má pokus o přístup k soukromé vlastnosti pomocí operátoru tečky (myExample.privVar)
v případě použití přísného režimu za následek chybu v čase kompilace. V jiném případě je chyba nahlášena v čase
zpracování, stejně jako při použití operátoru pro přístup k vlastnosti (myExample["privVar"]).
Následující tabulka uvádí přehled výsledku přístupu k soukromé vlastnosti, která náleží k uzavřené (nikoliv dynamické
) třídě:
Přísný režim
Standardní režim
operátor tečky (.)
chyba v čase kompilace
chyba v čase zpracování
operátor závorky ([])
chyba v čase zpracování
chyba v čase zpracování
Ve třídách deklarovaných pomocí atributu dynamic nebudou mít pokusy o přístup k soukromé proměnné za následek
chybu v čase zpracování. Namísto toho je proměnná jednoduše neviditelná, takže přehrávač Flash Player nebo Adobe®
AIR™ vrátí hodnotu undefined. K chybě v čase kompilace nicméně dojde, pokud používáte operátor tečky v přísném
režimu. Následující příklad je stejný jako předcházející příklad, pouze s výjimkou, že třída PrivateExample je
deklarována jako dynamická:
dynamic class PrivateExample
{
private var privVar:String = "private variable";
}
var myExample:PrivateExample = new PrivateExample();
trace(myExample.privVar);// compile-time error in strict mode
trace(myExample["privVar"]); // output: undefined
Dynamické třídy obecně vrací hodnotu undefined namísto vygenerování chyby v případě, kdy se kód externí ke třídě
pokouší o přístup k soukromé vlastnosti. Následující tabulka ukazuje, že chyba je vygenerována pouze tehdy, je-li
operátor tečky používán pro přístup k soukromé vlastnosti v přísném režimu.
Přísný režim
Standardní režim
operátor tečky (.)
chyba v čase kompilace
undefined
operátor závorky ([])
undefined
undefined
Atribut protected, který je v jazyce ActionScript 3.0 nový, zviditelní vlastnost pro volající v rámci vlastní třídy nebo
podtřídy. Jinými slovy, chráněná vlastnost je dostupná v rámci vlastní třídy nebo pro třídy, které leží kdekoliv pod ní
v hierarchii dědičnosti. To je pravdivé pro podtřídu ve stejném i v odlišném balíku.
Pro ty z vás, kteří znají jazyk ActionScript 2.0, je tato funkce podobná atributu private v jazyce ActionScript 2.0.
Atribut jazyka ActionScript 3.0 protected je podobný atributu protected v aplikaci Java, ale liší se v tom, že verze
Java také povoluje přístup k volajícím v rámci stejného balíku. Atribut protected je užitečný, jestliže máte
proměnnou nebo metodu, kterou vaše podtřídy potřebují skrýt z kódu mimo řetězec dědičnosti.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 95
Objektově orientované programování v jazyce ActionScript
Atribut internal, který je v jazyce ActionScript 3.0 nový, zviditelní vlastnost pro volající v rámci svého vlastního
balíku. Jedná se o výchozí atribut pro kód uvnitř balíku a použije se na jakoukoliv vlastnost, která nemá žádný z
následujících atributů:
•
public
•
private
•
protected
• uživatelem definovaný jmenný prostor
Atribut internal je podobný výchozímu ovládání přístupu v aplikaci Java, ačkoliv v Javě není pro tuto úroveň
přístupu žádný explicitní název a lze jej dosáhnou pouze prostřednictvím vynechání žádného jiného modifikátoru
přístupu. Atribut internal je dostupný v jazyce ActionScript 3.0 a umožňuje vám výslovně zvýraznit váš záměr
zviditelnění vlastnosti pouze pro volající v rámci vlastního balíku.
Atribut static
Atribut static, který lze použít s vlastnostmi deklarovanými pomocí klíčových slov var, const nebo function, vám
umožňuje přiřadit vlastnost ke třídě, spíše než k instancím dané třídy. Kód mimo danou třídu musí vyvolat statické
vlastnosti pomocí názvu třídy namísto názvu instance.
Statické vlastnosti nejsou zděděny podtřídami, ale dané vlastnosti jsou součástí řetězce rozsahu podtřídy. To znamená,
že v rámci těla podtřídy lze statickou proměnnou nebo metodu použít bez odkazu na třídu, ve které byla definována.
Více informací naleznete v části „Statické vlastnosti nezděděné“ na stránce 112.
Atributy jmenného prostoru definované uživatelem
Jako alternativu k předdefinovaným atributům ovládání přístupu můžete vytvořit vlastní jmenný prostor, který bude
použit jako atribut. Na každou definici může být použit pouze jeden atribut jmenného prostoru a takový atribut
nemůže být použit v kombinaci s jakýmikoliv atributy ovládání přístupu (public, private, protected, internal).
Více informací o používání jmenných prostorů naleznete v části „Jmenné prostory“ na stránce 42.
Proměnné
Proměnné mohou být deklarovány buď pomocí klíčového slova var nebo const. U proměnných deklarovaných
pomocí klíčového slova var lze jejich hodnoty několikrát změnit, a to kdykoliv při provádění skriptu. Proměnné
deklarované pomocí klíčového slova const jsou vyvolané konstanty a hodnoty k nim můžete přiřadit pouze jednou.
Pokus o přiřazení nové hodnoty ke konkretizované konstantě vyvolá chybu. Další informace naleznete v části
„Konstanty“ na stránce 67.
Statické proměnné
Statické proměnné jsou deklarovány pomocí kombinace klíčového slova static a buďto příkazem var nebo const.
Statické proměnné, které jsou připojeny ke třídě spíše než k instanci třídy, jsou používány pro ukládání a sdílení
informací používaných na celou třídu objektů. Statická proměnná je například vhodná, jestliže si přejete zachovat čítač
toho, kolikrát je třída konkretizovaná, nebo jestliže si přejete uchovat maximální počet instancí tříd, které jsou
povoleny.
Následující příklad vytváří proměnnou totalCount, která bude sledovat počet konkretizací třídy a konstantu
MAX_NUM pro uchování maximálního počtu konkretizací. Proměnné totalCount a MAX_NUM jsou statické, protože
obsahují hodnoty, které se vztahují ke třídě jako celku, spíše než k určité instanci.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 96
Objektově orientované programování v jazyce ActionScript
class StaticVars
{
public static var totalCount:int = 0;
public static const MAX_NUM:uint = 16;
}
Kód, který je externí ke třídě StaticVars a jakékoliv z jejích podtříd, může odkazovat vlastnosti totalCount a MAX_NUM
pouze prostřednictvím samotné třídy. Správný je například následující kód:
trace(StaticVars.totalCount); // output: 0
trace(StaticVars.MAX_NUM); // output: 16
Ke statickým proměnným nemáte přístup prostřednictvím instance třídy, takže následující kód vrátí chyby:
var myStaticVars:StaticVars = new StaticVars();
trace(myStaticVars.totalCount); // error
trace(myStaticVars.MAX_NUM); // error
Proměnné, které jsou deklarovány pomocí klíčového slova static i const, musí být iniciovány v čase deklarace
konstanty, jako to třída StaticVars provádí pro MAX_NUM. K MAX_NUM uvnitř konstruktoru nebo metody instance
nemůžete přiřadit hodnotu. Následující kód vygeneruje chybu, protože se nejedná o platný způsob inicializace statické
konstanty:
// !! Error to initialize static constant this way
class StaticVars2
{
public static const UNIQUESORT:uint;
function initializeStatic():void
{
UNIQUESORT = 16;
}
}
Proměnné instance:
Proměnné instance zahrnují vlastnosti deklarované pomocí klíčových slov var a const, ale bez klíčového slova
static. Proměnné instance připojené k instancím třídy spíše než k celé třídě jsou užitečné pro uchovávání hodnot,
které jsou specifické pro instanci. Například třída Array má vlastnost instance pojmenovanou length uchovávající
počet prvků pole, které vlastní určitá instance třídy Array.
Proměnné instance, ať už deklarovány jako var nebo const, nemohou být potlačeny v podtřídě. Funkce podobné
potlačení proměnných můžete nicméně dosáhnout potlačením metod mechanismů získání a nastavení. Další
informace, viz „Získání a nastavení metod mechanismů přístupu“ na stránce 99.
Metody
Metody jsou funkce, které jsou součástí definice třídy. Po vytvoření instance třídy je k dané instanci připojena metoda.
Narozdíl od funkce deklarované mimo třídu nelze metodu použít mimo instance, ke které byla připojena.
Metody jsou definovány pomocí klíčového slova function. Stejně jako u libovolné vlastnosti třídy můžete použít
jakýkoliv z atributů vlastnosti třídy na metody, včetně osobního, chráněného, veřejného, interního, statického nebo
vlastního jmenného prostoru. Použít můžete například následující příkaz funkce:
public function sampleFunction():String {}
Nebo můžete použít proměnnou, ke které připojíte výraz funkce, a to následovně:
public var sampleFunction:Function = function () {}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 97
Objektově orientované programování v jazyce ActionScript
Ve většině případů si z následujících důvodů budete přát použít příkaz funkce namísto výrazu funkce:
• Příkazy funkce jsou stručnější a snadněji se čtou.
• Příkazy funkce vám umožňují použít klíčová slova override a final. Další informace naleznete v části
„Potlačování metod“ na stránce 110.
• Příkazy funkce vytvářejí pevnější vazby mezi identifikátorem - tj. názvem funkce - a kódem uvnitř těla metody.
Protože hodnota proměnné může být změněna pomocí příkazu přiřazení, může být spojení mezi proměnnou a
výrazem její funkce kdykoliv přerušeno. Ačkoliv se této problematice můžete vyhnout deklarováním proměnné
pomocí const namísto var, tuto techniku nepovažujeme za nejlepší postup, protože kód je poté těžké přečíst a
zabraní se použití klíčových slov override a final.
Jedním případem, kdy musíte použít výraz funkce je to, jestliže si přejete připojit funkci k objektu prototypu. Více
informací naleznete v části „Objekt prototypu“ na stránce 118.
Metody konstruktoru
Metody konstruktoru, někdy jednoduše nazývané konstruktory, jsou funkce, které sdílejí stejný název jako třídy, ve
kterých jsou definovány. Každý kód, který zahrnete do metody konstruktoru je proveden, kdykoliv je instance dané
třídy vytvořena pomocí klíčového slova new. Následující kód například definuje jedinou třídu nazvanou Example,
která obsahuje jedinou vlastnost pojmenovanou status. Počáteční hodnota proměnné status je množina uvnitř
funkce konstruktoru.
class Example
{
public var status:String;
public function Example()
{
status = "initialized";
}
}
var myExample:Example = new Example();
trace(myExample.status); // output: initialized
Metody konstruktoru mohou být pouze veřejné, ale použití atributu public je volitelné. Na konstruktoru nemůžete
použít žádný z jiných specifikátorů přístupu, včetně private, protected nebointernal. S metodou konstruktoru
také nemůžete použít uživatelem definovaný jmenný prostor.
Konstruktor může provést explicitní volání ke konstruktoru své přímé nadřazené třídy pomocí příkazu super().
Jestliže konstruktor nadřazené třídy není explicitně vyvolán, kompilátor automaticky vloží volání před první příkaz do
těla konstruktoru. Metody nadřazené třídy můžete také vyvolat pomocí předpony super jako odkazu na nadřazenou
třídu. Jestliže se rozhodnete použít super() i super v těle stejného konstruktoru, volejte nejprve super(). V opačném
případě se odkaz super nebude chovat dle očekávání. Konstruktor super() by měl být také vyvolán před příkazem
throw nebo return.
Následující příklad demonstruje, co se stane, jestli se pokusíte použít odkaz super před vyvoláním konstruktoru
super(). Nová třída ExampleEx rozšiřuje třídu Example. Konstruktor ExampleEx se pokusí o přístup k proměnné
stavu definované ve své nadřazené třídě, ale tento pokus provede před vyvoláním super(). Příkaz trace() uvnitř
konstruktoru ExampleEx vytvoří hodnotu null, protože proměnná status není dostupná, dokud není konstruktor
super() proveden.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 98
Objektově orientované programování v jazyce ActionScript
class ExampleEx extends Example
{
public function ExampleEx()
{
trace(super.status);
super();
}
}
var mySample:ExampleEx = new ExampleEx(); // output: null
Ačkoliv je uvnitř konstruktoru povoleno použít příkaz return, není povoleno vrátit hodnotu. Jinými slovy, příkazy
return nesmí mít přiřazené výrazy nebo hodnoty. Následně pak metodám konstruktoru není povoleno vracet
hodnoty, což znamená, že nelze specifikovat žádný typ návratu.
Jestliže nedefinujete metodu konstruktoru ve své třídě, kompilátor automaticky vytvoří prázdný konstruktor. Jestliže
vaše třída rozšiřuje jinou třídu, kompilátor zahrne volání super() do konstruktoru, kterého vytvoří.
Statické metody
Statické metody, označované také metody třídy , jsou metody deklarované pomocí klíčového slova static. Statické
metody, které jsou připojeny ke třídě spíše než k instanci třídy, jsou užitečné pro funkci zapouzdření, která ovlivňuje
něco jiného než stav jednotlivé instance. Protože jsou statické metody přiřazeny ke třídě jako celek, jsou přístupné
pouze prostřednictvím třídy, ale nikoliv prostřednictvím instance třídy.
Statické metody jsou užitečné pro funkci zapouzdření, která neovlivňuje pouze stav instancí třídy. Jinými slovy,
metoda by měla být statická, jestliže poskytuje funkčnost, která přímo neovlivňuje hodnotu instance třídy. Například
třída Date má statickou metodu pojmenovanou parse(), která přebírá řetězec a převádí jej na číslo. Metoda je
statická, protože neovlivňuje jednotlivé instance třídy. Místo toho metoda parse() převezme řetězec, který
představuje hodnotu dat, analyzuje jej a vrátí několik formátů kompatibilních s interní reprezentací objektu Date. Tato
metoda není metoda instance, protože použití dané metody pro instanci třídy Date nedává smysl.
Porovnejte statickou metodu parse() s jednou z metod instance třídy Date, například s metodou getMonth().
Metoda getMonth() je metoda instance, protože operuje přímo na hodnotě instance, a to dosazením určité
komponenty (měsíce) instance Date.
Protože statické metody nejsou svázány s jednotlivými instancemi, nemůžete použít klíčová slova this nebo super v
rámci těla statické metody. Reference this i reference super mají význam pouze v rámci daného kontextu metody
instance.
V kontrastu k některým jiným programovacím jazykům založeným na třídě nejsou statické metody v jazyce
ActionScript 3.0 zděděné. Více informací naleznete v části „Statické vlastnosti nezděděné“ na stránce 112.
Metody instance
Metody instance jsou metody, které jsou prohlášeny bez klíčového slova static. Metody instance, které jsou
připojeny k instancím třídy namísto třídy jako celku, jsou užitečné pro implementaci funkčnosti, která ovlivňuje
jednotlivé instance třídy. Například třídy Array obsahuje metodu instance pojmenovanou sort(), která operuje
přímo na instancích Array.
V rámci těla metody instance jsou jak statické tak proměnné instance v rozsahu, což znamená, že proměnné
definované ve stejné třídě mohou být odkazovány pomocí jednoho identifikátoru. Například následující třída
CustomArray rozšiřuje třídu Array. Třída CustomArray definuje statickou proměnnou pojmenovanou
arrayCountTotal pro sledování celkového počtu instancí tříd, instanci pojmenovanou arrayNumber, která sleduje
pořadí, ve kterém jsou instance vytvářeny a metodu instance pojmenovanou getPosition(), která vrátí hodnoty
těchto proměnných.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 99
Objektově orientované programování v jazyce ActionScript
public class CustomArray extends Array
{
public static var arrayCountTotal:int = 0;
public var arrayNumber:int;
public function CustomArray()
{
arrayNumber = ++arrayCountTotal;
}
public function getArrayPosition():String
{
return ("Array " + arrayNumber + " of " + arrayCountTotal);
}
}
Ačkoliv kód mimo třídu musí odkazovat na statickou proměnnou arrayCountTotal pomocí objektu třídy
používajícího kód CustomArray.arrayCountTotal, kód, který je umístěn uvnitř těla metody getPosition()může
přímo odkázat k proměnné arrayCountTotal. Toto je pravda dokonce pro statické proměnné v nadřazených třídách.
Ačkoliv statické vlastnosti nejsou zděděny v jazyce ActionScript 3.0, statické vlastnosti v nadřazené třídě jsou v
rozsahu. Například třída Array má několik málo statických proměnných. Jednou z nich je konstanta pojmenovaná
DESCENDING. Kód v nadřazené třídě může na statickou konstantu DESCENDING odkazovat pomocí jednoduchého
identifikátoru:
public class CustomArray extends Array
{
public function testStatic():void
{
trace(DESCENDING); // output: 2
}
}
Hodnota reference this uvnitř těla metody instance je odkazem na instanci, ke které je metoda připojena. Následující
kód ukazuje, že odkaz this ukazuje k instanci, která obsahuje danou metodu:
class ThisTest
{
function thisValue():ThisTest
{
return this;
}
}
var myTest:ThisTest = new ThisTest();
trace(myTest.thisValue() == myTest); // output: true
Dědičnost metody instance lze ovládat pomocí klíčových slov override a final. Atribut override můžete použít pro
novou definici zděděné metody a atribut final zabraňuje podtřídám v potlačení metody. Další informace naleznete
v části „Potlačování metod“ na stránce 110.
Získání a nastavení metod mechanismů přístupu
Funkce získání a nastavení mechanismů přístupu se nazývají mechanismy získání a mechanismy nastavení. Umožňují
vám zachovat programovací principy skrývání informací a zapouzdření a pro vámi vytvářené třídy poskytují snadno
použitelné programovací rozhraní. Funkce získání a nastavení vám umožňují zachovat vlastnosti vaší třídy pouze pro
danou třídu, ale umožňují uživatelům vaší třídy přístup k těmto vlastnostem, jako v případě přístupu k proměnné třídy
namísto vyvolání metody třídy.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 100
Objektově orientované programování v jazyce ActionScript
Výhodou tohoto přístupu je to, že vám umožňuje vyhnout se tradičním funkcím přístupových mechanismů s
nepraktickými jmény, například getPropertyName() a setPropertyName(). Další výhodou mechanismů získání a
nastavení je to, že pro každou vlastnost nemusíte mít dvě veřejné funkce, které umožňují čtení a zápis.
Následující příklad třídy pojmenovaný GetSet zahrnuje funkce získání a nastavení mechanismů přístupu
pojmenované publicAccess(), které poskytují přístup k soukromé proměnné pojmenované privateProperty:
class GetSet
{
private var privateProperty:String;
public function get publicAccess():String
{
return privateProperty;
}
public function set publicAccess(setValue:String):void
{
privateProperty = setValue;
}
}
Jestliže se pokusíte o přímý přístup k vlastnosti privateProperty, dojde k chybě:
var myGetSet:GetSet = new GetSet();
trace(myGetSet.privateProperty); // error occurs
Namísto toho uživatel třídy GetSet použije něco, co se jeví jako vlastnost pojmenovaná publicAccess, ale jedná se o
dvojici funkcí získání a nastavení mechanismu přístupu, které operují na soukromé vlastnosti pojmenované
privateProperty. Následující příkaz konkretizuje třídu GetSet a poté nastaví hodnotu privateProperty pomocí
veřejného mechanismu přístupu s názvem publicAccess:
var myGetSet:GetSet = new GetSet();
trace(myGetSet.publicAccess); // output: null
myGetSet.publicAccess = "hello";
trace(myGetSet.publicAccess); // output: hello
Funkce mechanismů získání a nastavení také umožňují potlačení vlastností, které jsou zděděny z nadřazené třídy. To
není možné při použití běžných proměnných členů tříd. Proměnné členů třídy, které jsou deklarovány pomocí
klíčového slova var nelze v podtřídě potlačit. Vlastnosti vytvořené pomocí funkcí mechanismů získání a nastavení toto
omezení nicméně nemají. Atribut override můžete použít na funkcích mechanismů získání a nastavení, které jsou
zděděny z nadřazené třídy.
Metody vazeb
Metoda vazby, někdy nazvaná metoda ohraničení, je jednoduše metoda vyjmutá ze své instance. Příklady metod vazby
zahrnují metody, které jsou předány jako argumenty funkci nebo navráceny jako hodnoty z funkce. Nově v jazyce
ActionScript 3.0 je metoda vazby podobná metodě ohraničení v tom, že zachovává své lexikální prostředí i v případě,
že je vyjmuta ze své instance. Klíčovým rozdílem mezi metodou vazby a funkcí ohraničení je nicméně to, že reference
this pro metodu vazby zůstává propojena s instancí, která danou metodu implementuje. Jinými slovy reference this
v metodě vazby vždy poukazuje na původní objekt, který danou metodu implementoval. Pro funkci ohraničení je
reference this generická, což znamená, že poukazuje na jakýkoliv objekt, ke kterému je funkce v době svého vyvolání
připojena.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 101
Objektově orientované programování v jazyce ActionScript
Jestliže používáte klíčové slovo this, je důležité, abyste porozuměli metodám vazeb. Vzpomeňte si, že klíčové slovo
this poskytuje odkaz na nadřazený objekt metody. Většina programátorů jazyka ActionScript očekává, že klíčové
slovo this vždy odkazuje na objekt nebo třídu, která obsahuje definici metody. Bez provázání metod by toto nicméně
neplatilo vždy. V předchozích verzích jazyka ActionScript například reference this neodkazovala vždy k instanci,
která danou metodu implementovala. Při vyjmutí metod z instance v jazyce ActionScript 2.0 je reference this nejen
nepropojena s původní instancí, ale ani proměnné členů a metody třídy instance nejsou dostupné. To v jazyce
ActionScript 3.0 nepředstavuje problém, protože metody provázání jsou automaticky vytvořeny při odeslání metody
jako parametru. Metody vazeb zajišťují, že klíčové slovo this vždy odkazuje na objekt nebo třídu, ve které je
definována metoda.
Následující kód definuje třídu pojmenovanou ThisTest, která obsahuje metodu s názvem foo() definující metodu
vazby a metodu pojmenovanou bar(), která metodu vazby vrátí. Kód externí ke třídě vytvoří instanci třídy ThisTest,
vyvolá metodu bar() a uchová vrácenou hodnotu v proměnné pojmenované myFunc.
class ThisTest
{
private var num:Number = 3;
function foo():void // bound method defined
{
trace("foo's this: " + this);
trace("num: " + num);
}
function bar():Function
{
return foo; // bound method returned
}
}
var myTest:ThisTest = new ThisTest();
var myFunc:Function = myTest.bar();
trace(this); // output: [object global]
myFunc();
/* output:
foo's this: [object ThisTest]
output: num: 3 */
Poslední dva řádky kódu ukazují, že reference this v metodě vazby foo() stále ukazuje na instanci třídy ThisTest,
ačkoliv reference this v předcházejícím řádku ukazuje na globální objekt. Navíc metoda vazby uchovaná v proměnné
myFunc má stále přístup k proměnným, které jsou členy třídy ThisTest. Jestliže je stejný kód spuštěn v jazyce
ActionScript 2.0, reference this bude odpovídat a proměnná num bude undefined.
Jedna oblast, kde je přidání metody vazby nejvíce zřejmé, je zpracovávání událostí, protože metoda
addEventListener() vyžaduje, abyste funkci nebo metodu odeslali jako argument. Více informací naleznete v části
Funkce poslouchače definovaná jako metoda třídy v tématu „Posluchače událostí“ na stránce 253.
Výčet s třídami
Výčty jsou vlastní typy dat, které vytváříte za účelem zapouzdření malé množiny hodnot. Jazyk ActionScript 3.0
nepodporuje na rozdíl od jazyka C++ s klíčovým slovem enum nebo jazyka Java s rozhraním výčtu specifické možnosti
výčtu. Výčty můžete nicméně vytvořit pomocí tříd a statických konstant. Například třída PrintJob v jazyce
ActionScript 3.0 používá výčet nazvaný PrintJobOrientation pro uchovávání množiny hodnot zahrnující
"landscape" a "portrait", jak je uvedeno v následujícím kódu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 102
Objektově orientované programování v jazyce ActionScript
public final class PrintJobOrientation
{
public static const LANDSCAPE:String = "landscape";
public static const PORTRAIT:String = "portrait";
}
Dle úmluvy je třída výčtu deklarována s atributem final, protože není třeba danou třídu rozšířit. Třída obsahuje
pouze statické členy, což znamená, že nevytváříte instance dané třídy. Namísto toho přistupujete k hodnotám výčtu
přímo prostřednictvím objektu třídy, jak je ukázáno v následujícím výpise kódu.
var pj:PrintJob = new PrintJob();
if(pj.start())
{
if (pj.orientation == PrintJobOrientation.PORTRAIT)
{
...
}
...
}
Všechny třídy výčtu v jazyce ActionScript 3.0 obsahují pouze proměnné typu Řetězec, int nebo uint. Výhodou použití
výčtu namísto řetězce literálu nebo číselných hodnot je to, že pomocí výčtu naleznete snadněji typografické chyby.
Jestliže špatně zadáte název výčtu, kompilátor jazyka ActionScript vygeneruje chybu. Jestliže používáte hodnoty
literálu, kompilátor nezjistí chybu, jestliže slovo špatně napíšete nebo použijete špatné číslo. V předchozím příkladu
kompilátor vygeneruje chybu, jestliže je název konstanty výčtu nesprávný:
if (pj.orientation == PrintJobOrientation.PORTRAI) // compiler error
Nicméně kompilátor nevygeneruje chybu, jestliže špatně napíšete hodnotu řetězce literálu:
if (pj.orientation == "portrai") // no compiler error
Druhá technika pro vytvoření výčtů také zahrnuje vytvoření samostatné třídy se statickými vlastnostmi pro výčet. Tato
technika se nicméně liší v tom, že každá ze statických vlastností obsahuje instanci dané třídy, namísto řetězce nebo
celočíselné hodnoty. Například následující kód vytvoří třídu výčtu pro dny v týdnu:
public final class Day
{
public static const
public static const
public static const
public static const
public static const
public static const
public static const
}
MONDAY:Day = new Day();
TUESDAY:Day = new Day();
WEDNESDAY:Day = new Day();
THURSDAY:Day = new Day();
FRIDAY:Day = new Day();
SATURDAY:Day = new Day();
SUNDAY:Day = new Day();
Tato technika není používána jazykem ActionScript 3.0, ale je používána mnoha vývojáři, kteří upřednostňují
vylepšený typ kontroly, který tato technika nabízí. Například metoda, která vrátí hodnotu výčtu, může omezit
vrácenou hodnotu na datový typ výčtu. Následující kód ukazuje nejen funkci, která vrátí den v týdnu, ale také volání
funkce, které používá typ výčtu jako typ anotace:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 103
Objektově orientované programování v jazyce ActionScript
function getDay():Day
{
var date:Date = new Date();
var retDay:Day;
switch (date.day)
{
case 0:
retDay = Day.MONDAY;
break;
case 1:
retDay = Day.TUESDAY;
break;
case 2:
retDay = Day.WEDNESDAY;
break;
case 3:
retDay = Day.THURSDAY;
break;
case 4:
retDay = Day.FRIDAY;
break;
case 5:
retDay = Day.SATURDAY;
break;
case 6:
retDay = Day.SUNDAY;
break;
}
return retDay;
}
var dayOfWeek:Day = getDay();
Třídu Day můžete také vylepšit tak, aby propojila celek s každým dnem v týdnu a poskytla metodu toString(), která
vrátí reprezentaci řetězce daného dne. Můžete si přát povýšit třídu Day na cvičení.
Třídy vloženého datového zdroje
Jazyk ActionScript 3.0 používá speciální třídy, nazvané třídy vloženého datového zdroje, pro reprezentaci vložených
datových zdrojů. vložený datový zdroj je zdroj, jako například zvuk, obraz, nebo typ písma, který je zahrnut do souboru
SWF v čase kompilace. Vkládání datového zdroje namísto jeho dynamického načtení zajišťuje, že bude dostupný v čase
zpracování, ale na druhou stranu také zvýší velikost souboru SWF.
Použití tříd vloženého datového zdroje v přehrávači Flash
Pro vložení datového zdroje nejprve umístěte zdroj do knihovny souboru FLA. Poté pomocí vlastnosti propojení
datového zdroje poskytněte název pro třídu vloženého datového zdroje. Jestliže nemůže být třída dle daného názvu
nalezena v cestě třídy, je pro vás automaticky vygenerována. Poté můžete vytvořit instanci třídy vloženého datového
zdroje a použít jakékoliv vlastnosti a metody definované nebo zděděné danou třídou. Například následující kód lze
použít pro přehrání vloženého zvuku, který je propojen s třídou vloženého datového zdroje s názvem PianoMusic:
var piano:PianoMusic = new PianoMusic();
var sndChannel:SoundChannel = piano.play();
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 104
Objektově orientované programování v jazyce ActionScript
Rozhraní
Rozhraní je skupinou deklarací metody, které umožňují nesouvisejícím objektům navzájem komunikovat. Například
jazyk ActionScript 3.0 definuje rozhraní IEventDispatcher, které obsahuje deklarace metody, kterou třída používá pro
zpracování objektů události. Rozhraní IEventDispatcher zavádí standardní způsob pro vzájemné předání objektů
událostí. Následující kód ukazuje definici rozhraní IEventDispatcher interface:
public interface IEventDispatcher
{
function addEventListener(type:String, listener:Function,
useCapture:Boolean=false, priority:int=0,
useWeakReference:Boolean = false):void;
function removeEventListener(type:String, listener:Function,
useCapture:Boolean=false):void;
function dispatchEvent(event:Event):Boolean;
function hasEventListener(type:String):Boolean;
function willTrigger(type:String):Boolean;
}
Rozhraní jsou založena na rozdílu mezi rozhraním metody a její implementací. Rozhraní metody obsahuje veškeré
nezbytné informace pro vyvolání dané metody, včetně názvu metody, všech její parametrů a jejího typu návratu.
Implementace metody nezahrnuje pouze informace o rozhraní, ale také proveditelné příkazy, které provedou chování
metody. Definice rozhraní obsahuje pouze rozhraní metody a jakákoliv třída, která implementuje dané rozhraní, je
odpovědná za definici implementací metody.
V jazyce ActionScript 3.0 implementuje třída EventDispatcher rozhraní IEventDispatcher definováním všech metod
rozhraní IEventDispatcher a přidáním těl metod ke každé z těchto metod. Následující kód je výpisem z definice třídy
EventDispatcher:
public class EventDispatcher implements IEventDispatcher
{
function dispatchEvent(event:Event):Boolean
{
/* implementation statements */
}
...
}
Rozhraní IEventDispatcher slouží jako protokol, který instance EventDispatcher používají pro zpracování objektů
události a jejich předání k jiným objektům, které také mají implementováno rozhraní IEventDispatcher.
Dalším způsobem popsání rozhraní je to, že stejně jako třída definuje datový typ. Podle toho může být rozhraní
použito jako typ anotace i jako třída. Jako datový typ lze rozhraní použít s operátory, jako například is a as, které
vyžadují datový typ. Narozdíl od třídy nemůže být rozhraní konkretizováno. Tento rozdíl donutil mnoho
programátorů přemýšlet o rozhraních jako o abstraktních datových typech a třídách jako o konkrétních datových
typech.
Definice rozhraní
Struktura definice rozhraní je podobná struktuře definice třídy s výjimkou, že rozhraní může obsahovat pouze metody
bez těl. Rozhraní nemůže zahrnovat proměnné nebo konstanty, ale může obsahovat mechanismy získání a nastavení.
Pro definování rozhraní použijte klíčové slovo interface. Například následující rozhraní, IExternalizable, je součástí
balíku ActionScript 3.0. Rozhraní IExternalizable definuje protokol pro serializaci objektu, což znamená jeho
převedení do formátu vhodného k uložení na zařízení nebo pro přesun po síti.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 105
Objektově orientované programování v jazyce ActionScript
public interface IExternalizable
{
function writeExternal(output:IDataOutput):void;
function readExternal(input:IDataInput):void;
}
Upozorňujeme, že dané rozhraní IExternalizable je deklarováno pomocí modifikátoru ovládání přístupu public.
Definice rozhraní lze upravit pouze pomocí specifikátorů ovládání přístupu public a internal. Deklarace metody
uvnitř definice rozhraní nemohou mít žádné specifikátory ovládání přístupu.
Jazyk ActionScript 3.0 se řídí ustanovením, kde názvy rozhraní začínají velkým I, ale jako název rozhraní můžete
použít jakýkoliv povolený identifikátor. Definice rozhraní jsou často umístěny na nevyšší úrovni balíku. Definice
rozhraní nelze umístit dovnitř definice třídy nebo dovnitř jiné definice rozhraní.
Rozhraní mohou rozšířit jedno nebo více jiných rozhraní. Například následující rozhraní IExample rozšiřuje rozhraní
IExternalizable:
public interface IExample extends IExternalizable
{
function extra():void;
}
Jakákoliv třída, která implementuje rozhraní, musí zahrnovat implementace nejen pro metodu extra(), ale také pro
metodywriteExternal() a readExternal() zděděné z rozhraní IExternalizable.
Implementace rozhraní ve třídě
Třída je jediným prvkem jazyka ActionScript 3.0, který může implementovat rozhraní. Pomocí klíčového slova
implements v deklaraci třídy implementujete jedno nebo více rozhraní. Následující příklad definuje dvě rozhraní
IAlpha a IBeta a třídu Alfa, která je obě implementuje.
interface IAlpha
{
function foo(str:String):String;
}
interface IBeta
{
function bar():void;
}
class Alpha implements IAlpha, IBeta
{
public function foo(param:String):String {}
public function bar():void {}
}
Ve třídě, která implementuje rozhraní, musí implementovaná metoda provést následující:
• Použijte identifikátor ovládání přístupu public.
• Použijte stejný název jako má metoda rozhraní.
• Mají stejný počet parametrů s typy dat, které odpovídají datovým typům parametrů metody rozhraní.
• Použijte stejný typ návratu.
public function foo(param:String):String {}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 106
Objektově orientované programování v jazyce ActionScript
Jistou flexibilitu máte nicméně v tom, jak pojmenujete parametry metody, kterou implementujete. Ačkoliv počet
parametrů a datový typ každého parametru v dané implementované metodě musí odpovídat parametru metody
rozhraní, názvy parametrů odpovídat nemusí. Například v předchozím příkladě je parametr metody Alpha.foo()
pojmenovaný param:
Nicméně parametr je pojmenovaný str v metodě rozhraní IAlpha.foo():
function foo(str:String):String;
Určitou flexibilitu máte také s výchozími hodnotami parametru. Definice rozhraní může zahrnovat deklarace funkce
s výchozími hodnotami parametrů. Metoda, která implementuje takovou deklaraci funkce, musí mít výchozí hodnotu
parametru, který je členem stejného datového typu, shodnou s hodnotou určenou v definici rozhraní, ale skutečná
hodnota nemusí odpovídat. Například následující kód definuje rozhraní, které obsahuje metodu s výchozí hodnotou
parametru 3:
interface IGamma
{
function doSomething(param:int = 3):void;
}
Následující definice třídy implementuje rozhraní Igamma, ale používá odlišnou výchozí hodnotu parametru:
class Gamma implements IGamma
{
public function doSomething(param:int = 4):void {}
}
Důvodem pro tuto flexibilitu je to, že pravidla pro implementování rozhraní jsou navržena specificky pro zajištění
kompatibility typu dat a vyžadování identických názvů parametrů a výchozích hodnot parametrů není pro dosažení
daného cíle nezbytné.
Zdědění
Dědičnost je formou opětovného použití kódu, které programátorům umožňuje vyvinout nové třídy, které jsou
založeny na stávajících třídách. Stávající třídy jsou často označovány jako základní třídy nebo nadřazené třídy, zatímco
nové třídy se obvykle nazývají podtřídy. Klíčovou výhodou dědičnosti je to, že vám umožňuje znovu použít kód ze
základní třídy a přesto ponechat stávající kód bez změn. A navíc, dědičnost nevyžaduje žádné změny způsobu, kterým
jiné třídy reagují se základní třídou. Spíše než úpravou stávající třídy, která mohla být řádně testována nebo může již
být používána, můžete pomocí dědičnosti manipulovat s danými třídami jako s integrovaným modulem, který můžete
rozšířit o dodatečné vlastnosti nebo metody. Stejně tak pomocí klíčového slova extends určíte, že třída dědí z jiné
třídy.
Dědičnost vám také umožňuje využít ve svém kódu polymorfismus. Polymorfismus je schopnost použít jediný název
metody pro metodu, která se chová jinak při použití jiných typů dat. Jednoduchým příkladem je základní třída
pojmenovaná Shape s dvěma podtřídami pojmenovanými Circle a Square. Třída Shape definuje metodu
pojmenovanou area(), která vrací prostor tvaru. Jestliže je implementován polymorfismus, můžete metodu area()
vyvolat na objekty typu Circle a Square a provést správné výpočty. Dědičnost aktivuje polymorfismus umožněním
podtřídám zdědit, předefinovat nebo potlačit metody ze základní třídy. V následujícím příkladě je metoda area()
předefinována třídami Circle a Square:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 107
Objektově orientované programování v jazyce ActionScript
class Shape
{
public function area():Number
{
return NaN;
}
}
class Circle extends Shape
{
private var radius:Number = 1;
override public function area():Number
{
return (Math.PI * (radius * radius));
}
}
class Square extends Shape
{
private var side:Number = 1;
override public function area():Number
{
return (side * side);
}
}
var cir:Circle = new Circle();
trace(cir.area()); // output: 3.141592653589793
var sq:Square = new Square();
trace(sq.area()); // output: 1
Protože každá třída definuje typ dat, vytvoří použití dědičnosti zvláštní vztah mezi základní třídou a třídou, která jí
prodlužuje. Podtřída vlastní všechny vlastnosti své základní třídy, což znamená, že instance podtřídy může být vždy
nahrazena za instanci základní třídy. Například jestliže metoda definuje parametr typu Shape, je možné předat
argument typu Circle, protože Circle rozšiřuje Shape, a to následovně:
function draw(shapeToDraw:Shape) {}
var myCircle:Circle = new Circle();
draw(myCircle);
Vlastnosti a dědičnost instancí
Vlastnost instance, ať už definovaná pomocí klíčových slov function, var nebo const, je děděna všemi podtřídami,
pokud daná vlastnost není v základní třídě deklarována s atributem private. Například třída Event v jazyce
ActionScript 3.0 má několik podtříd, které dědí vlastnosti společné pro všechny objekty události.
Pro některé typy událostí třída Event obsahuje všechny vlastnosti nezbytné pro definici události. Tyto typy událostí
nevyžadují vlastnosti instancí mimo těch definovaných ve třídě Event. Příklady takových událostí jsou událost
complete, ke které doje při úspěšném načtení dat a událost connect, ke které dojde při navázání síťového spojení.
Následující příklad je výpisem ze třídy Event, která vykazuje některé z vlastností a metod, které jsou zděděny
podtřídou. Protože jsou vlastnosti zděděné, má k těmto vlastnostem přístup instance jakékoliv podtřídy.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 108
Objektově orientované programování v jazyce ActionScript
public class Event
{
public function get type():String;
public function get bubbles():Boolean;
...
public
public
public
public
...
function
function
function
function
stopPropagation():void {}
stopImmediatePropagation():void {}
preventDefault():void {}
isDefaultPrevented():Boolean {}
}
Jiné typy události vyžadují jedinečné vlastnosti, které nejsou dostupné ve třídě Event. Tyto události jsou definovány
pomocí podtříd třídy Event, takže nové vlastnosti lze přidat k vlastnostem definovaným ve třídě Event. Příkladem
takové podtřídy je třída MouseEvent, která přidává vlastnosti jedinečné k události spojené s pohybem nebo klepnutím
myši, například k události mouseMove a click. Následující příklad je výpisem z třídy MouseEvent, která ukazuje
definici vlastností, které existují na dané podtřídě, ale nikoliv na základní třídě:
public class MouseEvent extends Event
{
public static const CLICK:String= "click";
public static const MOUSE_MOVE:String = "mouseMove";
...
public function get stageX():Number {}
public function get stageY():Number {}
...
}
Specifikátory ovládání přístupu a dědičnost
Jestliže je vlastnost deklarována pomocí klíčového slova public, je vlastnost pro kód viditelná kdekoliv. To znamená,
že klíčové slovo public, narozdíl od klíčových slov private, protected a internalneuplatňuje na dědičnost
vlastnosti žádná omezení.
Jestliže je vlastnost deklarována pomocí klíčového slova private, je viditelná pouze ve třídě, která je definuje, což
znamená, že není děděná žádnou podtřídou. Toto chování je odlišné od předchozích verzí jazyka ActionScript, kde se
klíčové slovo private chovalo více jako klíčové slovo jazyka ActionScript protected.
Klíčové slovo protected udává, že je vlastnost viditelná nejen v rámci třídy, která ji definuje, ale také pro všechny
podtřídy. Narozdíl od klíčového slova protected v programovacím jazyce Java, klíčové slovo protected v jazyce
ActionScript 3.0 nezviditelňuje vlastnost pro všechny jiné třídy ve stejném balíku. V jazyce ActionScript 3.0 mají k
vlastnosti s klíčovým slovem protected přístup pouze podtřídy. Chráněná vlastnost je navíc viditelná pro podtřídy,
ať je podtřída ve stejném balíku jako daná třída, nebo v balíku odlišném.
Chcete-li omezit viditelnost vlastnosti na balík, ve kterém je definovaná, použijte klíčové slovo internal, nebo
nepoužijte žádný specifikátor ovládání přístupu. Specifikátor ovládání přístupu internal je výchozím specifikátorem
ovládání přístupu, který bude použit v případě, že jiný specifikátor určen není. Vlastnost označená jako internal
bude zděděna pouze podtřídou, která je ve stejném balíku.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 109
Objektově orientované programování v jazyce ActionScript
Pomocí následujícího příkladu zjistíte, jak každý ze specifikátorů ovládání přístupu ovlivní dědičnost napříč hranicemi
balíku. Následující kód definuje hlavní třídu aplikace nazvanou AccessControl a dvě další třídy pojmenované Base a
Extender. Třída Base se nachází v balíku pojmenovaném foo a třída Extender, která je podtřídou třídy Base, je
umístěna v balíku pojmenovaném bar. Třída AccessControl importuje pouze třídu Extender a vytvoří instanci
Extender, která se pokusí o přístup k proměnné pojmenované str definované ve třídě Base. Proměnná str je
deklarovaná jako public, takže kód je sestaven a běží tak, jak je ukázáno v následujícím výpise:
// Base.as in a folder named foo
package foo
{
public class Base
{
public var str:String = "hello"; // change public on this line
}
}
// Extender.as in a folder named bar
package bar
{
import foo.Base;
public class Extender extends Base
{
public function getString():String {
return str;
}
}
}
// main application class in file named AccessControl.as
package
{
import flash.display.MovieClip;
import bar.Extender;
public class AccessControl extends MovieClip
{
public function AccessControl()
{
var myExt:Extender = new Extender();
trace(myExt.str);// error if str is not public
trace(myExt.getString()); // error if str is private or internal
}
}
}
Chcete-li vědět, jak jiné specifikátory ovládání přístupu ovlivňují kompilaci a provedení předchozího příkladu, změňte
specifikátor ovládání přístupu proměnné str na private, protected nebo internal, a to po odstranění nebo
okomentování následujícího řádku ze třídy AccessControl:
trace(myExt.str);// error if str is not public
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 110
Objektově orientované programování v jazyce ActionScript
Potlačení proměnných není povoleno
Vlastnosti deklarované s klíčovými slovy var nebo const jsou zděděny, ale nemohou být potlačeny. Potlačit vlastnost
znamená předefinovat danou vlastnost v podtřídě. Jediný typ vlastnosti, který může být potlačen, jsou metody - to
znamená vlastnosti deklarované pomocí klíčového slova function. Ačkoliv nelze potlačit proměnnou instance,
podobné funkce můžete dosáhnout vytvořením metod získání a nastavení pro proměnou instance a potlačením
metod. Další informace naleznete v části „Potlačování metod“ na stránce 110.
Potlačování metod
Potlačení metody znamená nové definování chování zděděné metody. Statické metody nejsou zděděné a nelze je
potlačit. Metody instance jsou nicméně zděděny podtřídami a lze je potlačit pokud jsou splněna dvě kritéria:
• Metoda instance není deklarována pomocí klíčového slova final v základní třídě. Je-li používáno s metodou
instance, určuje klíčové slovo final záměr programátora zabránit podtřídám potlačit danou metodu.
• Metoda instance není deklarována pomocí specifikátoru ovládání private v základní třídě. Jestliže je metoda v
základní třídě označena jako private, není třeba použít klíčové slovo override jestliže definujete úplně stejně
pojmenovanou metodu v podtřídě, protože metoda základní třídy nebude pro podtřídu viditelná.
Chcete-li potlačit metodu instance, která splňuje tato kritéria, definice metody v podtřídě musí použít klíčové slovo
override a musí odpovídat verzi metody nadřazené třídy, a to následovně:
• Metoda potlačení musí mít stejnou úroveň ovládání přístupu, jako metoda základní třídy. Metoda označená jako
interní má stejnou úroveň ovládání přístupu jako metody, které nemají žádný specifikátor ovládání přístupu.
• Metoda potlačení musí mít stejný počet parametrů jako metoda základní třídy.
• Parametry metody potlačení musí mít stejné anotace typu dat, jako mají parametry v metodě základní třídy.
• Metoda potlačení musí mít stejný typ vrácení jako metoda základní třídy.
Názvy parametrů v dané metodě potlačení nicméně nemusí odpovídat názvům parametrů v základní třídě, jestliže
počet parametrů a typ dat každého parametru souhlasí.
Příkaz super
Při potlačování metody si programátoři často přejí přidat k chování metody nadřazené třídy, kterou potlačují, namísto
úplného nahrazení chování. To vyžaduje mechanismus, který umožňuje metodě podtřídy vyvolat vlastní verzi
nadřazené třídy. Příkaz super takový mechanismus poskytuje, protože obsahuje odkaz na další nadřazenou třídu.
Následující příklad definuje třídu pojmenovanou Base, která obsahuje metodu pojmenovanou thanks() a podtřídu
třídy Base pojmenovanou Extender, která potlačí metodu thanks(). Metoda Extender.thanks() používá příkaz
super pro vyvolání Base.thanks().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 111
Objektově orientované programování v jazyce ActionScript
package {
import flash.display.MovieClip;
public class SuperExample extends MovieClip
{
public function SuperExample()
{
var myExt:Extender = new Extender()
trace(myExt.thanks()); // output: Mahalo nui loa
}
}
}
class Base {
public function thanks():String
{
return "Mahalo";
}
}
class Extender extends Base
{
override public function thanks():String
{
return super.thanks() + " nui loa";
}
}
Potlačení mechanismů získání nebo nastavení
Ačkoliv nemůžete potlačit proměnné definované v nadřazené třídě, můžete potlačit mechanismy získání a nastavení.
Například následující kód potlačí mechanismus získání currentLabel, který je definován ve třídě MovieClip v jazyce
ActionScript 3.0:
package
{
import flash.display.MovieClip;
public class OverrideExample extends MovieClip
{
public function OverrideExample()
{
trace(currentLabel)
}
override public function get currentLabel():String
{
var str:String = "Override: ";
str += super.currentLabel;
return str;
}
}
}
Výstup příkazu trace() v konstruktoru třídy OverrideExample je Override: null, který ukazuje, že daný příklad
byl schopen potlačit zděděnou vlastnost currentLabel.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 112
Objektově orientované programování v jazyce ActionScript
Statické vlastnosti nezděděné
Statické vlastnosti nejsou zděděny podtřídami. To znamená, že statistické vlastnosti nejsou přístupné prostřednictvím
instance nadřazené třídy. Statická vlastnost je přístupná pouze prostřednictvím objektu třídy, na které je definovaná.
Například následující kód definuje základní třídu pojmenovanou Base a podtřídu, která rozšiřuje základní třídu,
pojmenovanou Extender. Statická proměnná pojmenovaná test je definována ve třídě Base. Kód, jak je zapsán v
následujícím výpise, není slučitelný s přísným režimem a ve standardním režimu vytvoří chybu za běhu programu.
package {
import flash.display.MovieClip;
public class StaticExample extends MovieClip
{
public function StaticExample()
{
var myExt:Extender = new Extender();
trace(myExt.test);// error
}
}
}
class Base {
public static var test:String = "static";
}
class Extender extends Base { }
Jediný způsob přístupu ke statické proměnné test je prostřednictvím objektu třídy, jak je ukázáno v následujícím
kódu:
Base.test;
Nicméně je povolené definovat vlastnost instance použitím stejného názvu jako statické vlastnosti. Taková vlastnost
instance může být definována ve stejné třídě jako statická vlastnost nebo v podtřídě. Například základní třída v
předcházejícím příkladě by mohla mít vlastnost instance pojmenovanou test. Následující kód je sestaven a proveden,
protože vlastnost instance je zděděna třídou Extender. Kód by byl také sestaven a proveden, pokud by byla definice
testové proměnné instance přesunuta, ale nikoliv zkopírována, do třídy Extender.
package
{
import flash.display.MovieClip;
public class StaticExample extends MovieClip
{
public function StaticExample()
{
var myExt:Extender = new Extender();
trace(myExt.test);// output: instance
}
}
}
class Base
{
public static var test:String = "static";
public var test:String = "instance";
}
class Extender extends Base {}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 113
Objektově orientované programování v jazyce ActionScript
Statistické vlastnosti a řetězec rozsahu
Ačkoliv statické vlastnosti nejsou zděděny, existují v rámci řetězce rozsahu třídy, která definuje tyto vlastnosti a
jakékoliv podtřídy dané třídy. Jako takové jsou statické vlastnosti v rozsahu třídy, ve které jsou definovány, i jakékoliv
podtřídy. To znamená, že statická vlastnost je přímo přístupná v rámci těla třídy, která definuje statickou vlastnost a v
jakékoliv podtřídě dané třídy.
Následující příklad upravuje třídy definované v předchozím příkladě a ukazuje, že statická proměnná test definovaná
v základní třídě je v rozsahu třídy Extender. Jinými slovy třída Extender má přístup k statické proměnné test bez
toho, aby byla proměnná opatřena předponou s názvem třídy, která definuje test.
package
{
import flash.display.MovieClip;
public class StaticExample extends MovieClip
{
public function StaticExample()
{
var myExt:Extender = new Extender();
}
}
}
class Base {
public static var test:String = "static";
}
class Extender extends Base
{
public function Extender()
{
trace(test); // output: static
}
}
Jestliže je definovaná vlastnost instance, která používá stejný název jako statická vlastnost ve stejné třídě nebo
nadřazené třídě, vlastnost instance má v řetězci rozsahu vyšší prioritu. Vlastnost instance stíní statickou vlastnost, což
znamená, že hodnota vlastnosti instance je použita namísto hodnoty statické vlastnosti. Například následující kód
ukazuje, že jestliže třída Extender definuje proměnnou instance pojmenovanou test, příkaz trace() používá
hodnotu proměnné instance namísto hodnoty statické proměnné:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 114
Objektově orientované programování v jazyce ActionScript
package
{
import flash.display.MovieClip;
public class StaticExample extends MovieClip
{
public function StaticExample()
{
var myExt:Extender = new Extender();
}
}
}
class Base
{
public static var test:String = "static";
}
class Extender extends Base
{
public var test:String = "instance";
public function Extender()
{
trace(test); // output: instance
}
}
Pokročilá témata
Tato část začíná stručným přehledem historie jazyka ActionScript a OOP a dále uvádí diskuse ohledně modelu objektu
jazyka ActionScript 3.0 a to, jak umožňuje novému nástroji ActionScript Virtual Machine (AVM2) pracovat výrazně
rychleji, než předchozí verze přehrávače Flash Player, které obsahují starý nástroj ActionScript Virtual Machine
(AVM1).
Historie podpory OOP jazyka ActionScript
Protože jazyk ActionScript 3.0 navazuje na předchozí verze jazyka ActionScript, může být užitečné pochopit, jak se
model objektu jazyka ActionScript vyvinul. Jazyk ActionScript začal jako jednoduchý skriptovací mechanismus pro
dřívější verze nástroje vytváření přehrávače Flash. Následně začali programátoři s jazykem ActionScript vytvářet
komplexnější aplikace. V reakci na potřeby těchto programátorů má každá následující verze nové funkce jazyka, které
umožňují vytváření složitých aplikací.
ActionScript 1.0
Jazyk ActionScript 1.0 je verze jazyka použitá v přehrávači Flash Player 6 a v dřívějších verzích. I v této ranné fázi
vývoje byl model objektu jazyka ActionScript založen na konceptu objektu jako základního typu dat. Objekt jazyka
ActionScript je složený typ dat se skupinou vlastností. Hovoříme-li o modelu objektu, pojem vlastnosti zahrnuje vše,
co je připojeno k objektu. Jedná se například o proměnné, funkce nebo metody.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 115
Objektově orientované programování v jazyce ActionScript
Ačkoliv první generace jazyka ActionScript nepodporuje definici tříd pomocí klíčového slova class, můžete definovat
třídu pomocí speciálního druhu objektu nazvaného objekt prototypu. Namísto použití klíčového slova class pro
vytvoření definice třídy, kterou zkonkretizujete do určitých objektů, jak to děláte v jazycích založených na třídě (Java
a C++), jazyky založené na prototypu (ActionScript 1.0) používají stávající objekt jako model (nebo prototyp) pro jiné
objekty. Zatímco objekty v jazyce založeném na třídě mohou indikovat třídu, která slouží jako její šablona, objekty v
jazyce založeném na prototypu namísto toho ukazují na jiný objekt, svůj prototyp, který slouží jako šablona.
Pro vytvoření třídy v jazyce ActionScript 1.0 vytvoříte pro danou třídu funkci konstruktoru. V jazyce ActionScript jsou
funkce skutečné objekty, nikoliv pouze abstraktní definice. Funkce konstruktoru, kterou vytváříte, slouží jako
prototypický objekt pro instance dané třídy. Následující kód vytvoří třídu pojmenovanou Shape a definuje jednu
vlastnost pojmenovanou visible, která je implicitně nastavena na hodnotu true (pravda):
// base class
function Shape() {}
// Create a property named visible.
Shape.prototype.visible = true;
Tato funkce konstruktoru definuje třídu Shape, kterou můžete konkretizovat pomocí operátoru new, a to následovně:
myShape = new Shape();
Stejně jako slouží objekt funkce konstruktoru Shape() jako prototyp pro instance třídy tvaru, může také sloužit jako
prototyp pro podtřídy tvaru - tj. pro další třídy, které rozšiřují třídu Shape.
Vytvoření třídy, která je podtřídou třídy Shape, je proces zahrnující dva kroky. Nejprve vytvořte třídu tím, že pro
danou třídu definujete funkci konstruktoru:
// child class
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
Poté použijte operátor new za účelem deklarování, která třída Shape je prototypem třídy Circle. Každá třída, kterou
vytvoříte, implicitně používá třídu Object jako prototyp, což znamená, že Circle.prototype aktuálně obsahuje
generický objekt (instance třídy Object). Pro určení, že prototyp kruhu je tvar a nikoliv objekt, použijte následující kód
pro změnu hodnoty Circle.prototype tak, aby obsahovala objekt tvaru namísto generického objektu:
// Make Circle a subclass of Shape.
Circle.prototype = new Shape();
Třídy Shape a Circle jsou nyní navzájem propojeny ve vztahu dědičnosti, který je běžně znám jako řetězec prototypu.
Tento diagram ilustruje vztah v řetězci prototypu:
Object.prototype
Shape.prototype
Circle.prototype
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 116
Objektově orientované programování v jazyce ActionScript
Základní třída na konci každého řetězce prototypu je třída Object. Třída Object obsahuje statickou vlastnost
pojmenovanou Object.prototype, která ukazuje na základní objekt prototypu pro všechny objekty vytvořené v
jazyce ActionScript 1.0. Další objekt v řetězci prototypu našeho příkladu je objekt Shape. Důvod je ten, že vlastnost
Shape.prototype nebyla nikdy explicitně nastavena, takže stále obsahuje generický objekt (instanci třídy Object).
Závěrečný odkaz v tomto řetězci je třída Circle, které je propojena se svým prototypem, tedy třídou Shape (vlastnost
Circle.prototype obsahuje objekt Shape).
Jestliže vytvoříme instanci třídy Circle jako v následujícím příkladě, zdědí daná instance řetězec prototypu třídy Circle:
// Create an instance of the Circle class.
myCircle = new Circle();
Vzpomeňte si, že jsme vytvořili vlastnost pojmenovanou visible jako člen třídy Shape. V našem případě vlastnost
visible neexistuje jako součást objektu myCircle, ale pouze jako člen objektu Shape. Přesto má ale následující řádek
kódu výsledek true (pravda):
trace(myCircle.visible); // output: true
Přehrávač Flash Player může zajistit, že objekt myCircle zdědí vlastnost visible, a to procházením řetězce prototypu
směrem vzhůru. Při provádění tohoto kódu přehrávač Flash Player nejprve prohledá vlastnosti objektu myCircle pro
vlastnost pojmenovanou visible, ale tuto vlastnost nenalezne. Přehrávač Flash Player se dále podívá do objektu
Circle.prototype, ale ani nyní vlastnost pojmenovanou visible nenalezne. Přehrávač Flash Player pokračuje dále
řetězcem a nakonec nalezne vlastnost visible definovanou na objektu Shape.prototype a vyprodukuje hodnotu
dané vlastnosti.
V zájmu jednoduchosti vypouští tato část mnoho podrobností řetězce prototypu a namísto toho je cílem poskytnout
dostatek informací, které vám pomohou pochopit model objektu jazyka ActionScript 3.0.
ActionScript 2.0
Jazyk ActionScript 2.0 zavedl nová klíčová slova, například class, extends, public a private, které vám umožnily
definovat třídy způsobem známým všem, kteří pracují s jazyky založenými na třídě, jako jsou Java a C++. Je důležité
pochopit, že výchozí mechanismus dědičnosti se mezi jazyky ActionScript 1.0 a ActionScript 2.0 nezměnil. Jazyk
ActionScript 2.0 pouze přidal novou syntaxi pro definování tříd. Řetězec prototypu funguje v obou verzích jazyka
stejně.
Nová syntaxe zavedená jazykem ActionScript 2.0, zobrazená v následujícím výpise, vám umožňuje definovat třídy
způsobem, který je pro mnoho programátorů intuitivnější.
// base class
class Shape
{
var visible:Boolean = true;
}
Všimněte si, že jazyk ActionScript 2.0 také zavedl typ anotací, které budou použity pro kontrolu času kompilace. To
vám umožní deklarovat, že by vlastnost visible v předchozím příkladě měla obsahovat pouze booleovskou hodnotu.
Nové klíčové slovo extends také zjednodušuje proces vytváření podtřídy. V následujícím příkladě je proces se dvěma
kroky v jazyce ActionScript 1.0 dokončen jedním krokem, a to pomocí klíčového slova extends:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 117
Objektově orientované programování v jazyce ActionScript
// child class
class Circle extends Shape
{
var id:Number;
var radius:Number;
function Circle(id, radius)
{
this.id = id;
this.radius = radius;
}
}
Konstruktor je nyní deklarován jako část definice třídy a vlastnosti třídy id a radius musí být také explicitně
deklarovány.
Jazyk ActionScript 2.0 také přidal podporu pro definici rozhraní, která vám umožňuje dále předefinovat své programy
orientované na objekt s formálně definovanými protokoly pro komunikaci mezi objekty.
Objekt třídy v jazyce ActionScript 3.0
Běžné paradigma programování orientované na objekt, které je nejčastěji spojené s jazyky Java a C++, používá třídy
pro definici tříd objektů. Programovací jazyky, které přijímají toto paradigma, také často používají třídy pro
konstrukci instancí typu dat, které třída definuje. Jazyk ActionScript používá třídy pro oba tyto způsoby, ale jeho
základ jazyka založeného na prototypu přidává další zajímavé vlastnosti. Jazyk ActionScript vytváří pro každou
definici třídy zvláštní objekt třídy, která umožňuje sdílení chování i stavu. Pro mnoho programátorů jazyka
ActionScript nicméně tento rozdíl nemusí mít žádné praktické implikace pro kód. Jazyk ActionScript 3.0 je navržen
tak, že vytváříte sofistikované aplikace jazyka ActionScript orientované na objekt bez použití, nebo dokonce
pochopení, těchto zvláštních objektů tříd. Pro pokročilé programátory, kteří chtějí využít objektů tříd, se tato část
věnuje danému tématu podrobně.
Následující diagram ukazuje strukturu objektu třídy, který představuje jednoduchou třídu pojmenovanou A
definovanou pomocí příkazu class A {}:
Class.prototype
T
Object.prototype
CA
delegát
typ
C
delegát
prototyp
konstruktor
A
vlastnost
T
A
P
A
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 118
Objektově orientované programování v jazyce ActionScript
Každý obdélník v diagramu představuje objekt. Každý objekt v daném diagramu má charakter dolního indexu A, který
představuje to, že náleží do třídy A. Objekt třídy (CA) obsahuje odkazy na několik jiných důležitých objektů. Objekt
vlastnosti instance (TA) uchovává vlastnosti instance, které jsou definovány v rámci definice třídy. Objekt vlastnosti
třídy (TCA) představuje interní typ třídy a uchovává statické vlastnosti definované danou třídou (znak dolního indexu
C znamená „class” - třída). Objekt prototypu (PA) vždy odkazuje na objekt třídy, ke kterému byl původně připojen
pomocí vlastnosti constructor.
Objekt vlastnosti
Objekt vlastnosti, který je v jazyce ActionScript 3.0 nový, byl implementován s ohledem na výkon. V předcházejících
verzích jazyka ActionScript mohlo být vyhledání názvu, kdy přehrávač Flash Player prochází řetězec prototypu, časově
náročným procesem. V jazyce ActionScript 3.0 je vyhledání názvu daleko účinnější a méně časově náročné, protože
zděděné vlastnosti jsou kopírovány z nadřazených tříd do objektů vlastností podtříd.
Objekt vlastnosti není přímo dostupný kódem programátora, ale jeho přítomnost zaznamenáte díky lepšímu výkonu
a využití paměti. Objekty vlastností poskytují AVM2 detailní informace o rozvržení a obsahu třídy. Díky této znalosti
může AVM2 výrazně zkrátit dobu provedení, protože může často vygenerovat přímé pokyny zařízení pro přístup k
vlastnostem nebo může vyvolat metody přímo bez časově náročného vyhledávání názvu.
Díky objektu vlastností může být otisk paměti objektu výrazně menší než podobný objekt v předchozích verzích jazyka
ActionScript. Jestliže je například třída zapečetěna (tj. třída není deklarovaná jako dynamická), instance třídy
nepotřebuje tabulku rušení pro dynamicky přidané vlastnosti a může přestavovat pouze ukazovátko na objekty
vlastností a některé bloky pro pevné vlastnosti definované ve třídě. Následkem toho by objekt, který vyžaduje 100 bytů
paměti v jazyce ActionScript 2.0, mohl vyžadovat pouze 20 bytů paměti v jazyce ActionScript 3.0.
Poznámka: Objekt vlastnosti je interním detailem implementace a neexistuje žádná záruka, že se nezmění nebo dokonce
v příštích verzích jazyka ActionScript nezmizí.
Objekt prototypu
Každý objekt třídy jazyka ActionScript má vlastnost pojmenovanou prototype, která je odkazem na objekt prototypu
třídy. Objekt prototypu je odkazem kořenů jazyka ActionScript jako jazyka založeného na prototypu. Pro více
informací viz „Historie podpory OOP jazyka ActionScript“ na stránce 114.
Vlastnost prototype je určena pouze ke čtení, což znamená, že nemůže být upravena a odkazovat tak na různé
objekty. To se liší od vlastnosti třídy prototype v předchozích verzích jazyka ActionScript, kdy může být prototyp
znovu přiřazen tak, aby odkazoval na odlišnou třídu. Ačkoliv je vlastnost prototype určena pouze ke čtení, objekt
prototypu, na který odkazuje, není. Jiným slovy, k objektu prototypu lze přidat nové vlastnosti. Vlastnosti přidané k
objektu prototypu jsou sdíleny mezi všemi instancemi dané třídy.
Řetězec prototypu, který byl jediným mechanismem dědičnosti v předchozích verzích jazyka ActionScript, slouží v
jazyce ActionScript 3.0 pouze jako sekundární úloha. Primární mechanismus dědičnosti, dědičnost pevné vlastnosti,
je zpracována interně objektem vlastnosti. Pevná vlastnost je proměnná nebo metoda definovaná jako část definice
třídy. Dědičnost pevné vlastnosti se také nazývá dědičnost třídy, protože se jedná o mechanismus dědičnosti, který je
spojen s klíčovými slovy jako class, extends a override.
Řetězec prototypu poskytuje alternativní mechanismus dědičnosti, který je dynamičtější než dědičnost pevné
vlastnosti. Vlastnosti k objektu prototypu třídy můžete přidat nejen jako součást definice třídy, ale také v čase
zpracování prostřednictvím třídy vlastnosti prototype objektu. Nicméně si všimněte, že jestliže nastavíte kompilátor
na přísný režim, nemusíte mít přístup k vlastnostem přidaným k objektu prototypu, pokud nedeklarujete třídu s
klíčovým slovem dynamic.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 119
Objektově orientované programování v jazyce ActionScript
Dobrým příkladem třídy s několika vlastnostmi připojené k objektu prototypu je třída Objekt. Metody třídy objektu
toString() a valueOf() jsou vlastně funkce přiřazené k vlastnostem objektu prototypu třídy Object. Následující
příklad ukazuje, jak by mohla deklarace těchto metod teoreticky vypadat (skutečná implementace se mírně liší z
důvodů detailů implementace).
public dynamic class Object
{
prototype.toString = function()
{
// statements
};
prototype.valueOf = function()
{
// statements
};
}
Jak již bylo zmíněno dříve, můžete připojit vlastnost k objektu prototypu třídy mimo definici třídy. Například metodu
toString() lze také definovat mimo definici třídy Object, a to následovně:
Object.prototype.toString = function()
{
// statements
};
Narozdíl od dědičnosti pevné vlastnosti dědičnost prototypu nevyžaduje klíčové slovo override, jestliže si přejete
znovu definovat metodu v podtřídě. Například. Jestliže si přejte znovu definovat metodu valueOf() v podtřídě třídy
Object, máte tři možnosti. Zaprvé definujete metodu valueOf() na objektu prototypu dílčí třídy uvnitř definice třídy.
Následující kód vytvoří podtřídu objektu pojmenovanou Foo a znovu definuje metodu valueOf() na objektu
prototypu Foo jako část definice třídy. Protože každá třída dědí ze třídy Object, není třeba použít klíčové slovo
extends.
dynamic class Foo
{
prototype.valueOf = function()
{
return "Instance of Foo";
};
}
Za druhé můžete definovat metodu valueOf() na objektu prototypu Foo mimo definici třídy, dle příkladu v
následujícím kódu:
Foo.prototype.valueOf = function()
{
return "Instance of Foo";
};
Za třetí můžete definovat pevnou vlastnost pojmenovanou valueOf() jako část třídy Foo. Tato technika se liší od
jiných tím, že kombinuje dědičnost pevné vlastnosti s dědičností prototypu. Jakákoliv podtřída Foo, která chce znovu
definovat valueOf(), musí použít klíčové slovo override. Následující kód ukazuje valueOf() definovanou jako
pevnou vlastnost v Foo:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 120
Objektově orientované programování v jazyce ActionScript
class Foo
{
function valueOf():String
{
return "Instance of Foo";
}
}
Jmenný prostor AS3
Existence dvou oddělených mechanismů dědičnosti, dědičnosti pevné vlastnosti a dědičnosti prototypu, vytváří
zajímavou otázku kompatibility s ohledem na vlastnosti a metody tříd jádra. Slučitelnost se specifikací jazyka výkresů
ECMAScript, na kterých je jazyk ActionScript založen vyžaduje použití dědičnosti prototypu, což znamená, že
vlastnosti a metody třídy jádra jsou definovány na objektu prototypu dané třídy. Na druhou stranu slučitelnost s
jazykem ActionScript 3.0 vyžaduje použití dědičnosti pevné vlastnosti, což znamená, že vlastnosti a metody třídy jádra
jsou definovány v definici třídy pomocí klíčových slov const, var a function. Navíc použití pevných vlastností
namísto verzí prototypů může vést k významnému nárůstu výkonu během zpracovávání.
Jazyk ActionScript 3.0 tento problém řeší použitím jak dědičnosti prototypu, tak dědičnosti pevné vlastnosti pro třídy
jádra. Každá třída jádra obsahuje dvě množiny vlastností a metod. Jedna množina je definována na objektu prototypu
pro slučitelnost se specifikací ECMAScript a druhá je definována pomocí pevných vlastností a jmenného prostoru
AS3,0 pro slučitelnost s jazykem ActionScript 3.0.
Jmenný prostor AS3 poskytuje výhodný mechanismus pro volbu mezi těmito dvěma množinami vlastností a metod.
Jestliže nepoužíváte jmenný prostor AS3, instance třídy jádra dědí vlastnosti a metody definované na objektu
prototypu třídy jádra. Jestliže se rozhodnete použít jmenný prostor AS3, instance třídy jádra dědí verze AS3, protože
jsou pevné vlastnosti vždy upřednostněny před vlastnostmi prototypu. Jinými slovy, kdykoliv je dostupná pevná
vlastnost, je vždy použita namísto stejně pojmenované vlastnosti prototypu.
Můžete selektivně použít verzi jmenného prostoru AS3 vlastnosti nebo metody, a to její kvalifikací s jmenným
prostorem AS3. Například následující kód používá verzi AS3 metody Array.pop():
var nums:Array = new Array(1, 2, 3);
nums.AS3::pop();
trace(nums); // output: 1,2
Můžete také použít příkaz use namespace a otevřít tak jmenný prostor AS3 pro všechny definice v rámci bloku kódu.
Například následující kód používá příkaz use namespace pro otevření jmenného prostoru AS3 pro metodu pop() i
pro metodu push():
use namespace AS3;
var nums:Array = new Array(1, 2, 3);
nums.pop();
nums.push(5);
trace(nums) // output: 1,2,5
Jazyk ActionScript 3.0 také poskytuje volby kompilátoru pro každou sadu vlastností, takže jmenný prostor AS3 můžete
použít na celý váš program. Volba kompilátoru -as3 představuje jmenný prostor AS3 a volba -es představuje volbu
dědičnosti prototypu (es znamená ECMAScript). Pro otevření jmenného prostoru AS3 pro celý váš program nastavte
volbu kompilátoru -as3 na hodnotu true (pravda) a volbu -es na hodnotu false (nepravda). Pro použití verzí
prototypu nastavte volby kompilátoru na opačné hodnoty. Výchozí nastavení kompilátoru pro aplikace Adobe Flex
Builder 3 a Adobe Flash CS4 Professional jsou -as3 = true (pravda) a -es = false (nepravda).
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 121
Objektově orientované programování v jazyce ActionScript
Jestliže si přejete rozšířit jakoukoliv z tříd jádra a potlačit nějakou metodu, měli byste chápat, jak může jmenný prostor
AS3 ovlivnit způsob deklarace potlačené metody. Jestliže používáte jmenný prostor AS3, jakékoliv metoda potlačení
metody třídy jádra musí také používat jmenný prostor AS3, společně s atributem override. Jestliže jmenný prostor
AS3 nepoužíváte a přejete si znovu definovat metodu třídy jádra v podtřídě, neměli byste používat jmenný prostor AS3
ani klíčové slovo override.
Příklad: GeometricShapes
Vzorová aplikace GeometricShapes ukazuje, jak lze pomocí jazyka ActionScript 3.0 použít několik konceptů a funkcí
orientovaných na objekt, a to včetně:
• Definování tříd
• Rozšiřování tříd
• Polymorfismus a klíčové slovo override
• Definování, rozšiřování a implementace rozhraní
Zahrnuje také „metodu rodiny”, která vytváří instanci třídy a ukazuje, jak deklarovat hodnotu vrácení jako instanci
rozhraní a použít daný vrácený objekt obecným způsobem.
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace GeometricShapes naleznete ve složce Samples/GeometricShapes. Aplikace sestává z následujících
souborů:
Soubor
Popis
GeometricShapes.mxml
Hlavní soubor aplikace v programu Flash (FLA)
nebo Flex (MXML).
nebo
GeometricShapes.fla
com/example/programmingas3/geometricshapes/IGeometricShape.as
Základní metody definující rozhraní budou
implementovány všemi třídami aplikace
GeometricShapes.
com/example/programmingas3/geometricshapes/IPolygon.as
Metody definující rozhraní budou
implementovány třídami aplikace
GeometricShapes, které mají více stran.
com/example/programmingas3/geometricshapes/RegularPolygon.as
Typ geometrického tvaru, jehož strany mají
stejnou délku a jsou rozloženy symetricky kolem
středu tvaru.
com/example/programmingas3/geometricshapes/Circle.as
Typ geometrického tvaru, který definuje kruh.
com/example/programmingas3/geometricshapes/EquilateralTriangle.as
Podtřída RegularPolygon, která definuje
trojúhelník, jehož strany mají stejné délky.
com/example/programmingas3/geometricshapes/Square.as
Podtřída RegularPolygon definující obdélník,
jehož všechny strany jsou stejně dlouhé.
com/example/programmingas3/geometricshapes/GeometricShapeFactory.as
Třída obsahující metodu rodiny pro vytvoření
tvarů s daným typem tvaru a velikostí.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 122
Objektově orientované programování v jazyce ActionScript
Definice tříd GeometricShapes
Aplikace GeometricShapes umožňuje uživateli specifikovat typ geometrického tvaru a jeho velikost. Tvar poté reaguje
s popisem tvaru, jeho oblasti a vzdálenosti okolo jeho obvodu.
Uživatelské rozhraní aplikace je triviální, včetně několika kontrol pro výběr typu tvaru, nastavení velikosti a zobrazení
popisu. Nejzajímavější část této aplikace je pod povrchem, ve struktuře tříd a samotných rozhraní.
Tato aplikace se zabývá geometrickými tvary, ale nezobrazuje je graficky. Poskytuje malou knihovnu tříd a rozhraní,
která budou opětovně použita v druhém příkladě této kapitoly (viz „Příklad: SpriteArranger“ na stránce 308). Příklad
SpriteArranger zobrazí tvary graficky a uživatel má možnost s nimi manipulovat, a to na základě rámce třídy, který je
k dispozici v aplikaci GeometricShapes.
Třídy a rozhraní, které definují geometrické tvary v tomto příkladě, jsou ukázány v následujícím diagramu pomocí
poznámky v jednotném modelovacím jazyce (UML):
<< interface >>
IGeometricShape
+getArea (): Number
+describe (): Strin
Circle
+diameter:Number
+Circle () : Circle
+getArea () : Number
+describe () : String
+getCircumference () : Number
<< interface >>
IPolygon
+getPerimeter (): Number
+getSumOfAngles (): Number
RegularPolygon
+numSides : int
+sideLength : Number
+RegularPolygon (): RegularPolygon
+getSumOfAngles (): Number
+getPerimeter (): Number
+getArea (): Number
+describe (): String
Square
EquilateralTriangle
+EquilateralTriangle (): EquilateralTriangle
+getArea (): Number
+describe (): String
+Square (): Square
+getArea (): Number
+describe (): String
Třídy příkladu GeometricShapes
Definice běžného chování s rozhraními
Tato aplikace GeometricShapes se zabývá třemi typy tvarů: kruhy, čtverci a rovnostrannými trojúhelníky. Struktura
třídy GeometricShapes začíná s velice jednoduchým rozhraním, IGeometricShape, které uvádí metody běžné pro
všechny tři typy tvarů:
package com.example.programmingas3.geometricshapes
{
public interface IGeometricShape
{
function getArea():Number;
function describe():String;
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 123
Objektově orientované programování v jazyce ActionScript
Rozhraní definuje dvě metody: metodu getArea(), která vypočítává a vrací oblast tvaru a metodu describe(), která
sestavuje textový popis vlastností tvaru.
Chceme také vědět vzdálenost okolo obvodu každého tvaru. Obvod kruhu je vypočten jedinečným způsobem, takže se
chování liší od chování trojúhelníku nebo čtverce. Přesto mezi trojúhelníky, čtverci a jinými mnohoúhelníky existuje
dostatečná podobnost a je tedy dobré definovat novou třídu rozhraní pouze pro ně: IPolygon. Rozhraní IPolygon je,
jak je ukázáno níže, také spíše jednoduché:
package com.example.programmingas3.geometricshapes
{
public interface IPolygon extends IGeometricShape
{
function getPerimeter():Number;
function getSumOfAngles():Number;
}
}
Toto rozhraní definuje dvě metody společné pro všechny mnohoúhelníky: metodu getPerimeter(), která měří
kombinovanou vzdálenost všech stran a metodu getSumOfAngles(), která sčítá všechny vnitřní úhly.
Rozhraní IPolygon rozšiřuje rozhraní IGeometricShape, což znamená, že jakákoliv třída, která implementuje rozhraní
IPolygon, musí deklarovat všechny čtyři metody - dvě z rozhraní IGeometricShape a dvě z rozhraní IPolygon.
Definice tříd tvaru
Jakmile pochopíte metody společné pro každý typ tvaru, můžete definovat samotné třídy tvarů. Co se týče počtu
metod, které potřebujete implementovat, je nejjednodušší třídou třída Circle:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 124
Objektově orientované programování v jazyce ActionScript
package com.example.programmingas3.geometricshapes
{
public class Circle implements IGeometricShape
{
public var diameter:Number;
public function Circle(diam:Number = 100):void
{
this.diameter = diam;
}
public function getArea():Number
{
// The formula is Pi * radius * radius.
var radius:Number = diameter / 2;
return Math.PI * radius * radius;
}
public function getCircumference():Number
{
// The formula is Pi * diameter.
return Math.PI * diameter;
}
public function describe():String
{
var desc:String = "This shape is a Circle.\n";
desc += "Its diameter is " + diameter + " pixels.\n";
desc += "Its area is " + getArea() + ".\n";
desc += "Its circumference is " + getCircumference() + ".\n";
return desc;
}
}
}
Třída Circle implementuje rozhraní IGeometricShape, takže musí poskytnout kód pro metodu getArea() i metodu
describe(). Dále definuje metodu getCircumference(), která je jedinečná pro třídu Circle. Třída Circle také
deklaruje vlastnost diameter, kterou lze najít v jiných třídách mnohoúhelníků.
Druhé dva typy tvarů, čtverce a jednostranné trojúhelníky, mají společné i jiné věci: oba mají stejně dlouhé strany a
existují společné vzorce, které můžete použít pro výpočet obvodu a součtu vnitřních úhlů obou tvarů. Tyto společné
vzorce se defacto použijí na jakékoliv jiné pravidelné mnohoúhelníky, které bude třeba definovat i v budoucnosti.
Třída RegularPolygon bude nadřazenou třídou pro třídu čtverce i třídu EquilateralTriangle. Nadřazená třída vám
umožňuje definovat běžné metody na stejném místě, takže je nemusíte definovat zvlášť v každé podtřídě. Zde je kód
pro třídu RegularPolygon:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 125
Objektově orientované programování v jazyce ActionScript
package com.example.programmingas3.geometricshapes
{
public class RegularPolygon implements IPolygon
{
public var numSides:int;
public var sideLength:Number;
public function RegularPolygon(len:Number = 100, sides:int = 3):void
{
this.sideLength = len;
this.numSides = sides;
}
public function getArea():Number
{
// This method should be overridden in subclasses.
return 0;
}
public function getPerimeter():Number
{
return sideLength * numSides;
}
public function getSumOfAngles():Number
{
if (numSides >= 3)
{
return ((numSides - 2) * 180);
}
else
{
return 0;
}
}
public function describe():String
{
var desc:String = "Each side is " + sideLength + " pixels long.\n";
desc += "Its area is " + getArea() + " pixels square.\n";
desc += "Its perimeter is " + getPerimeter() + " pixels long.\n";
desc += "The sum of all interior angles in this shape is " + getSumOfAngles() + "
degrees.\n";
return desc;
}
}
}
Nejprve třída RegularPolygon deklaruje dvě vlastnosti, které jsou společné pro všechny pravidelné mnohoúhelníky:
délka každé strany (vlastnost sideLength) a počet stran (vlastnost numSides).
Třída RegularPolygon implementuje rozhraní IPolygon a deklaruje všechny čtyři metody rozhraní IPolygon. Tato
třída implementuje dvě z nich - metodu getPerimeter() a metodu getSumOfAngles() - pomocí společných vzorců.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 126
Objektově orientované programování v jazyce ActionScript
Protože se vzorec pro metodu getArea() bude lišit tvar od tvaru, verze metody základní třídy nemůže zahrnovat
společnou logiku, která může být zděděna metodami podtřídy. Místo toho jednoduše vrátí výchozí hodnotu 0
udávající, že daná oblast nebyla vypočtena. Pro správný výpočet oblasti každého tvaru musí podtřídy třídy
RegularPolygon potlačit samotnou metodu getArea().
Následující kód pro třídu EquilateralTriangle ukazuje, jak je metoda getArea() potlačena:
package com.example.programmingas3.geometricshapes
{
public class EquilateralTriangle extends RegularPolygon
{
public function EquilateralTriangle(len:Number = 100):void
{
super(len, 3);
}
public override function getArea():Number
{
// The formula is ((sideLength squared) * (square root of 3)) / 4.
return ( (this.sideLength * this.sideLength) * Math.sqrt(3) ) / 4;
}
public override function describe():String
{
/* starts with the name of the shape, then delegates the rest
of the description work to the RegularPolygon superclass */
var desc:String = "This shape is an equilateral Triangle.\n";
desc += super.describe();
return desc;
}
}
}
Klíčové slovo override udává, že metoda EquilateralTriangle.getArea() záměrně potlačí metodu getArea()
z nadřazené třídy RegularPolygon. Při vyvolání metoda EquilateralTriangle.getArea() vypočte oblast pomocí
vzorce v předcházejícím kódu a kód v metodě RegularPolygon.getArea() nebude nikdy proveden.
Naopak třída EquilateralTriangle nedefinuje svou vlastní verzi metody getPerimeter(). Při vyvolání metody
EquilateralTriangle.getPerimeter() prochází volání řetězcem dědičnosti a provede kód v metodě
getPerimeter() nadřazené třídy RegularPolygon.
Konstruktor EquilateralTriangle() používá příkaz super() pro explicitní vyvolání konstruktoru
RegularPolygon() ze své nadřazené třídy. Pokud by konstruktory měly stejnou množinu parametrů, mohli byste
úplně vypustit konstruktor EquilateralTriangle() a konstruktor RegularPolygon() by byl proveden místo něj.
Nicméně konstruktor RegularPolygon() potřebuje parametr navíc, numSides. Proto konstruktor
EquilateralTriangle() vyvolá super(len, 3), který projde podél vstupního parametru len a hodnotu 3, která
určuje, že daný trojúhelník bude mít 3 strany.
Metoda describe() také používá příkaz super(), ale jiným způsobem - pro vyvolání verze nadřazené třídy
RegularPolygon metody describe(). Metoda EquilateralTriangle.describe() nejprve nastaví proměnnou
řetězce desc pro příkaz ohledně typu tvaru. Poté získá výsledky metody RegularPolygon.describe() vyvoláním
super.describe()a připíše výsledek k řetězci desc.
Třídu Square zde nebudeme podrobně popisovat, ale je podobná třídě EquilateralTriangle a poskytuje konstruktor a
své vlastní implementace metod getArea() a describe().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 127
Objektově orientované programování v jazyce ActionScript
Polymorfismus a metoda rodiny
Množina třídy, která využívá rozhraní a dědičnost, může být použita mnoha zajímavými způsoby. Například všechny
zatím popsané třídy tvaru buď implementují rozhraní IGeometricShape nebo rozšiřují nadřazenou třídu, která
provádí implementaci. Takže pokud definujete proměnou jako instanci IGeometricShape, nemusíte vědět, zda se
vlastně jedná o instanci třídy kruhu nebo čtverce pro to, aby došlo k vyvolání její metody describe().
Následující kód ukazuje způsob funkce:
var myShape:IGeometricShape = new Circle(100);
trace(myShape.describe());
Při vyvolání myShape.describe() dojde k provedení metody Circle.describe(), protože ačkoliv je proměnná
definována jako instance rozhraní IGeometricShape, třída Circle je její základní třídou.
Tento příklad ukazuje princip polymorfismu v akci: přesně to samé volání metody bude mít za následek provedení
různého kódu, a to v závislosti na třídě objektu, jehož metoda je vyvolávána.
Aplikace GeometricShapes použije tento typ polymorfismu založeného na rozhraní pomocí zjednodušené verze
designového vzoru známé jako metoda rodiny. Pojem metoda rodiny se vztahuje k funkci, která vrátí objekt, jehož
základní typ dat nebo obsah se může lišit v závislosti na kontextu.
Zde uvedená třída GeometricShapeFactory definuje metodu rodiny pojmenovanou createShape():
package com.example.programmingas3.geometricshapes
{
public class GeometricShapeFactory
{
public static var currentShape:IGeometricShape;
public static function createShape(shapeName:String,
len:Number):IGeometricShape
{
switch (shapeName)
{
case "Triangle":
return new EquilateralTriangle(len);
case "Square":
return new Square(len);
case "Circle":
return new Circle(len);
}
return null;
}
public static function describeShape(shapeType:String, shapeSize:Number):String
{
GeometricShapeFactory.currentShape =
GeometricShapeFactory.createShape(shapeType, shapeSize);
return GeometricShapeFactory.currentShape.describe();
}
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 128
Objektově orientované programování v jazyce ActionScript
Metoda rodiny createShape() umožňuje konstruktorům podtřídy tvaru definovat podrobnosti instancí, které
vytvářejí, zatímco vracejí nové objekty jako instance IGeometricShape, takže je aplikace může zpracovat obecnějším
způsobem.
Metoda describeShape() v předcházejícím příkladě ukazuje, jak může aplikace použít metodu rodiny pro získání
obecné reference ke specifičtějšímu objektu. Aplikace může získat popis pro nově vytvořený objekt Circle takto:
GeometricShapeFactory.describeShape("Circle", 100);
Metoda describeShape() poté vyvolá metodu rodiny createShape() se stejnými parametry a uchová nový objekt
kruhu ve statické proměnné pojmenované currentShape, která je typem objektu IGeometricShape. Poté je vyvolána
metoda describe() na objektu currentShape a dané volání je automaticky vyřešeno pro provedení metody
Circle.describe(), která bude mít za následek podrobný popis kruhu.
Vylepšení vzorové aplikace
Skutečná váha rozhraní a dědičnosti bude zřejmá, jakmile vylepšíte nebo změníte svou aplikaci.
Řekněme, že k této vzorové aplikaci chcete přidat nový tvar, pětiúhelník. Vytvořili byste novou třídu pětiúhelníku,
která rozšiřuje třídu RegularPolygon a definuje své vlastní verze metod getArea() a describe(). Poté byste přidali
novou volbu pětiúhelníku do vstupního pole v uživatelském rozhraní aplikace. Ale to je vše. Třída Pentagon by
automaticky získala funkce metody getPerimeter() a metody getSumOfAngles() z třídy RegularPolygon
prostřednictvím dědičnosti. Protože dědí ze třídy, která implementuje rozhraní IGeometricShape, může být s instancí
Pentagon zacházeno také jako s instancí IGeometricShape. To znamená, že pro přidání nového typu tvaru
nepotřebujete změnit metodu podpisu žádné z metod ve třídě GeometricShapeFactory (a následně také nemusíte
změnit žádný z kódů, která třída GeometricShapeFactory používá).
Můžete si přát přidat třídu Pentagon k příkladu geometrických tvarů jako cvičení a zjistit tak, jak mohou rozhraní a
dědičnost ulehčit pracovní zatížení přidání nových funkcí do aplikace.
129
Kapitola 6: Práce s daty a časy
Měření času nemusí být všechno, ale v softwarových aplikacích je to většinou klíčový faktor. Jazyk ActionScript 3.0
poskytuje účinné způsoby správy kalendářových dat, časů a časových intervalů. Většinu těchto časových funkcí
poskytují dvě hlavní třídy: třída Date a nová třída Timer v balíčku flash.utils.
Základy data a času
Úvod k práci s daty a časy
Data a časy jsou běžným typem informací používaných v programech ActionScript. Můžete například potřebovat znát
aktuální den v týdnu nebo změřit, kolik času uživatel stráví na konkrétní obrazovce atd. V jazyku ActionScript můžete
použít třídu Date k vyjádření jednoho okamžiku v čase, včetně informací o datu a čase. V instanci Date jsou hodnoty
pro jednotlivé jednotky data a času, včetně roku, měsíce, dne, dne v týdnu, hodin, minut, sekund, milisekund a
časového pásma. Pro pokročilejší použití obsahuje ActionScript také třídu Timer, kterou můžete použít k provádění
akcí s určitým zpožděním nebo v opakovaných intervalech.
Běžné úlohy s datem a časem
V této kapitole jsou popsány následující běžné úlohy pro práci s informacemi o datu a čase.
• Práce s objekty Date
• Získání aktuálního data a času
• Přístup k individuálním jednotkám data a času (dny, roky, hodiny, minuty atd.)
• Provádění aritmetických operací s datem a časem
• Převody mezi časovými pásmy
• Provádění opakovacích akcí
• Provádění akcí po nastaveném časovém intervalu
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Čas UTC: Koordinovaný světový čas – referenční časové pásmo „nulové hodiny“. Všechna ostatní časová pásma
jsou definována jako počet hodin přičítaných nebo odečítaných od času UTC.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Protože
příklady kódů uvedené v této kapitole se týkají především objektů Date, zkoušení příkladů bude zahrnovat prohlížení
hodnot proměnných používaných v příkladech, buď zapsáním proměnných do instance textového pole ve vymezené
ploše nebo použitím funkce trace() k vytištění hodnot do panelu Výstup. Tyto techniky jsou podrobně popsány v
části „Testování příkladů kódu v této kapitole“ na stránce 34.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 130
Práce s daty a časy
Správa kalendářních dat a časů
Všechny funkce pro správu kalendářních dat a časů v jazyku ActionScript 3.0 jsou soustředěny v nejvyšší třídě Date.
Třída Date obsahuje metody a vlastnosti, které umožňují zpracovávat data a časy buď v Koordinovaném světovém času
(UTC) nebo v místním času příslušejícím k danému časovému pásmu. UTC je standardní definice času, který je v
zásadě stejný jako Greenwichský čas (GMT).
Vytváření objektů Date
Třída Date se může pochlubit jednou z nejuniverzálnějších metod konstruktoru ze všech hlavních tříd. Můžete ji
vyvolat čtyřmi různými způsoby.
Za prvé, když nejsou zadány žádné parametry, konstruktor Date() vrátí objekt Date obsahující aktuální datum a čas,
v místním času na základě příslušného časového pásma. Zde je příklad:
var now:Date = new Date();
Za druhé, je-li zadán jeden číselný parametr, konstruktor Date() jej bude brát jako počet milisekund od 1. ledna 1970
a vrátí odpovídající objekt Date. Všimněte si, že předaná hodnota v milisekundách je brána jako počet milisekund od
1. ledna 1970 v UTC. Objekt Date však ukazuje hodnoty ve vašem místním časovém pásmu, pokud nepoužíváte k
jejich vyhledání a zobrazení metody orientované na UTC. Vytvoříte-li nový objekt Date pomocí jednoho parametru
milisekundy, Nezapomeňte vzít v úvahu rozdíl v časovém pásmu mezi vaším místním časem a UTC. Následující
příkazy vytvoří objekt Date nastavený na půlnoc 1. ledna 1970 v UTC:
var millisecondsPerDay:int = 1000 * 60 * 60 * 24;
// gets a Date one day after the start date of 1/1/1970
var startTime:Date = new Date(millisecondsPerDay);
Za třetí, můžete předat více číselných parametrů pro konstruktor Date(). Konstruktor bude brát tyto parametry jako
rok, měsíc, den, hodinu, minutu, sekundu, resp. milisekundu a vrátí odpovídající objekt Date. Předpokládá se, že tyto
vstupní parametry jsou uvedeny v místním času a ne v UTC. Následující příkazy získají objekt Date nastavený na
půlnoc na začátku 1. ledna 2000 v místním času:
var millenium:Date = new Date(2000, 0, 1, 0, 0, 0, 0);
Za čtvrté, můžete předat jeden parametr v podobě řetězce pro konstruktor Date(). Konstruktor se pokusí analyzovat
tento řetězec na složky data nebo času a vrátí odpovídající objekt Date. Použijete-li tento přístup, je dobré, když
uzavřete konstruktor Date() do bloku try..catch pro zachycení případných chyb analýzy. Konstruktor Date()
přijme číslo různých formátů řetězce, jak je uvedeno v Referenční příručce jazyka ActionScript 3.0 a jeho součástí.
Následující příkaz inicializuje nový objekt Date pomocí hodnoty řetězce:
var nextDay:Date = new Date("Mon May 1 2006 11:30:00 AM");
Nemůže-li konstruktor Date() úspěšně analyzovat parametr v podobě řetězce, nevrátí výjimku. Výsledný objekt Date
však bude obsahovat neplatnou hodnotu data.
Získání hodnot v jednotkách času
V rámci objektu Date můžete pomocí vlastností nebo metod třídy Date vyjmout hodnoty pro různé jednotky času.
Každá z následujících vlastností dává hodnotu v jednotkách času v objektu Date:
• Vlastnost fullYear
• Vlastnost month, která je v číselném formátu s 0 pro leden až 11 pro prosinec
• Vlastnost date, která udává kalendářní pořadí dne v měsíci, v rozsahu od 1 do 31
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 131
Práce s daty a časy
• Vlastnost day, která udává den v týdnu v číselném formátu, s 0 pro neděli
• Vlastnost hours v rozsahu od 0 do 23
• Vlastnost minutes
• Vlastnost seconds
• Vlastnost milliseconds
Třída Date ve skutečnosti poskytuje několik způsobů jak získat každou z uvedených hodnot. Hodnotu měsíce
objektu Date můžete například získat čtyřmi různými způsoby:
• Vlastnost month
• Metoda getMonth()
• Vlastnost monthUTC
• Metoda getMonthUTC()
Všechny čtyři způsoby jsou v podstatě rovnocenné ve smyslu efektivity, můžete tedy použít libovolný přístup, jaký
nejlépe vyhovuje vaší aplikaci.
Všechny právě vyjmenované vlastnosti představují komponenty celkové hodnoty data. Například, vlastnost
milliseconds nebude nikdy větší než 999, protože když dosáhne hodnoty 1000, tak se hodnota seconds zvýší o 1 a
vlastnost milliseconds se nastaví znovu na 0.
Chcete-li získat hodnotu objektu Date v milisekundách od 1. ledna 1970 (UTC), můžete použít metodu getTime().
Její protějšek, metoda setTime(), umožňuje změnit hodnotu stávajícího objektu Date při použití milisekund od 1.
ledna 1970 (UTC).
Provádění aritmetických operací s datem a časem
Pomocí třídy Date můžete u data a času provádět sčítání a odčítání. Hodnoty data jsou interně uchovávány v
milisekundách, takže byste měli ostatní hodnoty nejdříve převést na milisekundy, než s nimi budete provádět sčítání
nebo odčítání s objekty Date.
Pokud bude vaše aplikace provádět hodně aritmetických operací s datem a časem, bude pro vás možná užitečné, když
si vytvoříte konstanty, které budou udávat běžné hodnoty jednotek času v milisekundách, jako zde:
public static const millisecondsPerMinute:int = 1000 * 60;
public static const millisecondsPerHour:int = 1000 * 60 * 60;
public static const millisecondsPerDay:int = 1000 * 60 * 60 * 24;
Nyní je jednoduché provádět aritmetické operace s použitím standardních jednotek času. Následující kód nastaví
hodnotu data na jednu hodinu od aktuálního času pomocí metod getTime() a setTime().
var oneHourFromNow:Date = new Date();
oneHourFromNow.setTime(oneHourFromNow.getTime() + millisecondsPerHour);
Jiný způsob jak nastavit hodnotu data je vytvořit nový objekt Date s použitím parametru milliseconds. Například,
následující kód přičte 30 dnů k jednomu datu, aby vypočítal jiné:
// sets the invoice date to today's date
var invoiceDate:Date = new Date();
// adds 30 days to get the due date
var dueDate:Date = new Date(invoiceDate.getTime() + (30 * millisecondsPerDay));
Konstanta millisecondsPerDay je dále vynásobena 30, což dává čas v délce 30 dnů, a výsledek je přičten k hodnotě
invoiceDate a použit k nastavení hodnoty dueDate.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 132
Práce s daty a časy
Převody mezi časovými pásmy
Aritmetické operace s datem a časem přijdou vhod, když chcete převést data z jednoho časového pásma na jiné. K
tomu slouží metoda getTimezoneOffset(), která vrátí hodnotu v minutách, o kterou se bude časové pásmo objektu
Date lišit od UTC. Tato metoda vrátí hodnotu v minutách, protože ne všechna časová pásma jsou nastavena na
přírůstky v celých hodinách – některé mají půlhodinový časový posun od sousedního pásma.
V následujícím příkladu je použit časový posun k převedení data z místního času na UTC. Převod se provede tak, že
se nejprve vypočítá hodnota časového pásma v milisekundách a poté se o danou hodnotu upraví hodnota Date:
// creates a Date in local time
var nextDay:Date = new Date("Mon May 1 2006 11:30:00 AM");
// converts the Date to UTC by adding or subtracting the time zone offset
var offsetMilliseconds:Number = nextDay.getTimezoneOffset() * 60 * 1000;
nextDay.setTime(nextDay.getTime() + offsetMilliseconds);
Kontrola časových intervalů
Když vyvíjíte aplikace pomocí programu Adobe Flash CS4 Professional, máte přístup k časové ose, která poskytuje
stabilní postup vaší aplikací po snímcích. V ryzích projektech ActionScript se však musíte spoléhat na jiné časovací
mechanismy.
Smyčky versus časovače
V některých programovacích jazycích musíte navrhnout své vlastní časovací systémy pomocí smyčkových příkazů
jako for nebo do..while.
Smyčkové příkazy se obvykle provádějí tak rychle, jak to umožňuje místní počítač, což znamená, že aplikace běží na
některých počítačích rychleji a na jiných pomaleji. Potřebuje-li vaše aplikace konzistentní interval časování, musíte ji
napojit na samotný kalendář nebo hodiny. Mnohé aplikace, např. hry, animace nebo ovladače v reálném čase,
potřebují pravidelné, časově řízené časovací mechanismy, které jsou na různých počítačích konzistentní.
Třída Timer jazyka ActionScript 3.0 poskytuje výkonné řešení. Pomocí modelu událostí ActionScript 3.0 třída Timer
odešle událost časovače vždy po uplynutí určeného časového intervalu.
Třída Timer
Upřednostňovaný způsob zpracování funkcí časování v jazyku ActionScript 3.0 je použití třídy Timer
(flash.utils.Timer), kterou lze použít k odesílání událostí po dosažení určitého intervalu.
Chcete-li spustit časovač, vytvořte nejprve instanci třídy Timer, která bude sdělovat, jak často se má generovat událost
timer a kolikrát se to má opakovat, než dojde k zastavení.
Například následující kód vytvoří instanci třídy Timer, která odešle událost každou sekundu a bude v tom pokračovat
60 sekund.
var oneMinuteTimer:Timer = new Timer(1000, 60);
Objekt Timer odešle objekt TimerEvent při každém dosažení zadaného intervalu. Typ události objektu TimerEvent je
timer (definovaný konstantou TimerEvent.TIMER). Objekt TimerEvent obsahuje stejné vlastnosti jako standardní
objekt Event.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 133
Práce s daty a časy
Je-li instance Timer nastavena na pevný počet intervalů, odešle také událost timerComplete (definovanou konstantou
TimerEvent.TIMER_COMPLETE), jakmile dosáhne konečného intervalu.
Zde je malá ukázka aplikace, která ukazuje třídu Timer v činnosti:
package
{
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class ShortTimer extends Sprite
{
public function ShortTimer()
{
// creates a new five-second Timer
var minuteTimer:Timer = new Timer(1000, 5);
// designates listeners for the interval and completion events
minuteTimer.addEventListener(TimerEvent.TIMER, onTick);
minuteTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
// starts the timer ticking
minuteTimer.start();
}
public function onTick(event:TimerEvent):void
{
// displays the tick count so far
// The target of this event is the Timer instance itself.
trace("tick " + event.target.currentCount);
}
public function onTimerComplete(event:TimerEvent):void
{
trace("Time's Up!");
}
}
}
Jakmile je vytvořena třída ShortTimer, vytvoří instanci třídy Timer, která bude tikat jednou za sekundu po dobu pěti
sekund. Dále přidá k časovači dva posluchače událostí: jeden, který poslouchá každé tiknutí, a jeden, který poslouchá
událost timerComplete.
Dále spustí tikání časovače a od toho okamžiku se bude v jednosekundových intervalech provádět metoda onTick().
Metoda onTick() jednoduše zobrazuje aktuální počet tiknutí. Po uplynutí pěti sekund se provede metoda
onTimerComplete(), která oznámí, že čas vypršel.
Když spustíte tuto ukázku, měli byste vidět, jak se ve vaší konzole nebo sledovacím okně objevují následující řádky
rychlostí jeden řádek za sekundu:
tick 1
tick 2
tick 3
tick 4
tick 5
Time's Up!
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 134
Práce s daty a časy
Funkce časování v balíčku flash.utils
Jazyk ActionScript 3.0 obsahuje několik funkcí časování podobných těm, které byly k dispozici ve verzi ActionScript
2.0. Tyto funkce jsou poskytnuty jako funkce na úrovni balíčku v balíčku flash.utils a fungují stejně jako ve verzi
ActionScript 2.0.
Funkce
Popis
clearInterval(id:uint):void
Zruší určené volání setInterval().
clearTimeout(id:uint):void
Zruší určené volání setTimeout().
getTimer():int
Vrátí počet milisekund, které uplynuly od spuštění přehrávače Adobe® Flash®
Player nebo Adobe® AIR™.
setInterval(closure:Function,
delay:Number, ... arguments):uint
Spouští funkci v určeném intervalu (v milisekundách).
setTimeout(closure:Function,
delay:Number, ... arguments):uint
Spouští určenou funkci po určené prodlevě (v milisekundách).
Tyto funkce zůstávají v jazyku ActionScript 3.0 kvůli zpětné kompatibilitě. Společnost Adobe nedoporučuje jejich
používání v nových aplikacích ActionScript 3.0. Obecně je jednodušší a efektivnější používat ve vašich aplikacích třídu
Timer.
Příklad: Jednoduché analogové hodiny
Příklad jednoduchých analogových hodin znázorňuje dvě koncepce data a času probrané v této kapitole:
• Získání aktuálního data a času a vyjímání hodnot pro hodiny, minuty a sekundy
• Použití objektu Timer k nastavení tempa aplikace
Aplikační soubory pro tuto ukázku najdete na adrese
www.adobe.com/go/learn_programmingAS3samples_flash_cz. Soubory aplikace SimpleClock najdete ve složce
Samples/SimpleClock. Aplikace sestává z následujících souborů:
Soubor
Popis
SimpleClockApp.mxml
Hlavní soubor aplikace v programu Flash (FLA) nebo Flex
(MXML).
nebo
SimpleClockApp.fla
com/example/programmingas3/simpleclock/SimpleClock.as
Hlavní soubor aplikace.
com/example/programmingas3/simpleclock/AnalogClockFace.as
Nakreslí kruhový tvar číselníku a hodinové, minutové a
sekundové ručičky podle času.
Definování třídy SimpleClock
Příklad hodin je jednoduchý, ale je dobré si i jednoduché aplikace dobře uspořádat, abyste je mohli v budoucnosti
snadno rozšířit. K tomu účelu používá aplikace SimpleClock třídu SimpleClock pro zpracování úloh spuštění a
sledování času a dále používá další třídu s názvem AnalogClockFace k vlastnímu zobrazování času.
Zde je kód, který definuje a inicializuje třídu SimpleClock (všimněte si, že ve verzi Flash je třída SimpleClock
rozšířením třídy Sprite):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 135
Práce s daty a časy
public class SimpleClock extends UIComponent
{
/**
* The time display component.
*/
private var face:AnalogClockFace;
/**
* The Timer that acts like a heartbeat for the application.
*/
private var ticker:Timer;
Tato třída má dvě důležité vlastnosti:
• Vlastnost face, která je instancí třídy AnalogClockFace
• Vlastnost ticker, která je instancí třídy Timer
Třída SimpleClock používá výchozí konstruktor. Metoda initClock() se stará o práci opravdového rozvržení a
vytváří číselník a spouští instanci tikání třídy Timer.
Vytvoření číselníku hodin
Následující řádky kódu SimpleClock vytvoří hodinový číselník, který se používá k zobrazování času:
/**
* Sets up a SimpleClock instance.
*/
public function initClock(faceSize:Number = 200)
{
// creates the clock face and adds it to the display list
face = new AnalogClockFace(Math.max(20, faceSize));
face.init();
addChild(face);
// draws the initial clock display
face.draw();
Velikost číselníku je možno předat do metody initClock(). Není-li předána žádná hodnota faceSize, použije se
výchozí hodnota 200 obr. bodů.
Dále aplikace inicializuje číselník a poté jej přidá na seznam zobrazení pomocí metody addChild() zděděné z třídy
DisplayObject. Dále vyvolá metodu AnalogClockFace.draw() k jednomu zobrazení číselníku ukazujícího aktuální
čas.
Spuštění časovače
Po vytvoření číselníku hodin metoda initClock() nastaví časovač:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 136
Práce s daty a časy
// creates a Timer that fires an event once per second
ticker = new Timer(1000);
// designates the onTick() method to handle Timer events
ticker.addEventListener(TimerEvent.TIMER, onTick);
// starts the clock ticking
ticker.start();
Nejprve tato metoda inicializuje instanci třídy Timer, která bude odesílat událost každou sekundu (každých 1000
milisekund). Protože nebyl konstruktoru Timer() předán žádný parametr repeatCount, časovač bude spuštěný do
nekonečna.
Metoda SimpleClock.onTick() se provede každou sekundu při obdržení události timer.
public function onTick(event:TimerEvent):void
{
// updates the clock display
face.draw();
}
Metoda AnalogClockFace.draw() jednoduše nakreslí číselník a ručičky hodin.
Zobrazení aktuálního času
Většina kódu v třídě AnalogClockFace zajišťuje nastavení elementů zobrazení číselníku hodin. Jakmile je třída
AnalogClockFace inicializována, nakreslí kruhový obrys, umístí do něj číselné popisy k jednotlivým značkám hodin a
poté vytvoří tři objekty Shape, po jednom pro hodinovou ručičku, minutovou ručičku a sekundovou ručičku.
Jakmile je aplikace SimpleClock spuštěná, vyvolá metodu AnalogClockFace.draw() každou sekundu, viz zde:
/**
* Called by the parent container when the display is being drawn.
*/
public override function draw():void
{
// stores the current date and time in an instance variable
currentTime = new Date();
showTime(currentTime);
}
Tato metoda ukládá aktuální čas do proměnné, takže čas se nemůže během překreslování ručiček hodin změnit. Dále
vyvolá metodu showTime() k zobrazení ručiček, jak můžete vidět zde:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 137
Práce s daty a časy
/**
* Displays the given Date/Time in that good old analog clock style.
*/
public function showTime(time:Date):void
{
// gets the time values
var seconds:uint = time.getSeconds();
var minutes:uint = time.getMinutes();
var hours:uint = time.getHours();
// multiplies by 6 to get degrees
this.secondHand.rotation = 180 + (seconds * 6);
this.minuteHand.rotation = 180 + (minutes * 6);
// Multiply by 30 to get basic degrees, then
// add up to 29.5 degrees (59 * 0.5)
// to account for the minutes.
this.hourHand.rotation = 180 + (hours * 30) + (minutes * 0.5);
}
Tato metoda nejprve vyjme hodnoty pro hodiny, minuty a sekundy aktuálního času. Poté použije tyto hodnoty k
výpočtu úhlu jednotlivých ručiček. Protože sekundová ručička se otočí kolem dokola každých 60 sekund, posune se
každou sekundu o 6 stupňů (360/60). Minutová ručička se posune o stejný úhel každou minutu.
Hodinová ručička se aktualizuje každou minutu, aby bylo během ubíhajících minut vidět, že se pohybuje. Posune se
každou hodinu o 30 stupňů (360/12), ale také se posune každou minutu o půl stupně (30 stupňů děleno 60 minutami).
138
Kapitola 7: Práce s řetězci
Třída String obsahuje metody, které umožňují pracovat s textovými řetězci. Řetězce jsou důležité pro práci s mnoha
objekty. Metody popsané v této kapitole jsou užitečné pro práci s řetězci používanými v objektech jako TextField,
StaticText, XML, ContextMenu a FileReference.
Řetězce jsou posloupnosti znaků. Jazyk ActionScript 3.0 podporuje znaky ASCII a Unicode.
Základy řetězců
Úvod do práce s řetězci
V programátorském slangu je řetězec textovou hodnotou - posloupností písmen, čísel a dalších znaků spojených do
jedné hodnoty. Například tato řádka kódu vytváří proměnnou s datovým typem String a přiřazuje této proměnné
hodnotu literálového řetězce:
var albumName:String = "Three for the money";
Jak ukazuje tento příklad, v jazyce ActionScript můžete označit hodnotu řetězce obklopením textu dvojitými nebo
jednoduchými uvozovkami. Zde jsou další příklad řetězců:
"Hello"
"555-7649"
"http://www.adobe.com/"
Při každé manipulaci s textem v jazyce ActionScript pracujete s hodnotou řetězce. Řetězec jazyka ActionScript je
datovým typem, který můžete použít pro práci s textovými hodnotami. Instance String jsou často používány pro
vlastnosti, parametry metod atd. v mnoha jiných třídách jazyka ActionScript.
Běžné úlohy pro práci s řetězci
Následující úlohy jsou běžné úlohy související s řetězci, které jsou probírány v této kapitole:
• Vytváření objektů String
• Práce se zvláštními znaky, například CR (návrat vozíku), Tab a znaky, které nejsou na klávesnici
• Měření délky řetězce
• Izolování jednotlivých znaků v řetězci
• Spojování řetězců
• Porovnávání řetězců
• Vyhledání, extrahování a nahrazení částí řetězce
• Převedení řetězce na velká nebo malá písmena
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• ASCII: systém představující textové znaky a symboly v počítačových programech. Systém ASCII podporuje
26znakovou anglickou abecedu, plus omezenou sadu dodatečných znaků.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 139
Práce s řetězci
• Znak: nejmenší jednotka textových dat (jedno písmeno nebo symbol).
• Zřetězení: spojení několika řetězcových hodnot přidáním jedné na konec druhé a vytvoření nové hodnoty řetězce.
• Prázdný řetězec: řetězec neobsahující žádný text, prázdné znaky nebo jiné znaky, zapsaný jako "". Hodnota
prázdného řetězce se odlišuje od proměnné String s hodnotou null - proměnná String s hodnotou null je proměnná,
která nemá přiřazenou instanci String, zatímco prázdný řetězec má instanci s hodnotou neobsahující žádný znak.
• Řetězec: textová hodnota (posloupnost znaků).
• Řetězcová konstanta (nebo „literálový řetězec“): hodnota řetězce zapsaná explicitně v kódu jako textová hodnota v
dvojitých nebo jednoduchých uvozovkách.
• Podřetězec: řetězec, který je součástí jiného řetězce.
• Unicode: standardní systém představující textové znaky a symboly v počítačových programech. Systém Unicode
umožňuje použití jakéhokoliv znaku v kterémkoliv systému zápisu.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Protože
příklady kódu v této kapitole se primárně zabývají zpracováním textu, testování příklad bude zahrnovat sledování
hodnot proměnných použitých na příkladech, buď zapisováním hodnot do instancí textových polí na plochu nebo
používání funkce trace() k tisku hodnot do výstupního panelu. Tyto techniky jsou podrobně popsány v části
„Testování příkladů kódu v této kapitole“ na stránce 34.
Vytváření řetězců
Třída String se používá pro vyjádření dat řetězce (textového) v jazyce ActionScript 3.0. Jazyk ActionScript podporuje
v řetězcích znaky ASCII a Unicode. Nejjednodušší způsob, jak vytvořit řetězec, je použít řetězcovou konstantu.
Chcete-li deklarovat řetězcovou konstantu, použijte rovné dvojité uvozovky (") nebo jednoduché uvozovky (').
Například následující dva řetězce jsou rovnocenné:
var str1:String = "hello";
var str2:String = 'hello';
Můžete také deklarovat řetězec pomocí operátoru new a to takto:
var str1:String = new String("hello");
var str2:String = new String(str1);
var str3:String = new String();
// str3 == ""
Následující dva řetězce jsou rovnocenné:
var str1:String = "hello";
var str2:String = new String("hello");
Chcete-li použít jednoduché uvozovky (') v řetězcové konstantě definované v jednoduchých uvozovkách ('), použijte
únikový znak zpětné lomítko (\). Chcete-li použít dvojité uvozovky (") v řetězcové konstantě definované v dvojitých
uvozovkách ("), použijte únikový znak zpětné lomítko (\). Následující dva řetězce jsou rovnocenné:
var str1:String = "That's \"A-OK\"";
var str2:String = 'That\'s "A-OK"';
Můžete si vybrat, zda použijete jednoduché uvozovky nebo dvojité uvozovky na základě kterýchkoliv jednoduchých
nebo dvojitých uvozovek existujících v řetězcové konstantě, jako v následujícím případu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 140
Práce s řetězci
var str1:String = "ActionScript <span class='heavy'>3.0</span>";
var str2:String = '<item id="155">banana</item>';
Mějte na paměti, že jazyk ActionScript rozlišuje mezi rovnými jednoduchými uvozovkami (') a levou či pravou
jednoduchou uvozovkou (' nebo ' ). Totéž platí pro dvojité uvozovky. Pro vymezení řetězcových konstant použijte
rovné uvozovky. Při vkládání textu z jiného zdroje do jazyka ActionScript nezapomeňte použít správné znaky.
Jak ukazuje následující tabulka, můžete použít znak zpětného lomítka (\) k definování jiných znaků v řetězcové
konstantě.
Posloupnost pro změnu
Znak
\b
Backspace
\f
Posuv formuláře
\n
Nový řádek
\r
Návrat vozíku
\t
Tabulátor
\unnnn
Znak Unicode s kódem znaku specifikovaný šestnáctkovým číslem nnnn; například \u263a je znak
smajlíku.
\\xnn
Znak ASCII s kódem znaku specifikovaný šestnáctkovým číslemnn
\'
Jednoduché uvozovky
\"
Dvojité uvozovky
\\
Znak jednoduchého zpětného lomítka
Vlastnost length
Každý řetězec má vlastnost length, která je rovna počtu znaků v řetězci.
var str:String = "Adobe";
trace(str.length);
// output: 5
Prázdný řetězec a řetězec null mají oba délku 0, jak ukazuje následující příklad:
var str1:String = new String();
trace(str1.length);
// output: 0
str2:String = '';
trace(str2.length);
// output: 0
Práce se znaky v řetězci
Každý znak v řetězci má pozici indexu v řetězci (celočíselná hodnota). Pozice indexu prvního znaku je 0. Například v
následujících řetězcích má znak y polohu 0 a znak w polohu 5:
"yellow"
Jednotlivé znaky v různých pozicích řetězce můžete prověřit pomocí metody charAt() a charCodeAt(), jako v
následujícím příkladu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 141
Práce s řetězci
var str:String = "hello world!";
for (var i:int = 0; i < str.length; i++)
{
trace(str.charAt(i), "-", str.charCodeAt(i));
}
Když tento kód spustíte, získáte následující výsledek:
h
e
l
l
o
w
o
r
l
d
!
- 104
- 101
- 108
- 108
- 111
32
- 119
- 111
- 114
- 108
- 100
- 33
Můžete také použít kódy znaků a definovat řetězec pomocí metody fromCharCode(), jako na následujícím příkladu:
var myStr:String = String.fromCharCode(104,101,108,108,111,32,119,111,114,108,100,33);
// Sets myStr to "hello world!"
Porovnávání řetězců
K porovnávání řetězců můžete použít následující operátory: <, <=, !=, ==, => a >. Tyto operátory lze používat s
podmínečnými příkazy, například if a while, jak je vidět na následujícím příkladu:
var str1:String = "Apple";
var str2:String = "apple";
if (str1 < str2)
{
trace("A < a, B < b, C < c, ...");
}
Pokud používáte tyto operátory s řetězci, jazyk ActionScript zvažuje hodnotu kódu každého znaku v řetězci,
porovnává znaky zleva doprava, jako na následujícím příkladu:
trace("A" < "B"); // true
trace("A" < "a"); // true
trace("Ab" < "az"); // true
trace("abc" < "abza"); // true
Použijte operátory == a != k vzájemnému porovnání řetězců a k porovnání řetězců s ostatními typy objektů, jako na
následujícím příkladu:
var str1:String = "1";
var str1b:String = "1";
var str2:String = "2";
trace(str1 == str1b); // true
trace(str1 == str2); // false
var total:uint = 1;
trace(str1 == total); // true
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 142
Práce s řetězci
Získání vyjádření řetězce z jiných objektů
Vyjádření String můžete získat pro kterýkoliv objekt. Všechny objekty mají pro tento účel metodu toString():
var n:Number = 99.47;
var str:String = n.toString();
// str == "99.47"
Když použijete operátor zřetězení + s kombinací objektů String a objektů, které řetězcem nejsou, nemusíte používat
metodu toString(). Podrobnosti o zřetězení, viz následující kapitola.
Globální funkce String() vrací stejnou hodnotu pro daný objekt jako hodnotu vrácenou objektem volajícím metodu
toString().
Zřetězení řetězců
Zřetězení řetězců znamená převzetí dvou řetězců a jejich spojení za sebou do jednoho. Například můžete použít
operátor + a zřetězit dva řetězce:
var str1:String = "green";
var str2:String = "ish";
var str3:String = str1 + str2; // str3 == "greenish"
Následující příklad ukazuje, že můžete také použít operátor += a dosáhnout stejného výsledku:
var str:String = "green";
str += "ish"; // str == "greenish"
Kromě toho třída String zahrnuje metodu concat(), kterou lze použít takto:
var str1:String = "Bonjour";
var str2:String = "from";
var str3:String = "Paris";
var str4:String = str1.concat(" ", str2, " ", str3);
// str4 == "Bonjour from Paris"
Pokud použijete operátor + (nebo operátor +=) s objektem String a objektem, který není řetězec, jazyk ActionScript
automaticky převede neřetězcový objekt na objekt String a vyhodnotí výraz, jak je vidět na následujícím příkladu:
var str:String = "Area = ";
var area:Number = Math.PI * Math.pow(3, 2);
str = str + area; // str == "Area = 28.274333882308138"
Následující příklad ukazuje, že však můžete použít závorky pro seskupení a poskytnout tak kontext pro operátor +:
trace("Total: $" + 4.55 + 1.45); // output: Total: $4.551.45
trace("Total: $" + (4.55 + 1.45)); // output: Total: $6
Vyhledání podřetězců a vzorků v řetězci
Podřetězce jsou znaky posloupnosti v řetězci: Například řetězec "abc" má následující podřetězce:"", "a", "ab",
"abc", "b", "bc", "c". Můžete použít metody jazyka ActionScript a lokalizovat podřetězec řetězce.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 143
Práce s řetězci
Vzorky jsou definovány v jazyce ActionScript řetězci nebo regulárními výrazy. Například následující regulární výraz
definuje specifický vzorek - písmena A, B a C následovaná číslicí (dopředná lomítka jsou oddělovači regulárního
výrazu):
/ABC\d/
Jazyk ActionScript zahrnuje metody pro vyhledání vzorků v řetězcích a pro náhradu nalezených shod s náhradním
podřetězcem. Tyto metody jsou popsané v následujících kapitolách.
Regulární výrazy mohou definovat komplikované vzorky. Další informace, viz „Používání regulárních výrazů“ na
stránce 202.
Vyhledání podřetězce podle polohy znaku
Metody substr() a substring() jsou obdobné. Obě vracejí podřetězec řetězce. Obě používají dva parametry. V
obou metodách je první parametr pozicí počátečního znaku v daném řetězci. V metodě substr() je však druhý
parametr délka vraceného podřetězce a v metodě substring() je druhý parametr polohou znaku na konci podřetězce
(není součástí vraceného řetězce). Tento příklad ukazuje rozdíl mezi těmito dvěma metodami:
var str:String = "Hello from Paris, Texas!!!";
trace(str.substr(11,15)); // output: Paris, Texas!!!
trace(str.substring(11,15)); // output: Pari
Metoda slice() pracuje podobně jako metoda substring(). Pokud jsou parametry vzaty dvě nezáporné celočíselné
hodnoty, pracují metody shodně. Metoda slice() však může vzít jako parametry záporné celočíselné hodnoty; v
tomto případě je poloha znaku vzata od konce řetězce, jak je vidět na následující příkladu:
var str:String = "Hello from Paris,
trace(str.slice(11,15)); // output:
trace(str.slice(-3,-1)); // output:
trace(str.slice(-3,26)); // output:
trace(str.slice(-3,str.length)); //
trace(str.slice(-8,-3)); // output:
Texas!!!";
Pari
!!
!!!
output: !!!
Texas
Nezáporné a záporné celočíselné hodnoty můžete zkombinovat jako parametry metody slice().
Vyhledání polohy znaku odpovídajícího podřetězce
Můžete použít metody indexOf() a lastIndexOf() a lokalizovat odpovídající podřetězce v rámci řetězce, jak
ukazuje následující příklad:
var str:String = "The moon, the stars, the sea, the land";
trace(str.indexOf("the")); // output: 10
Povšimněte si, že metoda indexOf() rozlišuje malá a velká písmena.
Můžete specifikovat druhý parametr a definovat tak pozici indexu v řetězci, ze kterého má začít hledání a to takto:
var str:String = "The moon, the stars, the sea, the land"
trace(str.indexOf("the", 11)); // output: 21
Metoda lastIndexOf() vyhledává poslední výskyt podřetězce v řetězci.
var str:String = "The moon, the stars, the sea, the land"
trace(str.lastIndexOf("the")); // output: 30
Pokud zahrnete druhý parametr do metody lastIndexOf(), hledání proběhne z této pozice indexu v řetězci směrem
zpět (zprava doleva):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 144
Práce s řetězci
var str:String = "The moon, the stars, the sea, the land"
trace(str.lastIndexOf("the", 29)); // output: 21
Vytváření pole podřetězců rozdělené oddělovacím znakem
Metodu split() můžete použít pro vytvoření pole podřetězců, které je rozděleno na základě oddělovacího znaku.
Například můžete rozdělit řetězec oddělený čárkou nebo tabulátorem do několika řetězců.
Následující příklad ukazuje způsob rozdělení pole do podřetězců se znakem ampersand (&) jako oddělovacím znakem:
var queryStr:String = "first=joe&last=cheng&title=manager&StartDate=3/6/65";
var params:Array = queryStr.split("&", 2); // params == ["first=joe","last=cheng"]
Druhý parametr metody split(), který je volitelný, definuje maximální velikost pole, které je vráceno.
Jako oddělovací znak můžete použít regulární výraz:
var str:String = "Give me\t5."
var a:Array = str.split(/\s+/); // a == ["Give","me","5."]
Další informace naleznete v kapitole „Používání regulárních výrazů“ na stránce 202 a Referenční příručce jazyka
ActionScript 3.0 a jeho součástí.
Vyhledání vzorků v řetězcích a nahrazení podřetězců
Třída String zahrnuje následující metody pro práci se vzorky v řetězcích:
• Metody match() a search() použijte k vyhledání podřetězců, které odpovídají vzorku.
• Metodu replace() použijte k vyhledání podřetězce, který odpovídá vzorku a nahraďte je specifikovaným
podřetězcem.
Tyto metody jsou popsané v následujících kapitolách.
Můžete použít řetězce nebo regulární výrazy k definování vzorků použitých v těchto metodách. Další informace o
regulárních výrazech naleznete v kapitole „Používání regulárních výrazů“ na stránce 202.
Vyhledání odpovídajících podřetězců
Metoda search() vrací pozici indexu prvního podřetězce, který odpovídá danému vzorku, jak je vidět na tomto
příkladu:
var str:String = "The more the merrier.";
// (This search is case-sensitive.)
trace(str.search("the")); // output: 9
Můžete také použít regulární výrazy a definovat odpovídající vzorek, jako na následujícím příkladu:
var pattern:RegExp = /the/i;
var str:String = "The more the merrier.";
trace(str.search(pattern)); // 0
Výstup z metody trace() je 0, protože první znak v řetězci má polohu indexu 0. Příznak i je nastaven v regulárním
výrazu, takže hledání nerozlišuje velká a malá písmena.
Metoda search() vyhledá pouze jednu shodu a vrací počáteční polohu indexu, i když je příznak g (globální) nastaven
na regulární výraz.
Následující příklad ukazuje komplikovanější regulární výraz a to takový, který odpovídá řetězci v dvojitých
uvozovkách.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 145
Práce s řetězci
var pattern:RegExp = /"[^"]*"/;
var str:String = "The \"more\" the merrier.";
trace(str.search(pattern)); // output: 4
str = "The \"more the merrier.";
trace(str.search(pattern)); // output: -1
// (Indicates no match, since there is no closing double quotation mark.)
Metoda match() pracuje podobným způsobem. Vyhledává odpovídající podřetězec. Když však použijete globální
příznak ve vzorku regulárního výrazu, jako na následujícím příklad, metoda match() vrátí pole odpovídajících
podřetězců:
var str:String = "[email protected], [email protected]";
var pattern:RegExp = /\w*@\w*\.[org|com]+/g;
var results:Array = str.match(pattern);
Pole results je nastaveno následovně:
["[email protected]","[email protected]"]
Další informace o regulárních výrazech naleznete v kapitole „Používání regulárních výrazů“ na stránce 202„Používání
regulárních výrazů“ na stránce 202.
Náhrada odpovídajících podřetězců
Metodu replace() můžete použít k vyhledání specifikovaného vzorku v řetězci a nahradit shody se specifikovaným
řetězcem, jak ukazuje následující příklad:
var str:String = "She sells seashells by the seashore.";
var pattern:RegExp = /sh/gi;
trace(str.replace(pattern, "sch"));
//sche sells seaschells by the seaschore.
Na tomto příkladu si povšimněte, že odpovídající řetězce nerozlišují velká a malá písmena, protože příznak i
(ignoreCase) je nastaven v regulárním výrazu a několik shod je nahrazeno proto, že je nastaven příznak g (global).
Další informace, viz „Používání regulárních výrazů“ na stránce 202.
Následující nahrazující kódy $ můžete zahrnout do nahrazujícího řetězce. Nahrazující text zobrazený v následující
tabulce se vloží namísto nahrazujícího kódu $:
$ Kód
Nahrazující text
$$
$
$&
Odpovídající dílčí řetězec.
$`
Část řetězce, který předchází odpovídajícímu dílčímu řetězci. Tento kód používá levou jednoduchou uvozovku (`),
nikoliv rovnou jednoduchou uvozovku (') nebo levou zatočenou jednoduchou uvozovku (' ).
$'
Část řetězce, který následuje po odpovídajícím dílčím řetězci. Tento kód používá rovnou jednoduchou uvozovku ('
).
$n
Zachycená, vsunutá n-tá skupina odpovídá, kde n je jednoduché číslo 1-9 a $n není následováno desetinnou číslicí.
$nn
Zachycená, vsunutá n-tá skupina odpovídá, kde nn je dvoumístné desetinné číslo 01-99. Pokud je nn-tý záchyt
nedefinovaný, je nahrazující text prázdný řetězec.
V následujícím příkladu se ukazuje použití nahrazujících kódů $1 a $2, které znázorňují první a druhou vyhovující
zachycenou skupinu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 146
Práce s řetězci
var str:String = "flip-flop";
var pattern:RegExp = /(\w+)-(\w+)/g;
trace(str.replace(pattern, "$2-$1")); // flop-flip
Jako druhý parametr metody replace() můžete také použít funkci. Odpovídající text je nahrazen vrácenou hodnotou
funkce.
var str:String = "Now only $9.95!";
var price:RegExp = /\$([\d,]+.\d+)+/i;
trace(str.replace(price, usdToEuro));
function usdToEuro(matchedSubstring:String, capturedMatch1:String,
str:String):String
{
var usd:String = capturedMatch1;
usd = usd.replace(",", "");
var exchangeRate:Number = 0.853690;
var euro:Number = parseFloat(usd) * exchangeRate;
const euroSymbol:String = String.fromCharCode(8364);
return euro.toFixed(2) + " " + euroSymbol;
}
index:int,
Když funkci použijete jako druhý parametr metody replace(), jsou funkci předány následující argumenty:
• Vyhovující část řetězce.
• Jakákoliv zachycená vsunutá skupina odpovídá. Počet argumentů předaných tímto způsobem se bude měnit v
závislosti na počtu vsunutých shod. Můžete určit počet vsunutých shod ověřením arguments.length - 3uvnitř
kódu funkce.
• Indexová pozice v řetězci, kde začíná shoda.
• Úplný řetězec.
Převod řetězců mezi velkými a malými písmeny
Následující příklad ukazuje, jak metoda toLowerCase() a toUpperCase() převádějí abecední znaky v řetězci na
malá, respektive na velká písma:
var str:String = "Dr. Bob Roberts, #9."
trace(str.toLowerCase()); // dr. bob roberts, #9.
trace(str.toUpperCase()); // DR. BOB ROBERTS, #9.
Po vykonání těchto metod zůstává zdrojový řetězec nezměněný. Chcete-li transformovat zdrojový řetězec, použijte
následující kód:
str = str.toUpperCase();
Tyto metody jsou funkční s rozšířenými znaky, nikoliv jednoduše s a–z a A–Z:
var str:String = "José Barça";
trace(str.toUpperCase(), str.toLowerCase()); // JOSÉ BARÇA josé barça
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 147
Práce s řetězci
Příklad: kresba ASCII
Tato kresba ASCII ukazuje několik funkcí, které lze s třídou String v jazyce ActionScript 3.0 použít, včetně
následujícího:
• Metoda split() třídy String se používá pro extrahování hodnot z řetězce odděleného znaky (informace o obrázku
v textovém souboru odděleném tabulátoru).
• K změně prvního písmena každého slova v názvech souborů na velké se používá několik technik zpracování, včetně
split(), zřetězení a extrahování části řetězce pomocí substring() a substr().
• Metoda getCharAt() se používá k získání jednoho znaku z řetězce (pro stanovení znaku ASCII odpovídajícího
hodnotě stupnice šedé bitmapy).
• Zřetězení řetězce se používá pro sestavení vyjádření kresby ASCII obrazu po jednotlivých znacích.
Termín kresba ASCII popisuje textová vyjádření obrázku, ve kterém se obrázek vykreslí ve formě mřížky znaků písma
se stejnou roztečí, například Courier New. Následující obrázek ukazuje příklad kresby ASCII vytvořené aplikací.
Verze kresby ASCII je zobrazena vpravo.
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace ASCIIArt naleznete ve složce Samples/AsciiArt. Aplikace sestává z následujících souborů:
Soubor
Popis
AsciiArtApp.mxml
Hlavní aplikační soubor v aplikaci Flash (FLA) nebo Flex
(MXML)
nebo
AsciiArtApp.fla
com/example/programmingas3/asciiArt/AsciiArtBuilder.as
Třída poskytující hlavní funkci aplikace, včetně metadat
extrahování aplikace z textového soubor, načítající obrázky a
řídicí proces převodu obrázku a textu.
com/example/programmingas3/asciiArt/BitmapToAsciiConverter.as
Třída zajišťující metodu parseBitmapData() pro převod
obrazových dat do verze String.
com/example/programmingas3/asciiArt/Image.as
Třída zastupující načtený bitmapový obraz.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 148
Práce s řetězci
Soubor
Popis
com/example/programmingas3/asciiArt/ImageInfo.as
Třída zastupující metadata pro kresbu obrazu ASCII (například
název, URL obrazového souboru atd.).
obraz/
Složka obsahující obrazy používané aplikací.
txt/ImageData.txt
Textový soubor oddělený tabulátory, obsahující informace o
obrázcích, které mají být načteny aplikací.
Extrahování hodnot oddělených tabulátorem
Tento příklad používá běžný postup ukládání dat aplikace odděleně od samotné aplikace; tímto způsobem není nutné
soubory SWF opakovaně vytvářet, pokud se data změní (například pokud přidáte jiný obrázek nebo se změní název
obrázku). V tomto případě jsou obrazová metadata, včetně názvu obrázku, URL stávajícího obrazového souboru a
některé hodnoty použité pro manipulaci s obrazem, uložena v textovém souboru (soubor txt/ImageData.txt projektu).
Obsahy textových souborů jsou následující:
FILENAMETITLEWHITE_THRESHHOLDBLACK_THRESHHOLD
FruitBasket.jpgPear, apple, orange, and bananad810
Banana.jpgA picture of a bananaC820
Orange.jpgorangeFF20
Apple.jpgpicture of an apple6E10
Soubor používá specifický formát oddělený tabulátorem. První řádek je záhlaví. Zbývající řádky obsahují následující
data pro každou bitmapu, kterou je nutné načíst:
• Název souboru bitmapy.
• Zobrazovaný název bitmapy.
• Prahová hodnota bílé a černé pro bitmapy. To jsou šestnáctkové hodnoty, nad a pod kterými obrazový bod bude
považován za zcela bílý nebo zcela černý.
Jakmile se aplikace spustí, třída AsciiArtBuilder se načte a analyzuje obsah textového souboru, aby mohla vytvořit
„svazek“ obrázků, které zobrazí, a to pomocí následujícího kódu z metody parseImageInfo() třídy AsciiArtBuilder:
var lines:Array = _imageInfoLoader.data.split("\n");
var numLines:uint = lines.length;
for (var i:uint = 1; i < numLines; i++)
{
var imageInfoRaw:String = lines[i];
...
if (imageInfoRaw.length > 0)
{
// Create a new image info record and add it to the array of image info.
var imageInfo:ImageInfo = new ImageInfo();
// Split the current line into values (separated by tab (\t)
// characters) and extract the individual properties:
var imageProperties:Array = imageInfoRaw.split("\t");
imageInfo.fileName = imageProperties[0];
imageInfo.title = normalizeTitle(imageProperties[1]);
imageInfo.whiteThreshold = parseInt(imageProperties[2], 16);
imageInfo.blackThreshold = parseInt(imageProperties[3], 16);
result.push(imageInfo);
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 149
Práce s řetězci
Celý obsah textového souboru je obsažený v jedné instanci String, vlastnosti _imageInfoLoader.data. Pomocí
metody split() se znakem nové řádky ("\n") jako parametrem je instance String rozdělena do pole Array (lines),
jehož prvky jsou jednotlivé řádky textového souboru. Dále kód využívá cyklus k práci s každou řádkou (kromě první,
protože ta obsahuje pouze záhlaví, spíše než stávající obsah). Uvnitř cyklu je použita metoda split() znovu k
rozdělení obsahu jedné řádky do souboru hodnotu (objekt Array nazvaný imageProperties). Parametr použitý s
metodou split() je v tomto případě znak tabulátoru ("\t"), protože hodnoty v každé řádce jsou rozděleny znakem
tabulátoru.
Použití metod String k normalizování názvů obrázků
Jedním z rozhodnutí při návrhu této aplikace je to, že všechny názvy obrázků jsou zobrazeny pomocí standardního
formátu, s prvním písmenem každého slova velkým (kromě několika slov, které v anglických názvech obvykle nejsou
s velkými písmeny). Aplikace naformátuje názvy, když jsou extrahovány z textového souboru, spíše než aby
předpokládala, že textový soubor obsahuje správně naformátované názvy.
V předchozím kódu byla použita následující řádka, jako součást extrahování jednotlivých hodnot metadat obrázku:
imageInfo.title = normalizeTitle(imageProperties[1]);
V tomto kódu je název obrázku z textového souboru předán metodou normalizeTitle() předtím, než je uložen v
objektu ImageInfo.
private
{
var
var
for
{
function normalizeTitle(title:String):String
words:Array = title.split(" ");
len:uint = words.length;
(var i:uint; i < len; i++)
words[i] = capitalizeFirstLetter(words[i]);
}
return words.join(" ");
}
Tato metoda používá metodu split() k rozdělení názvu do jednotlivých slov (oddělené mezerou), předává každé
slovo metodě capitalizeFirstLetter() a pak použije metodu join() třídy Array ke kombinování slov zpět do
jednoho řetězce.
Jak naznačuje název, metoda capitalizeFirstLetter() provede změnu prvního písmena každého slova na velké:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 150
Práce s řetězci
/**
* Capitalizes the first letter of a single word, unless it's one of
* a set of words that are normally not capitalized in English.
*/
private function capitalizeFirstLetter(word:String):String
{
switch (word)
{
case "and":
case "the":
case "in":
case "an":
case "or":
case "at":
case "of":
case "a":
// Don't do anything to these words.
break;
default:
// For any other word, capitalize the first character.
var firstLetter:String = word.substr(0, 1);
firstLetter = firstLetter.toUpperCase();
var otherLetters:String = word.substring(1);
word = firstLetter + otherLetters;
}
return word;
}
U následujících slov není v angličtině počáteční znak každého slova v názvu uveden velkým písmenem: „and“, „the“,
„in“, „an“, „or“, „at“, „of“, nebo „a“ (to je zjednodušená verze pravidel). Pro vykonání této logiky kód nejprve použije
příkaz switch je kontrole, zda slovo je jedno ze slov, které by nemělo mít první písmeno velké. Pokud ani, kód
jednoduše vyskočí z příkazu switch. Na druhou stranu, pokud slovo má mít první písmeno velké, je to provedeno
několika kroky takto:
1 První písmeno slova je extrahováno pomocí metody substr(0, 1), která extrahuje podřetězec začínající znakem
na indexu 0 (první písmeno v řetězci, jak je uvedeno prvním parametrem 0). Podřetězec bude jeden znak v délce
(označeno druhým parametrem 1).
2 Tento znak bude převeden na velké písmeno pomocí metody toUpperCase().
3 Zbývající znaky původního slova jsou extrahovány pomocí metody substring(1), která extrahuje podřetězec
začínající na indexu 1 (druhé písmeno) až na konec řetězce (stanoveno opuštěním druhého parametru metody
substring()).
4 Závěrečné slovo je vytvořeno kombinací prvního písmena nově převedeného na velké, se zbývajícími písmeny
pomocí metody zřetězení: firstLetter + otherLetters.
Generování textu kresby ASCII
Třída BitmapToAsciiConverter poskytuje funkci převedení bitmapy do textového vyjádření ASCII. Tento proces je
prováděn metodou parseBitmapData(), která je zde částečně popsána:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 151
Práce s řetězci
var result:String = "";
// Loop through the rows of pixels top to bottom:
for (var y:uint = 0; y < _data.height; y += verticalResolution)
{
// Within each row, loop through pixels left to right:
for (var x:uint = 0; x < _data.width; x += horizontalResolution)
{
...
// Convert the gray value in the 0-255 range to a value
// in the 0-64 range (since that's the number of "shades of
// gray" in the set of available characters):
index = Math.floor(grayVal / 4);
result += palette.charAt(index);
}
result += "\n";
}
return result;
Tento kód nejprve definuje instanci String pojmenovanou result, která bude použita pro vytvoření bitmapového
obrazu ve verzi kresby ASCII. Dále dojde k opakování s jednotlivými obrazovými body zdrojového bitmapového
obrazu. Pomocí několika technik pro manipulaci s barvami (zde jsou pro zestručnění vynechány), převede červenou,
zelenou a modrou barvu z příslušných hodnot jednotlivých obrazových bodů do jediné škály šedé (číslo od 0 do 255).
Kód pak podělí tuto hodnotu 4 (jak je znázorněno) a převede ji do hodnoty stupnice 0-63, která je uložena v proměnné
index. (Stupnice 0-63 se používá proto, že „paleta“ dostupných znaků ASCII použitých v aplikaci obsahuje 64
hodnot.) Paleta znaků je definována jako instance String v třídě BitmapToAsciiConverter.
// The characters are in order from darkest to lightest, so that their
// position (index) in the string corresponds to a relative color value
// (0 = black).
private static const palette:String =
"@#$%&8BMW*mwqpdbkhaoQ0OZXYUJCLtfjzxnuvcr[]{}1()|/?Il!i><+_~-;,. ";
Protože proměnná index definuje, který znak ASCII v paletě odpovídá stávajícímu obrazovému bodu v bitmapovém
obrázku, tento znak bude načten z palette String pomocí metody charAt(). Poté dojde k připojení k result
instance String pomocí operátoru přiřazení zřetězení (+=). Kromě toho na konci každé řádky obrazových bodů je znak
nové řádky zřetězen na konec result String, což vynutí zalomení řádky a vytvoření nové řádky znaků „obrazových
bodů“.
152
Kapitola 8: Práce s poli
Pole vám umožňují ukládat více hodnot do jediné struktury dat. Můžete použít jednoduchá indexovaná pole, která
uchovávají hodnoty pomocí pevných indexů s pořadovými celými čísly nebo složitá asociativní pole, která uchovávají
hodnoty pomocí libovolných klíčů. Pole mohou být také vícedimenzionální, mohou obsahovat prvky, které jsou také
pole. Můžete také použít Vector pro pole, jehož prvky jsou všechny instance stejného datového typu. Tato kapitola
uvádí způsob vytváření a práce s různými typy polí.
Základní informace o polích
Úvod do práce s poli
Během programovaní budete často pracovat se souborem položek více než s jediným objektem. Například v aplikaci
přehrávače hudby si můžete přát vytvořit seznam písní čekajících k přehrání. Pravděpodobně si nebudete přát vytvořit
samostatnou proměnnou pro každou píseň na seznamu. Oceníte všechny objekty Song společně v jednom balíku a
možnost pracovat s nimi jako se skupinou.
Pole je programovací element, který se chová jako kontejner pro množinu položek, například pro seznam písní.
Všechny položky v poli jsou většinou instance stejné třídy. Tato shoda ale není v jazyce ActionScript požadavkem.
Jednotlivé položky v poli se nazývají elementy pole. Pole si lze představit jako zásuvku pro proměnné. Proměnné lze
přidat jako elementy v poli, což se podobá umístění složky do zásuvky. S polem můžete pracovat jako s jedinou
proměnnou (jako byste celou zásuvku přenesli na jiné místo). S proměnnými můžete pracovat jako se skupinou (jako
procházení složek a vyhledávání určité informace). K proměnným můžete také přistupovat jednotlivě (jako otevření
zásuvky a vybrání jediné složky).
Představte si například vytvoření aplikace přehrávače hudby, ve kterém si uživatel může vybrat více písní a přidat je
do seznamu přehrávání. Ve svém kódu jazyka ActionScript máte metodu pojmenovanou addSongsToPlaylist(),
která přijímá jediné pole jako parametr. Bez ohledu na počet písní, které si přejete přidat do seznamu (několik, mnoho
nebo pouze jednu), voláte metodu addSongsToPlaylist() pouze jednou a předáte jí pole obsahující objekty Song.
Uvnitř metody addSongsToPlaylist() můžete pomocí opakování procházet elementy pole (písně) jeden po druhým
a přidat je do seznamu přehrávání.
Nejběžnějším typem pole jazyka ActionScript je indexované pole. V indexovaném poli je každá položka uložena v
několika slotech (nazvaných index). K položkám můžete získat přístup pomocí čísla, které slouží jako adresa.
Indexovaná pole fungují dobře pro většinu programovacích potřeb. Třída Array je běžná třída, která je použita k
reprezentaci indexovaného pole.
Indexované pole je často použito k uložení více položek stejného typu (objekty, které jsou instancemi stejné třídy).
Třída Array nemá žádné prostředky k omezení typu položek, které obsahuje. Třída Vector je typ indexovaného pole,
ve kterém mají všechny položky v jednom poli stejný typ. Použitím instance Vector namísto instance Array můžete
získat lepší výkon a jiné výhody. Třída Vector je dostupná od verzí Flash Player 10 a Adobe AIR 1.5.
Speciální použití indexovaného pole je multidimenzionální pole. Multidimenzionální pole je indexované pole, jehož
elementy jsou indexovaná pole (která obsahují další elementy).
Dalším typem pole je asociativní pole, které k určení jednotlivých elementů používá řetězec key namísto numerického
indexu. Jazyk ActionScript 3.0 obsahuje také třídu Dictionary, která představuje slovník. Slovník je pole, které vám
umožňuje použít jakýkoliv typ objektu jako klíč k rozlišení elementů.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 153
Práce s poli
Běžné úlohy polí
V této kapitole jsou popsány následující běžné činnosti pro práci s poli:
• Vytvoření indexovaných polí pomocí třídy Array a třídy Vector
• Přidávání a odstraňování elementů polí
• Třídění elementů polí
• Vyjímání částí pole
• Práce s asociativními poli a slovníky
• Práce s multidimenzionálními poli
• Kopírování elementů pole
• Vytváření podtřídy pole
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Pole: objekt, který slouží jako kontejner k seskupení více objektů
• Operátor přístupu k poli ([]): dvojice hranatých závorek obklopujících index nebo klíč, který jedinečně identifikuje
element pole. Tato syntaxe je použita po názvu proměnné pole k určení jediného elementu pole spíše než celého pole.
• Asociativní pole: pole, které používá klíče řetězců k určení jednotlivých elementů
• Základní typ: datový typ daného objektu, který instance Vector může uložit
• Slovník: pole, jehož položky se skládají z dvojice objektů, z klíče a hodnoty. Klíč je použit namísto numerického
indexu k určení jednotlivých elementů.
• Element: položka v poli
• Index: numerická „adresa“ použitá k určení jednotlivých elementů v indexovaném poli
• Indexované pole: standardní typ pole, které ukládá každý element v očíslované pozici a k určení jednotlivých
elementů používá číslo (index)
• Klíč: řetězec nebo objekt použitý k určení jednotlivých elementů v asociativním poli nebo slovníku
• Multidimenzionální pole: pole obsahující položky, které jsou pole spíše než jednotlivé hodnoty
•
T: standardní konvence, která je použita v této dokumentaci k reprezentaci základního typu instance Vector, ať už
je daným základním typem cokoliv. T konvence je použita k reprezentaci názvu třídy, viz popis parametru Type.
(„T” znamená „typ“, jako ve spojení „datový typ“.)
• Parametr typu: syntaxe používaná s názvem třídy Vector k určení základního typu vektoru (datového typu objektů,
které uchovává). Syntaxe se skládá z tečky (.), poté z názvu datového typu obklopeného lomenými závorkami (<>).
Dohromady vše vypadá následovně: Vector.<T>. V této dokumentaci je třída určená v parametru typu znázorněna
genericky jako T.
• Vektor: typ pole jehož všechny elementy jsou instance stejného datového typu
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 154
Práce s poli
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. V
podstatě všechny výpisy kódů uvedené v této kapitole zahrnují příslušné volání funkce trace(). Návod na vyzkoušení
kódů uvedených v této kapitole:
1 Ve vývojovém nástroji Flash vytvořte prázdný dokument
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
Výsledky funkcetrace() se zobrazí v panelu Výstup.
Tyto a další postupy pro testování vzorových výpisů kódů jsou podrobněji popsány v sekci „Testování příkladů kódu
v této kapitole“ na stránce 34.
Indexovaná pole
Indexovaná pole uchovávají sérii jedné nebo více hodnot seřazených tak, aby každá hodnota byla přístupná pomocí
celého čísla bez znaménka. První index je vždy číslo 0 a pro každý následující prvek přidaný do pole se hodnota indexu
zvýší o 1. V jazyce ActionScript 3.0 jsou jako indexovaná pole použity dvě třídy: třída Array a třída Vector.
Indexovaná pole používají pro číslo indexu 32-bitové celé číslo bez znaménka. Maximální velikost indexovaného pole
je 232 - 1 nebo 4,294,967,295. Pokus o vytvoření pole většího než je maximální velikost vyvolá chybu v době běhu.
Pro přístup k jednotlivým elementům indexovaného pole použijte operátor přístupu k poli ([]) k určení pozice indexu
elementu, ke kterému si přejete získat přístup. Například následující kód představuje první element (element v indexu
0) v indexovaném poli nazvaném songTitles:
songTitles[0]
Kombinace názvu proměnné pole následovaná indexem v hranatých závorkách má funkci identifikátoru. (Jinak
řečeno, může být použita jakýmkoliv způsobem, kterým bývá proměnná obvykle použita.) Elementu indexovaného
pole můžete přiřadit hodnotu pomocí názvu a indexu na levé straně příkazu přiřazení:
songTitles[1] = "Symphony No. 5 in D minor";
Podobně můžete načíst hodnotu elementu indexovaného pole pomocí názvu a indexu na pravé straně příkazu
přiřazení:
var nextSong:String = songTitles[2];
Můžete také použít proměnnou v hranatých závorkách a nemusíte zadat explicitní hodnotu. (Proměnná musí
obsahovat nezápornou hodnotu celého čísla, např. uint, kladný int nebo kladnou instanci celého čísla Number.) Tato
technika je běžně používána k „vytvoření smyčky“ přes elementy v indexovaném poli a provedení operace na
některých nebo na všech elementech. Toto technika je ukázána v následujícím výpise kódu. Kód používá opakování k
přístupu ke každé hodnotě v objektu Array nazvaném oddNumbers. Používá příkaz trace() k vytištění každé hodnoty
ve formuláři „oddNumber[index] = value“:
var oddNumbers:Array = [1, 3, 5, 7, 9, 11];
var len:uint = oddNumbers.length;
for (var i:uint = 0; i < len; i++)
{
trace("oddNumbers[" + i.toString() + "] = " + oddNumbers[i].toString());
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 155
Práce s poli
Třída Array
Prvním typem indexovaného pole je třída Array. Instance Array může obsahovat hodnotu libovolného datového typu.
Stejný objekt Array může obsahovat objekty, které mají odlišný datový typ. Každá instance Array může mít například
hodnotu String v indexu 0, instanci Number v indexu 1 a objekt XML v indexu 2.
Třída Vector
Dalším typem indexovaného pole, které je v jazyce ActionScript 3.0 dostupné, je třída Vector. Instance Vector je
typované pole, což znamená, že všechny elementy v instanci Vector mají vždy stejný datový typ.
Poznámka: Třída Vector je dostupná od verzí Flash Player 10 a Adobe AIR 1.5.
Jestliže deklarujete proměnnou Vector nebo konkretizujete objekt Vector, explicitně určíte datový typ daného objektu,
který může daný vektor obsahovat. Určený datový typ je známý jako základní typ Vektoru. V době běhu a v době
kompilace (v přísném režimu) je zkontrolován jakýkoliv kód, který nastaví hodnotu elementu Vector nebo načte
hodnotu z Vektoru. Jestliže přidávaný nebo načítaný datový typ objektu neodpovídá základnímu typu Vektoru,
vygeneruje se chyba.
Kromě omezení typu dat má třída Vector i další omezení, která ji odlišují od třídy Array:
• Vektor je husté pole. Objekt Array může mít hodnoty v indexu 0 a 7, i když nemá žádné hodnoty v pozicích 1 až 6.
Nicméně Vektor musí mít v každém indexu hodnotu (nebo null).
• Vektor může mít volitelně pevně stanovenou délku. To znamená, že počet elementů, které vektor obsahuje, se
nezmění.
• Přístup k prvkům Vektoru je kontrolován s ohledem na meze. Nelze číst hodnotu z indexu většího než poslední
prvek (length- 1). Nelze nastavit hodnotu s indexem více než jedna za aktuálním konečným indexem (jinými
slovy, můžete nastavit hodnotu pouze na stávajícím indexu nebo na indexu [length]).
V důsledku těchto omezení má Vektor dvě hlavní výhody před instancí Array, jejíž prvky jsou všechny instance jediné
třídy:
• Výkon: přístup k prvkům pole a iterace jsou mnohem rychlejší při použití instance Vector než při použití instance
Array.
• Typ zabezpečení: v přísném režimu může kompilátor identifikovat chyby datového typu. Příklady takových chyb
zahrnují přiřazení hodnoty k nesprávnému datovému typu k Vektoru nebo očekávání špatného datového typu při
čtení hodnoty z Vektoru. V době běhu jsou datové typy také zkontrolovány při přidávání dat nebo načítání dat z
objektu Vector. Upozorňujeme však, že pomocí metody push() nebo unshift() pro přidání hodnot do Vektoru
nebudou typy dat argumentů kontrolovány během kompilace. Při používání těchto metod jsou hodnoty stále
kontrolovány v době běhu.
Mimo dodatečných omezení a výhod se třída Vector velice podobá třídě Array. Vlastnosti a metody objektu Vector
jsou podobné – ve většině případů totožné – vlastnostem a metodám Array. V každé situaci tam, kde byste použili pole,
ve kterém mají všechny prvky stejný datový typ, je výhodnější použít instanci Vector.
Vytváření polí
K vytvoření instance Array nebo Vector můžete použít několik technik. Nicméně techniky k vytvoření každého typu
pole se trochu liší.
Vytváření instance Array
Objekt Array vytvoříte voláním konstruktoru Array() nebo použitím syntaxe literálu Array.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 156
Práce s poli
Funkci konstruktoru třídyArray() lze použít třemi způsoby. Zaprvé, jestliže voláte konstruktor bez argumentů,
získáte prázdné pole. Pro ověření, zda pole nemá žádné prvky, můžete použít vlastnost třídy Array length. Následující
kód například vyvolá konstruktor třídy Array() bez argumentů:
var names:Array = new Array();
trace(names.length); // output: 0
Za druhé, jestliže použijete jako jediný parametr konstruktoru třídy Array() číslo, vytvoří se pole o dané délce a každá
hodnota prvku bude nastavena na undefined. Argument musí být celé číslo bez znaménka o hodnotě od 0 do
4,294,967,295. Následující kód například volá konstruktor třídy Array() pomocí jediného číselného argumentu:
var names:Array = new Array(3);
trace(names.length); // output: 3
trace(names[0]); // output: undefined
trace(names[1]); // output: undefined
trace(names[2]); // output: undefined
Zatřetí, jestliže voláte konstruktor a předáte seznam prvků jako parametry, vytvoří se pole a jeho prvky budou
odpovídat každému parametru. Následující kód předá do konstruktoru třídy Array() tři argumenty:
var names:Array = new Array("John", "Jane", "David");
trace(names.length); // output: 3
trace(names[0]); // output: John
trace(names[1]); // output: Jane
trace(names[2]); // output: David
Můžete také vytvořit pole s literály Array. Literál pole může být přiřazen přímo k proměnné pole, viz následující
příklad:
var names:Array = ["John", "Jane", "David"];
Vytváření instance Vector
Instanci Vector vytvoříte voláním konstruktoru Vector.<T>(). Vector můžete také vytvořit voláním globální funkce
Vector.<T>(). Daná funkce převede určený objekt na instanci Vector. Jazyk ActionScript nemá žádný ekvivalent
vektoru k syntaxi literálu Array.
Kdykoliv deklarujete proměnnou Vector (nebo podobně parametr metody Vector nebo typ návratové metody),
určujete základní typ proměnné Vector. Základní typ také určíte, když vytvoříte instanci Vector, voláním
konstruktoruVector.<T>(). Jinak řečeno, kdykoliv použijete v jazyce ActionScript termín Vector, je tento termín
doplněn základním typem.
Základní typ vektoru určíte pomocí syntaxe parametru typu. Parametr typu v kódu ihned následuje za slovem Vector.
Skládá se z tečky .), poté z názvu základní třídy obklopené lomenými závorkami (<>), viz následující příklad:
var v:Vector.<String>;
v = new Vector.<String>();
Na prvním řádku příkladu je proměnná v deklarována jako instance Vector.<String>. Jinými slovy, představuje
indexované pole, které může obsahovat pouze instance String. Druhý řádek volá konstruktor Vector() k vytvoření
instance stejného typu Vector (tj. Vektor, jehož elementy jsou všechny objekty String). Přiřadí daný objekt k v.
Používání konstruktoru Vector.<T>()
Jestliže používáte konstruktor Vector.<T>() bez argumentů, vytvoří se prázdná instance Vector. Prázdný vektor
otestujete zkontrolováním jeho vlastnosti length. Například následující kód volá konstruktorVector.<T>() bez
argumentů:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 157
Práce s poli
var names:Vector.<String> = new Vector.<String>();
trace(names.length); // output: 0
Jestliže již předem víte, kolik elementů bude vektor na začátku potřebovat, můžete předem definovat počet elementů
v daném Vektoru. Pro vytvoření Vektoru s určitým počtem elementů předejte počet elementů jako první parametr
(parametr length). Protože elementy Vector nemohou být prázdné, jsou vyplněny instancemi základního typu.
Jestliže je základní typ referenčním typem, který umožňuje hodnoty null, všechny elementy obsahují null. V
opačném případě všechny elementy obsahují výchozí hodnotu pro danou třídu. Například proměnná uint nemůže být
null. V následujícím kódu je Vektor nazvaný ages vytvořen se sedmi elementy, kde každý obsahuje hodnotu 0:
var ages:Vector.<uint> = new Vector.<uint>(7);
trace(ages); // output: 0,0,0,0,0,0,0
Nakonec pomocí konstruktoruVector.<T>() můžete vytvořit Vektor s pevnou délkou true pro druhý parametr
(parametr fixed). V daném příkladě je Vektor vytvořený s určitým počtem elementů a daný počet elementů nelze
změnit. Nicméně upozorňujeme, že hodnoty elementů Vektoru s pevnou délkou stále můžete změnit.
Narozdíl od třídy Array nemůžete předat seznam hodnot ke konstruktoru Vector.<T>() k určení počátečních
hodnot Vektoru.
Používání globální funkce Vector.<T>()
Mimo konstruktor Vector.<T>() můžete také k vytvoření objektu Vector použít globální funkci Vector.<T>().
Globální funkce Vector.<T>() je funkcí konverze. Když voláte globální funkci Vector.<T>(), určíte základní typ
Vektoru, který daná metoda vrátí. Předáte jednotlivé indexované pole (instance Array nebo Vector) jako argument.
Metoda poté vrátí Vektor s určitým datovým typem obsahujícím hodnoty v argumentu zdrojového pole. Následující
výpis kódu ukazuje syntaxi pro volání globální funkce Vector.<T>():
var friends:Vector.<String> = Vector.<String>(["Bob", "Larry", "Sarah"]);
Globální funkce Vector.<T>() provádí konverzi datového typu na dvou úrovních. Zaprvé, při předání instance Array
k funkci bude vrácena instance Vector. Zadruhé, ať je zdrojové pole instance Array nebo Vector, funkce se pokusí
převést elementy zdrojového pole na hodnoty základního typu. Převod používá standardní pravidla převodu datového
typu jazyka ActionScript. Například následující výpis kódu převede hodnoty String ve zdrojovém poli na celá čísla ve
výsledném Vektoru. Desetinná část prví hodnoty ("1.5") je zkrácená a nečíselná třetí hodnota ("Waffles") je ve
výsledku převedena na 0:
var numbers:Vector.<int> = Vector.<int>("1.5", "17", "Waffles"]);
trace(numbers); // output: 1,17,0
Jestliže jakýkoliv ze zdrojových elementů nelze převést, vygeneruje se chyba.
Jestliže kód volá globální funkci Vector.<T>() a element ve zdrojovém poli je instancí podtřídy určeného základního
typu, je daný element přidán k výslednému Vektoru (nevygeneruje se chyba). Používání globální funkce
Vector.<T>() je ve skutečnosti jediný způsob, jak převést Vektor se základním typem T na Vektor se základním
typem, který je supertřídou T.
Vkládání prvků pole
Nejzákladnějším způsobem přidání elementu k indexovanému poli je použití operátoru přístupu k poli ([]). K
nastavení hodnoty elementu indexovaného pole použijte název objektu Array nebo Vector a číslo indexu na levé straně
přiřazeného příkazu:
songTitles[5] = "Happy Birthday";
Jestliže Array nebo Vector ještě nemá na daném indexu element, index se vytvoří a hodnota se uloží tam. Jestliže v
daném indexu hodnota existuje, nová hodnota nahradí tu stávající.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 158
Práce s poli
Objekt Array vám umožňuje vytvořit element v daném indexu. Nicméně u objektu Vector můžete hodnotu přiřadit
pouze ke stávajícímu indexu nebo k dalšímu dostupnému indexu. Další dostupný index odpovídá vlastnosti objektu
Vectorlength. Nejbezpečnějším způsobem přidání nového elementu k objektu Vector je použít kód podobný tomuto
výpisu kódu:
myVector[myVector.length] = valueToAdd;
Tři z metod třídy Array a Vector - push(), unshift() a splice() - vám umožňují vkládat prvky do indexovaného
pole. Metoda push() přidá jeden nebo více prvků na konec pole. Jinak řečeno, poslední prvek vložený do daného pole
pomocí metody push() bude mít nejvyšší číslo indexu. Metoda unshift() vloží jeden nebo více prvků na začátek
pole, a to vždy do umístění čísla indexu 0. Metoda splice() vloží libovolný počet položek do určeného indexu v poli.
Následující příklad ukazuje všechny tři metody. Pole pojmenované planets je vytvořeno pro uložení názvů planet v
pořadí jejich blízkosti ke Slunci. Zaprvé, metoda push() je volána za účelem přidání první položky Mars. Zadruhé,
metoda unshift() je volána pro vložení položky, která patří do přední části pole, Mercury. Nakonec je volána metoda
splice() pro vložení položek Venus a Earth za Mercury, ale před Mars. První argument odeslán do splice(), celé
číslo 1, řídí vkládání tak, aby začalo na indexu 1. Druhý argument odeslaný do splice(), celé číslo 0, určuje, že by
neměly být vymazány žádné položky. Nakonec třetí a čtvrté argumenty odeslané dosplice(), Venus a Earth jsou
položky, které mají být vloženy.
var planets:Array = new Array();
planets.push("Mars"); // array contents: Mars
planets.unshift("Mercury"); // array contents: Mercury,Mars
planets.splice(1, 0, "Venus", "Earth");
trace(planets); // array contents: Mercury,Venus,Earth,Mars
Metody push() a unshift() vrátí celé číslo bez znaménka, které představuje délku upraveného pole. Metoda
splice() vrátí prázdné pole, je-li použita pro vložení prvků. To se může zdát divné, ale vezmeme-li v úvahu pružnost
metody splice(), je to již jasnější. Metodu splice() můžete použít nejen k vkládání prvků do pole, ale také k
odstraňování prvků z pole. Je-li používána k odstraňování prvků, vrátí metoda splice()pole obsahující odstraněné
prvky.
Poznámka: Jestliže vlastnost objektu Vector fixed je true, celkový počet elementů ve Vektoru se nemůže změnit. Jestliže
se snažíte přidat nový element k Vektoru s pevnou délkou pomocí zde popsaných technik, vygeneruje se chyba.
Načítání hodnot a odstraňování elementů pole
Nejjednodušší způsob načtení hodnoty elementu z indexovaného pole je použít operátor přístupu k poli ([]). K
načtení hodnoty elementu indexovaného pole použijte název objektu Array nebo Vector a číslo indexu na levé straně
přiřazeného příkazu:
var myFavoriteSong:String = songTitles[3];
Můžete se pokusit načíst hodnotu z pole nebo vektoru pomocí indexu, kde neexistují žádné elementy. V daném
případě vrátí objekt Array hodnotu nedefinovanou a vektor vygeneruje výjimku RangeError.
Tři metody tříd Array a Vector - pop(), shift(), a splice() - vám umožňují odstranit elementy. Metoda pop()
odstraní prvek z konce pole. Jinak řečeno, odstraní prvek na nejvyšším čísle indexu. Metoda shift() odstraní prvek
ze začátku pole, což znamená, že vždy odstraní prvek v čísle indexu 0. Metoda splice(), kterou lze také použít pro
vkládání prvků, odstraní libovolný počet prvků, které začínají na čísle indexu určeném prvním argumentem
odeslaném na metodu.
Následující příklad používá všechny tři metody pro odstranění prvků z instance Array. Pole pojmenované oceans je
vytvořeno za účelem uložení názvů větších vodních ploch. Některé názvy v poli jsou jezera, nikoliv oceány, takže je
třeba je vyjmout.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 159
Práce s poli
Zaprvé, metoda splice() se použije pro odstranění položek Aral a Superior a vložení položek Atlantic a Indian.
První argument odeslaný na splice(), celé číslo 2, určuje, že by operace měla začínat třetí položkou v seznamu, která
se nachází na indexu 2. Druhý argument, 2, určuje, že by měly být odstraněny dvě položky. Zbývající argumenty,
Atlantic a Indian, jsou hodnoty, které budou vloženy na místo indexu 2.
Zadruhé, metoda pop() se použije k odstranění posledního prvku v poli, Huron. A zatřetí, metoda shift() se použije
k odstranění první položky v poli, Victoria.
var oceans:Array = ["Victoria", "Pacific", "Aral", "Superior", "Indian", "Huron"];
oceans.splice(2, 2, "Arctic", "Atlantic"); // replaces Aral and Superior
oceans.pop(); // removes Huron
oceans.shift(); // removes Victoria
trace(oceans);// output: Pacific,Arctic,Atlantic,Indian
Metody pop() a shift() obě vrátí položku, která byla odstraněna. Pro instanci Array je datový typ návratové hodnoty
Object, protože pole mohou obsahovat hodnoty jakéhokoliv datového typu. Pro instanci Vector je datový typ
návratové hodnoty základním typem Vektoru. Metoda splice() vrátí Pole nebo Vektor obsahující odstraněné
hodnoty. Pole oceans můžete například změnit tak, že volání splice() přiradí Pole k nové proměnné Pole, viz
následující příklad:
var lakes:Array = oceans.splice(2, 2, "Arctic", "Atlantic");
trace(lakes); // output: Aral,Superior
Kód, který používá operátor delete, můžete najít na elementu objektu Array. Operátor delete nastaví hodnotu
elementu Pole na undefined, ale neodstraní element z Pole. Například následující kód používá operátor delete na
třetím elementu v Poli oceans, ale délka Pole zůstává 5.
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Indian", "Atlantic"];
delete oceans[2];
trace(oceans);// output: Arctic,Pacific,,Indian,Atlantic
trace(oceans[2]); // output: undefined
trace(oceans.length); // output: 5
Pole nebo vektor můžete oříznout pomocí vlastností polelength. Jestliže nastavíte vlastnost lengthindexovaného
pole na délku, která je menší než aktuální délka pole, pole je oříznuto a odstraní se všechny uložené prvky na
indexových číslech vyšších než je nová hodnota Length mínus 1. Jestliže pole oceans bylo například roztříděno tak,
aby všechny platné záznamy byly na začátku pole, můžete vlastnost length použít pro odstranění záznamů na konci
pole, viz následující kód:
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Aral", "Superior"];
oceans.length = 2;
trace(oceans); // output: Arctic,Pacific
Poznámka: Jestliže vlastnost objektu Vector fixed je true, celkový počet elementů ve Vektoru se nemůže změnit. Jestliže
se snažíte odstranit element nebo seříznout Vektor s pevnou délkou pomocí zde popsaných technik, vygeneruje se chyba.
Třídění pole
Existují tři metody - reverse(), sort() a sortOn() - které vám umožňují změnit pořadí indexovaného pole, a to buď
tříděním nebo obrácením pořadí. Všechny tyto metody upravují stávající pole. Následující tabulka nabízí souhrn
těchto metod a jejich chování pro objekty Array a Vector:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 160
Práce s poli
Metoda
Chování pole
Chování vektoru
reverse()
Změní pořadí elementů tak, aby se poslední element stal elementem
prvním, předposlední element se stal elementem druhým, atd.
Identické s chováním Pole
sort()
Umožňuje vám třídit elementy Array různými předem definovanými
způsoby, například v alfabetickém nebo číselném pořadí. Můžete také
určit vlastní algoritmus třídění.
Třídí elementy podle vlastního algoritmu
třídění, který zadáte.
sortOn()
Umožňuje vám třídit objekty, které mají jednu nebo více společných
vlastností a určuje vlastnost nebo vlastnosti, které budou použity jako
klíče třídění
Ve třídě Vector není dostupná
Metoda reverse()
Metoda reverse() nepřebírá žádné parametry a nevrací hodnotu. Nicméně vám umožňuje přepínat pořadí svého
pole z jeho aktuálního stavu do opačného pořadí. Následující příklad obrací pořadí oceánů uvedených v poli oceans:
var oceans:Array = ["Arctic", "Atlantic", "Indian", "Pacific"];
oceans.reverse();
trace(oceans); // output: Pacific,Indian,Atlantic,Arctic
Základní třídění pomocí metody sort() (pouze třída Array)
Pro instance Array změní metoda sort() pořadí prvků v poli pomocí výchozího pořadí třídění. Výchozí pořadí třídění
má následující charakteristiky:
• Třídění je citlivé na velká a malá písmena, což znamená, že velká písmena předcházejí malá písmena. Například
písmeno D předchází písmenu b.
• Třídění je vzestupné, což znamená, že kódy malých písmen (například A) předcházejí kódům velkých písmen
(například B).
• Třídění umístí stejné hodnoty tak, aby navzájem sousedily, ale bez zvláštního pořadí.
• Třídění je založeno na řetězci, což znamená, že prvky jsou před porovnáním převedeny na řetězce (například 10
předchází 3, protože řetězec "1" má nižší kód znaku než řetězec "3").
Můžete zjistit, že svá pole potřebujete roztřídit bez ohledu na velká a malá písmena, v sestupném pořadí, nebo vaše
pole možná obsahuje čísla, která si přejete třídit číselně namísto abecedně. Metoda třídy Array sort() má parametr
options, který vám umožňuje změnit každou charakteristiku výchozího pořadí třídění. Volby jsou definovány sadou
statických konstant ve třídě Array, viz následující seznam:
•
Array.CASEINSENSITIVE: Po vybrání této možnosti nebude třídění zohledňovat velikost písmen. Například malé
písmeno b předchází velkému písmenu D.
•
•
Array.DESCENDING: Obrátí výchozí vzestupné třídění. Například písmeno B předchází písmenu A.
Array.UNIQUESORT: Vybráním této možnosti bude třídění přerušeno v případě, že budou nalezeny dvě stejné
hodnoty.
•
Array.NUMERIC: Vyvolá číselné třídění, takže 3 předchází 10.
Následující příklad zdůrazňuje některé z těchto voleb. Vytvořeno je pole pojmenované poets, které je tříděno pomocí
několika různých možností.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 161
Práce s poli
var poets:Array = ["Blake", "cummings", "Angelou", "Dante"];
poets.sort(); // default sort
trace(poets); // output: Angelou,Blake,Dante,cummings
poets.sort(Array.CASEINSENSITIVE);
trace(poets); // output: Angelou,Blake,cummings,Dante
poets.sort(Array.DESCENDING);
trace(poets); // output: cummings,Dante,Blake,Angelou
poets.sort(Array.DESCENDING | Array.CASEINSENSITIVE); // use two options
trace(poets); // output: Dante,cummings,Blake,Angelou
Vlastní třídění pomocí metody sort() (třídy Array a Vector)
Vedle základního třídění, které je dostupné pro objekt Array, můžete také definovat vlastní pravidla třídění. Tato
technika je jediným formátem metody sort(), který je dostupný pro třídu Vector. K definování vlastního třídění
zapište vlastní funkci třídění a předejte ji jako argument k metodě sort().
Jestliže máte například seznam jmen, kde každý prvek seznamu obsahuje celé jméno osoby, ale přejete si seznam třídit
podle příjmení, musíte použít vlastní funkci třídění pro analyzování každého prvku a použití příjmení ve funkci
třídění. Následující kód ukazuje způsob třídění pomocí vlastní funkce, která je použita jako parametr metody
Array.sort():
var names:Array = new Array("John Q. Smith", "Jane Doe", "Mike Jones");
function orderLastName(a, b):int
{
var lastName:RegExp = /\b\S+$/;
var name1 = a.match(lastName);
var name2 = b.match(lastName);
if (name1 < name2)
{
return -1;
}
else if (name1 > name2)
{
return 1;
}
else
{
return 0;
}
}
trace(names); // output: John Q. Smith,Jane Doe,Mike Jones
names.sort(orderLastName);
trace(names); // output: Jane Doe,Mike Jones,John Q. Smith
Vlastní funkce třídění orderLastName() používá běžný výraz k vyjmutí příjmení z každého prvku a jeho použití pro
operaci porovnání. Identifikátor funkce orderLastName se používá jako výhradní parametr při volání metody sort()
na poli names. Funkce třídění přijímá dva parametry, a a b, protože pracuje najednou na dvou prvcích pole. Návratová
hodnota funkce třídění udává, jak by měly být prvky tříděny:
• Návratová hodnota -1 určuje, že první parametr a předchází druhému parametru b.
• Návratová hodnota 1 určuje, že druhý parametr b předchází prvnímu a.
• Návratová hodnota 0 určuje, že prvky mají při třídění stejnou přednost.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 162
Práce s poli
Metoda sortOn() (pouze třída Array)
Metoda sortOn() je určena pro objekty Array s elementy, které obsahují objekty. Očekává se, že tyto objekty mají
minimálně jednu společnou vlastnost, která může být použita jako klíč třídění. Použití metody sortOn() pro pole
jakéhokoliv jiného typu vygeneruje neočekávané výsledky.
Poznámka: Třída Vector nezahrnuje metodu sortOn(). Tato metoda je dostupná pouze pro objekty Array.
Následující příklad reviduje pole poets tak, že každý prvek je objekt namísto řetězec. Každý objekt obsahuje jak
příjmení básníka, tak datum jeho narození.
var poets:Array = new Array();
poets.push({name:"Angelou", born:"1928"});
poets.push({name:"Blake", born:"1757"});
poets.push({name:"cummings", born:"1894"});
poets.push({name:"Dante", born:"1265"});
poets.push({name:"Wang", born:"701"});
Metodu sortOn() můžete použít pro třídění pole dle vlastnosti born. Metoda sortOn() definuje dva parametry,
fieldName a options. Argument fieldName musí být určen jako řetězec. V následujícím příkladě je metoda
sortOn() volána se dvěma argumenty "born" a Array.NUMERIC. Argument Array.NUMERIC se používá pro zajištění,
že třídění je provedeno číselně a nikoliv abecedně. Toto je dobrou praxí i v případě, kdy všechna čísla mají stejný počet
číslic, protože argument zajistí, že jestliže je později k poli přidáno číslo s méně nebo více číslicemi, bude se třídění i
nadále chovat dle očekávání.
poets.sortOn("born", Array.NUMERIC);
for (var i:int = 0; i < poets.length; ++i)
{
trace(poets[i].name, poets[i].born);
}
/* output:
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
Třídění bez úpravy původního pole (pouze třída Array)
Metody sort() a sortOn() obecně upravují Pole. Jestliže si přejete třídit Pole bez úpravy stávajícího pole, odešlete
konstantu Array.RETURNINDEXEDARRAY jako součást parametru options. Tato možnost nařídí metodě vrátit nové
pole, které odráží třídění a ponechá původní Pole beze změn. Pole vrácené metodami je jednoduché pole čísel indexu,
které odráží nové pořadí třídění a neobsahuje žádné prvky z původního Pole. Například pro třídění pole poets dle
data narození bez úpravy Pole začleňte konstantu Array.RETURNINDEXEDARRAY do argumentu odeslaného pro
parametr options.
Následující příklad uchovává vrácenou informaci indexu v Poli pojmenovaném indices a používá pole indices ve
spojení s nezměněným polem poets pro dosazení básníků v pořadí dle roku narození:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 163
Práce s poli
var indices:Array;
indices = poets.sortOn("born", Array.NUMERIC | Array.RETURNINDEXEDARRAY);
for (var i:int = 0; i < indices.length; ++i)
{
var index:int = indices[i];
trace(poets[index].name, poets[index].born);
}
/* output:
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
Dotazování pole
Čtyři metody třídy Array a Vector - concat(), join(), slice()a toString() - všechny dotazují pole pro informaci,
ale pole nemění. Metody concat() a slice() vrátí nová pole, zatímco metody join() a toString() vrátí řetězce.
Metoda concat() vezme nové pole nebo seznam prvků jako argumenty, zkombinuje je se stávajícím polem a vytvoří
tak pole nové. Metoda slice() má dva parametry, vhodně pojmenované startIndex a endIndex a vrátí nové pole
obsahující kopii prvků „odříznutých“ ze stávajícího pole. Řez začíná u prvku na startIndex a končí u prvku před
endIndex. To přivodí opakování: prvek na endIndex není zahrnut do návratové hodnoty.
Následující příklad používá concat() a slice() pro vytvoření nových polí pomocí prvků jiných polí.
var array1:Array = ["alpha", "beta"];
var array2:Array = array1.concat("gamma", "delta");
trace(array2); // output: alpha,beta,gamma,delta
var array3:Array = array1.concat(array2);
trace(array3); // output: alpha,beta,alpha,beta,gamma,delta
var array4:Array = array3.slice(2,5);
trace(array4); // output: alpha,beta,gamma
Metody join() a toString() můžete použít pro dotazování pole a vrácení svého obsahu jako řetězce. Jestliže pro
metodu join() nejsou použity žádné parametry, chovají se obě dvě metody stejně - vrátí řetězec obsahující čárkou
rozdělený seznam všech prvků v poli. Metoda join() narozdíl od metody toString() přijímá parametr
pojmenovaný delimiter, který vám umožní zvolit symbol, který bude použit jako oddělovač mezi každým
parametrem ve vráceném řetězci.
Následující příklad vytvoří pole nazvané rivers a volá jak metodu join() tak toString() pro vrácení hodnoty v Poli
jako řetězec. Metoda toString() je použita pro vrácení hodnot oddělených čárkou (riverCSV), zatímco metoda
join() se používá pro vrácení hodnot oddělených znakem +.
var rivers:Array = ["Nile", "Amazon", "Yangtze", "Mississippi"];
var riverCSV:String = rivers.toString();
trace(riverCSV); // output: Nile,Amazon,Yangtze,Mississippi
var riverPSV:String = rivers.join("+");
trace(riverPSV); // output: Nile+Amazon+Yangtze+Mississippi
V případě metody join() je třeba upozornit na jeden možný problém a to ten, že jakékoliv vnořené instance Array
nebo Vector jsou vždy vráceny s hodnotami oddělenými čárkami, bez ohledu na to, jaký oddělovač určíte pro hlavní
prvky pole. Viz následující příklad:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 164
Práce s poli
var nested:Array = ["b","c","d"];
var letters:Array = ["a",nested,"e"];
var joined:String = letters.join("+");
trace(joined); // output: a+b,c,d+e
Asociativní pole
Asociativní pole, někdy nazvané křížek nebo mapa, používá pro seřazení uchovaných hodnot namísto číselného
indexu klíče. Každý klíč v asociativním poli je jedinečným řetězcem, který se používá k získání přístupu k uložené
hodnotě. Asociativní pole je instancí třídy Object, což znamená, že každý klíč odpovídá názvu vlastnosti. Asociativní
pole jsou sbírkou párů klíčů a hodnot bez pořadí. Váš kód by neměl předpokládat klíče asociativního pole v určitém
pořadí.
Jazyk ActionScript 3.0 obsahuje také pokročilý typ asociativního pole nazvaný slovník. Slovníky, které jsou instancemi
třídy Dictionary v balíku flash.utils, používají klíče, které mohou mít jakýkoliv datový typ. Jinak řečeno, klíče slovníku
nejsou omezeny na hodnoty typu String.
Asociativní pole s klíči řetězce
Existují dva způsoby k vytvoření asociativních polí v jazyce ActionScript 3.0. Prvním způsobem je použití instance
Object. Pomocí instance Object můžete konkretizovat své pole s literálem objektu. Instance třídy Object, nazvaná také
generický objekt, je co do funkce totožná s asociativním polem. Každý název vlastnosti generického objektu slouží jako
klíč, který poskytuje přístup k uložené hodnotě.
Následující příklad vytvoří asociativní pole nazvané monitorInfo, pomocí literálu objektu inicializuje pole se dvěma
dvojicemi klíče a hodnoty:
var monitorInfo:Object = {type:"Flat Panel", resolution:"1600 x 1200"};
trace(monitorInfo["type"], monitorInfo["resolution"]);
// output: Flat Panel 1600 x 1200
Jestliže nepotřebujete inicializovat pole v čase deklarace, můžete pro vytvoření pole použít konstruktor třídy Object,
viz níže:
var monitorInfo:Object = new Object();
Po vytvoření objektu pomocí buď literálu objektu nebo konstruktoru třídy Object můžete do pole přidat nové hodnoty
pomocí operátoru přístupu k poli ([]) nebo operátoru tečky (.). Následující příklad přidá dvě nové hodnoty
domonitorArray:
monitorInfo["aspect ratio"] = "16:10"; // bad form, do not use spaces
monitorInfo.colors = "16.7 million";
trace(monitorInfo["aspect ratio"], monitorInfo.colors);
// output: 16:10 16.7 million
Všimněte si, že klíč pojmenovaný aspect ratio obsahuje znak mezery. To je možné s operátorem přístupu k poli
([]), ale jestliže pokus provedete s operátorem tečky, dojde k vygenerování chyby. Použití mezer v názvech klíčů se
doporučuje.
Druhý způsob vytvoření asociativního pole je použít konstruktor třídy Array (nebo konstruktor libovolné dynamické
třídy) a poté použít buď operátor přístupu k poli ([]) nebo operátor tečky (.) pro přidání dvojic klíče a hodnoty k poli.
Jestliže své asociativní pole prohlásíte za typ Array, nemůžete použít objekt literálu k inicializaci pole. Následující
příklad vytvoří asociativní pole nazvané monitorInfo pomocí konstruktoru Array a přidá klíč nazvaný type a klíč
nazvaný resolution, spolu s jejich hodnotami:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 165
Práce s poli
var monitorInfo:Array = new Array();
monitorInfo["type"] = "Flat Panel";
monitorInfo["resolution"] = "1600 x 1200";
trace(monitorInfo["type"], monitorInfo["resolution"]);
// output: Flat Panel 1600 x 1200
Použití konstruktoru třídy Array pro vytvoření asociativního pole neposkytuje žádnou výhodu. Vlastnost
Array.length nebo žádnou z metod třídy Array nemůžete použít s asociativními poli, i v případě, že použijete
konstruktor Array nebo datový typ Array. Použití konstruktoru třídy Array je lépe ponechat pro vytváření
indexovaných polí.
Asociativní pole s klíči objektu (Slovníky)
Třídu Dictionary můžete použít pro vytvoření asociativního pole, které používá objekty pro klíče spíše než pro řetězce.
Taková pole se někdy nazývají slovníky, křížky nebo mapy. Zvažte například aplikaci, která určuje umístění objektu
Sprite na základě jeho asociace s určitým kontejnerem. Objekt Dictionary můžete použít pro mapování každého
objektu Sprite ke kontejneru.
Následující kód vytvoří tři instance třídy Sprite, které slouží jako klíče pro objekt Dictionary. Každému klíči je
přiřazena hodnota buď GroupA nebo GroupB. Hodnota může mít jakýkoliv datový typ, ale v tomto příkladě jsou
GroupA i GroupB instancemi třídy Object. Následně můžete získat přístup k hodnotě přiřazené ke každému klíči s
operátorem přístupu k poli ([]), viz následující kód:
import flash.display.Sprite;
import flash.utils.Dictionary;
var groupMap:Dictionary = new Dictionary();
// objects to use
var spr1:Sprite =
var spr2:Sprite =
var spr3:Sprite =
as keys
new Sprite();
new Sprite();
new Sprite();
// objects to use as values
var groupA:Object = new Object();
var groupB:Object = new Object();
// Create new key-value pairs in dictionary.
groupMap[spr1] = groupA;
groupMap[spr2] = groupB;
groupMap[spr3] = groupB;
if (groupMap[spr1]
{
trace("spr1 is
}
if (groupMap[spr2]
{
trace("spr2 is
}
if (groupMap[spr3]
{
trace("spr3 is
}
== groupA)
in groupA");
== groupB)
in groupB");
== groupB)
in groupB");
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 166
Práce s poli
Iterace s klíči objektu
Obsahem objektu Dictionary můžete iterovat buď pomocí smyčkyfor..in nebo smyčky for each..in smyčka.
Smyčka for..in vám umožňuje iteraci na základě klíčů, zatímco smyčkafor each..in umožňuje iteraci na základě
hodnot přiřazených ke každému klíči.
Použijte smyčku for..in pro přímý přístup ke klíčům objektu Dictionary. K hodnotám objektu Dictionary lze také
získat přístup pomocí operátora přístupu k poli ([]). Následující kód používá předchozí příklad slovníku groupMap a
ukazuje tak, jak iterovat skrze objekt Dictionary se smyčkou for..in:
for (var key:Object in groupMap)
{
trace(key, groupMap[key]);
}
/* output:
[object Sprite] [object Object]
[object Sprite] [object Object]
[object Sprite] [object Object]
*/
Použijte smyčku for each..in pro přímý přístup k hodnotám objektu Dictionary. Následující kód také používá
slovník groupMap a ukazuje tak, jak iterovat skrze objekt Dictionary se smyčkou for each..in:
for each (var item:Object in groupMap)
{
trace(item);
}
/* output:
[object Object]
[object Object]
[object Object]
*/
Klíče objektu a správa paměti
Adobe® Flash® Player a Adobe® AIR™ používají systém pro čištění volnění paměti pro obnovení paměti, která již není
používaná. Jestliže objekt nemá žádné reference, které by k němu ukazovaly, stává se objekt vhodným pro čištění
uvolněné paměti a paměť je obnovena při příštím provedení čištění uvolněné paměti. Následující kód například
vytvoří nový objekt a přiřadí referenci objektu k proměnné myObject:
var myObject:Object = new Object();
Jestliže na daný objekt existuje reference, systém čištění uvolněné paměti neobnoví paměť, kterou objekt zabírá. Jestliže
je hodnota myObject změněna tak, že ukazuje na odlišný objekt nebo je nastavena na hodnotu null, paměť využívaná
původním objektem se stává vhodnou pro čištění uvolněné paměti, ale pouze pokud na původní objekt neexistují
žádné reference.
Jestliže používáte myObject jako klíč v objektu Dictionary, vytváříte na původní objekt jinou referenci. Například
následující kód vytvoří dvě reference na objektu - proměnnou myObject a klíč v objektu myMap:
import flash.utils.Dictionary;
var myObject:Object = new Object();
var myMap:Dictionary = new Dictionary();
myMap[myObject] = "foo";
Aby byl objekt odkazovaný myObject vhodný pro čištění uvolněné paměti, musíte odstranit všechny reference, které
jsou s ním spojené. V tomto případě musíte změnit hodnotu myObject a odstranit klíč myObjectz myMap, viz
následující kód:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 167
Práce s poli
myObject = null;
delete myMap[myObject];
Alternativně můžete použít parametr useWeakReference konstruktoru Dictionary pro označení všech klíčů slovníku
jako slabé reference. Systém pro čištění uvolněné paměti ignoruje slabé reference, což znamená, že objekt, který má
pouze slabé reference je vhodný pro čištění uvolněné paměti. V následujícím kódu například není třeba odstranit klíč
myObject z myMap, aby byl objekt označen jako vhodný pro čištění uvolněné paměti:
import flash.utils.Dictionary;
var myObject:Object = new Object();
var myMap:Dictionary = new Dictionary(true);
myMap[myObject] = "foo";
myObject = null; // Make object eligible for garbage collection.
Vícedimenzionální pole
Vícedimenzionální pole obsahují jiná pole jako prvky. Představte si například seznam úloh, který je uložený jako
indexované pole řetězců:
var tasks:Array = ["wash dishes", "take out trash"];
Jestliže si přejete uložit samostatný seznam úloh pro každý den v týdnu, můžete vytvořit vícedimenzionální pole s
jedním prvkem pro každý den v týdnu. Každý prvek obsahuje indexované pole, podobné poli tasks, které ukládá
seznam úloh. Ve vícedimenzionálních polích můžete použít libovolnou kombinaci indexovaných nebo asociovaných
polí. Příklady v následující části používají buď dvě indexovaná pole nebo asociativní pole indexovaných polí. Další
kombinace můžete zkusit jako cvičení.
Dvě indexovaná pole
Jestliže používáte dvě indexovaná pole, můžete výsledek zobrazit jako tabulku nebo pracovní formulář. Prvky prvního
pole reprezentují řádky tabulky, zatímco prvky druhého pole reprezentují sloupce.
Například následující vícedimenzionální pole používá dvě indexovaná pole pro sledování seznamů stop pro každý den
v týdnu. První pole, masterTaskList, je vytvořeno pomocí konstruktoru třídy Array. Každý prvek pole představuje
den v týdnu, kde index 0 představuje pondělí a index 6 představuje neděli. Tyto prvky si můžete představit jako řádky
v tabulce. Seznam úloh pro každý den můžete vytvořit přiřazením literálu pole ke každému ze sedmi prvků, které
vytvoříte v poli masterTaskList. Literál pole představuje sloupce v tabulce.
var masterTaskList:Array = new Array();
masterTaskList[0] = ["wash dishes", "take out trash"];
masterTaskList[1] = ["wash dishes", "pay bills"];
masterTaskList[2] = ["wash dishes", "dentist", "wash dog"];
masterTaskList[3] = ["wash dishes"];
masterTaskList[4] = ["wash dishes", "clean house"];
masterTaskList[5] = ["wash dishes", "wash car", "pay rent"];
masterTaskList[6] = ["mow lawn", "fix chair"];
K jednotlivým položkám na jakémkoliv seznamu úloh můžete získat přístup pomocí operátoru přístupu k poli ([]).
První sada závorek představuje den v týdnu a druhá sada závorek představuje seznam úloh pro daný den. Například
pro získání druhé úlohy ze seznamu středy nejprve použijte index 2 pro středu a poté použijte index 1 pro druhou
úlohu v seznamu.
trace(masterTaskList[2][1]); // output: dentist
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 168
Práce s poli
Pro získání první úlohy ze seznamu neděle použijte index 6 pro neděli a index 0 pro první úlohu na seznamu.
trace(masterTaskList[6][0]); // output: mow lawn
Asociativní pole s indexovaným polem
Aby bylo získání přístupu k jednotlivým polím snadnější, můžete asociativní pole použít pro dny v týdny a indexovaná
pole pro seznamy úloh. Použití asociativního pole vám umožňuje použít syntaxi tečky při odkazování na určitý den v
týdnu, ale to za cenu vyššího zpracovávání v době běhu pro přístup ke každému prvku asociativního pole. Následující
příklad používá asociativní pole jako základ seznamu úloh, s dvojicí klíče a hodnoty pro každý den v týdnu:
var masterTaskList:Object = new Object();
masterTaskList["Monday"] = ["wash dishes", "take out trash"];
masterTaskList["Tuesday"] = ["wash dishes", "pay bills"];
masterTaskList["Wednesday"] = ["wash dishes", "dentist", "wash dog"];
masterTaskList["Thursday"] = ["wash dishes"];
masterTaskList["Friday"] = ["wash dishes", "clean house"];
masterTaskList["Saturday"] = ["wash dishes", "wash car", "pay rent"];
masterTaskList["Sunday"] = ["mow lawn", "fix chair"];
Díky syntaxi tečky bude kód snáze čten a budete se tak moct vyhnout více sadám závorek.
trace(masterTaskList.Wednesday[1]); // output: dentist
trace(masterTaskList.Sunday[0]);// output: mow lawn
Seznamem úloh můžete iterovat pomocí smyčky for..in, ale pro přístup k hodnotě přiřazené každému klíči musíte
použít operátor přístupu k poli ([]) namísto syntaxe tečky. Protože masterTaskList je asociativní pole, prvky nejsou
nezbytně získány v pořadí, které můžete očekávat, viz následující příklad:
for (var day:String in masterTaskList)
{
trace(day + ": " + masterTaskList[day])
}
/* output:
Sunday: mow lawn,fix chair
Wednesday: wash dishes,dentist,wash dog
Friday: wash dishes,clean house
Thursday: wash dishes
Monday: wash dishes,take out trash
Saturday: wash dishes,wash car,pay rent
Tuesday: wash dishes,pay bills
*/
Klonování polí
Třída Array nemá žádnou zabudovanou metodu pro kopírování polí. Mělkoukopii pole můžete vytvořit voláním
metody concat() nebo slice() bez argumentů. V mělké kopii, jestliže má původní pole prvky, které jsou objekty,
jsou zkopírovány pouze reference na objekty, nikoliv samotné objekty. Kopie ukazuje na stejné objekty jako původní
pole. Jakékoliv změny provedené v objektech se odrazí v obou polích.
V hluboké kopii jsou jakékoliv objekty nalezené v původním poli také zkopírovány, takže nové pole neukazuje na stejné
objekty jako pole původní. Hluboké kopírování vyžaduje více než jeden řádek kódu, což obvykle volá po vytvoření
funkce. Taková funkce by měla být vytvořena jako globální funkce utility nebo jako metoda podtřídy Array.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 169
Práce s poli
Následující příklad definuje funkci pojmenovanou clone(), která provádí hluboké kopírování. Algoritmus je
vypůjčen z běžné programovací techniky jazyka Java. Funkce vytvoří hlubokou kopii serializací pole do instance třídy
ByteArray a poté načte pole zpět do nového pole. Tato funkce přijímá objekt a může být použita s indexovanými poli
i asociativními poli, viz následující kód:
import flash.utils.ByteArray;
function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
Pokročilá témata
Rozšíření třídy Array
Třída Array je jednou z mála základních tříd, která není koncová. To znamená, že můžete vytvořit svoji vlastní
podtřídu třídy Array. Tato část poskytuje příklad způsobu vytvoření podtřídy třídy Array a uvádí některé z problémů,
které mohou během procesu vzniknout.
Jak již bylo zmíněno dříve, pole v jazyku ActionScript nejsou typová, ale můžete vytvořit podtřídu třídy Array, která
přijímá prvky pouze určitého datového typu. Příklad v následujících částech definuje podtřídy třídy Array
pojmenované TypedArray, které omezují její prvky na hodnoty datového typu určeného v prvním parametru. Třída
TypedArray je uvedena pouze jako příklad rozšíření třídy Array a nemusí být vhodná pro účely produkování, a to z
několika důvodů. Zaprvé, kontrola typu probíhá v době běhu spíše než v době kompilace. Zadruhé, jestliže metoda
TypedArray nalezne nesoulad, bude nesoulad ignorován a nebude vygenerována žádná výjimka, ačkoliv mohou být
metody snadno upraveny tak, aby výjimky vygenerovaly. Zatřetí, třída nemůže zabránit použití operátoru přístupu k
poli ve vložení hodnot libovolného typu do pole. Začtvrté, styl kódování upřednostňuje jednoduchost před
optimalizací výkonu.
Poznámka: Zde popsanou techniku můžete použít k vytvoření typovaného pole. Lepším přístupem je nicméně použít
objekt Vector. Instance Vector je pravé typované pole a na rozdíl od třídy Array nebo jakékoliv podtřídy poskytuje lepší
výkon a jiné výhody. Účelem této diskuse je ukázat způsob vytvoření podtřídy Array.
Deklarování podtřídy
Pomocí klíčového slova extends určíte, že třída je podtřídou třídy Array. Podtřída třídy Array by měla použít atribut
dynamic, stejně jako třída Array. V opačném případě nebude vaše podtřída pracovat správně.
Následující kód ukazuje definici třídy TypedArray obsahující konstantu, která bude obsahovat datový typ, metodu
konstruktoru a čtyři metody, které jsou schopné přidat prvky do pole. V tomto příkladě je u každé metody vynechán
kód, ale je vymezen a plně vysvětlen v částech uvedených níže:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 170
Práce s poli
public dynamic class TypedArray extends Array
{
private const dataType:Class;
public function TypedArray(...args) {}
AS3 override function concat(...args):Array {}
AS3 override function push(...args):uint {}
AS3 override function splice(...args) {}
AS3 override function unshift(...args):uint {}
}
Všechny čtyři potlačené metody používají jmenný prostor AS3 namísto atributu public, protože tento příklad
předpokládá, že je volba kompilátoru -as3nastavena na hodnotu true a volba kompilace -es je nastavena na false.
Jedná se o výchozí nastavení produktu Adobe Flex Builder 3 a Adobe® Flash® CS4 Professional. Více informací
naleznete v části „Jmenný prostor AS3“ na stránce 120.
Jste-li pokročilý vývojář, který upřednostňuje použití dědičnosti prototypu, můžete provést dvě menší změny třídy
TypedArray a přikázat jí kompilovat s volbou kompilace -es nastavenou na true. Nejprve odstraňte všechny výskyty
atributu override a nahraďte jmenný prostor AS3 atributem public. Zadruhé, nahraďte Array.prototype pro
všechny čtyři výskyty super.
Konstruktor TypedArray
Konstruktor podtřídy představuje zajímavou otázku, protože musí přijmout seznam argumentů libovolné délky.
Otázka se týká způsobu odeslání argumentů na superkonstruktor pro vytvoření pole. Jestliže předáte seznam
argumentů jako pole, superkonstruktor jej bude považovat za jediný argument typu Array a výsledné pole je vždy o 1
prvek delší. Tradičním způsobem zpracovávání procházení seznamů argumentů je použití metody
Function.apply(), která bere pole argumentů jako svůj druhý parametr, ale převádí jej na seznam argumentů při
provádění funkce. Metodu Function.apply() nelze bohužel použít s konstruktory.
Jedinou zbývající možností je znovu vytvořit logiku konstruktoru Array v konstruktoru TypedArray. Následující kód
ukazuje algoritmus použitý v konstruktoru třídy Array, který můžete znovu použít v konstruktoru podtřídy Array:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 171
Práce s poli
public dynamic class Array
{
public function Array(...args)
{
var n:uint = args.length
if (n == 1 && (args[0] is Number))
{
var dlen:Number = args[0];
var ulen:uint = dlen;
if (ulen != dlen)
{
throw new RangeError("Array index is not a 32-bit unsigned integer ("+dlen+")");
}
length = ulen;
}
else
{
length = n;
for (var i:int=0; i < n; i++)
{
this[i] = args[i]
}
}
}
}
Konstruktor TypedArray sdílí většinu kódu z konstruktoru Array, pouze se čtyřmi změnami kódu. Zaprvé, seznam
parametrů zahrnuje nový vyžadovaný parametr typu Class, který umožňuje specifikaci datového typu pole. Zadruhé,
datový typ předaný konstruktoru je přiřazen proměnné dataType. Zatřetí, v příkazu else je hodnota vlastnosti
length přiřazena po smyčce for, takže length zahrnuje pouze argumenty, které mají správný typ. Začtvrté, tělo
smyčky for používá potlačenou verzi metody push(), takže jsou do pole přidány pouze argumenty správného
datového typu. Následující příklad ukazuje funkci TypedArray.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 172
Práce s poli
public dynamic class TypedArray extends Array
{
private var dataType:Class;
public function TypedArray(typeParam:Class, ...args)
{
dataType = typeParam;
var n:uint = args.length
if (n == 1 && (args[0] is Number))
{
var dlen:Number = args[0];
var ulen:uint = dlen
if (ulen != dlen)
{
throw new RangeError("Array index is not a 32-bit unsigned integer ("+dlen+")")
}
length = ulen;
}
else
{
for (var i:int=0; i < n; i++)
{
// type check done in push()
this.push(args[i])
}
length = this.length;
}
}
}
Potlačené metody TypedArray
Třída TypedArray potlačí čtyři metody třídy Array, které mohou přidat prvky do pole. V každém případě přidá
potlačená metoda kontrolu typu, která zabrání předání prvků bez správného datového typu. Následně každá metoda
volá verzi nadřazené třídy sebe sama.
Metoda push() iteruje skrze seznam argumentů se smyčkou for..in a na každém argumentu provádí kontrolu typu.
Jakýkoliv argument, který nemá správný typ, je odstraněn z pole args pomocí metody splice(). Po ukončení smyčky
for..in obsahuje pole args pouze hodnoty typudataType. Verze nadřazené třídy push()je poté volána s
aktualizovaným polem args, viz následující příklad:
AS3 override function push(...args):uint
{
for (var i:* in args)
{
if (!(args[i] is dataType))
{
args.splice(i,1);
}
}
return (super.push.apply(this, args));
}
Metoda concat() vytvoří přechodnou třídu TypedArray pojmenovanou passArgs pro uložení argumentů, které
projdou kontrolou typu. To umožní opětovné použití kódu kontroly typu, který existuje v metodě push(). Smyčka
for..in iteruje skrze pole args a na každém argumentu volá metodu push(). Protože je passArgs typováno jako
TypedArray, bude provedena verze TypedArray metody push(). Metoda concat() poté volá verzi své vlastní
nadřazené třídy, viz následující příklad:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 173
Práce s poli
AS3 override function concat(...args):Array
{
var passArgs:TypedArray = new TypedArray(dataType);
for (var i:* in args)
{
// type check done in push()
passArgs.push(args[i]);
}
return (super.concat.apply(this, passArgs));
}
Metoda splice() vezme libovolný seznam argumentů, ale první dva argumenty se vždy vztahují k číslu indexu a
počtu prvků, které mají být odstraněny. To je důvod, proč potlačená metoda splice() provádí kontrolu typu pouze
pro prvky pole args v poloze indexu 2 nebo vyšší. Jedním bodem zájmu je kód, který se zdá být rekurzivním voláním
splice() uvnitř smyčky for, ale nejedná se o rekurzivní volání, protože args je typem třídy Array, nikoliv
TypedArray, což znamená, že volání args.splice() je voláním verze nadřazené třídy metody. Po ukončení smyčky
for..in obsahuje pole args pouze hodnoty se správným typem v poloze indexu 2 nebo vyšší a metoda splice() volá
verzi své vlastní nadřazené třídy, viz.následující kód:
AS3 override function splice(...args):*
{
if (args.length > 2)
{
for (var i:int=2; i< args.length; i++)
{
if (!(args[i] is dataType))
{
args.splice(i,1);
}
}
}
return (super.splice.apply(this, args));
}
Metoda unshift(), která přidává prvky na začátek pole, také přijímá libovolný seznam argumentů. Potlačená metoda
unshift() používá algoritmus velice podobný algoritmu používaného metodou push(), viz následující příklad kódu:
AS3 override function unshift(...args):uint
{
for (var i:* in args)
{
if (!(args[i] is dataType))
{
args.splice(i,1);
}
}
return (super.unshift.apply(this, args));
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 174
Práce s poli
Příklad: PlayList
Příklad PlayList ukazuje techniky pro práci s poli v kontextu aplikace seznamu přehrávání hudby, která spravuje
seznam písní. Tyto techniky jsou následující:
• Vytvoření indexovaného pole
• Přidávání položek do indexovaného pole
• Třídění pole objektů podle odlišných vlastností, pomocí odlišných voleb třídění
• Převádění pole na řetězec oddělený znakem.
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace PlayList lze nalézt ve složce Samples/PlayList. Aplikace sestává z následujících souborů:
Soubor
Popis
PlayList.mxml
Hlavní soubor aplikace v programu Flash (FLA) nebo Flex (MXML).
nebo
PlayList.fla
com/example/programmingas3/playlist/PlayList.as
Třída, která zastupuje seznam skladeb. K uložení seznamu používá
pole a spravuje pořadí položek tohoto seznamu.
com/example/programmingas3/playlist/Song.as
Objekt hodnoty představující informaci o jediné písni. Položky,
které jsou spravovány třídou PlayList, jsou instancemi třídy Song.
com/example/programmingas3/playlist/SortProperty.as
Pseudo-vyčíslení, jehož dostupné hodnoty představují vlastnosti
třídy Song, dle kterých lze třídit seznam objektů Song.
Přehled třídy PlayList
Třída PlayList spravuje sadu objektů Song. Má veřejné metody s funkcemi pro přidání písně do seznamu přehrávání
(metoda addSong()) a třídění písní v seznamu (metody sortList()). Daná třída také zahrnuje vlastnost
přístupového mechanismu určenou pouze ke čtení songList, která poskytuje přístup k vlastnímu seznamu písní v
seznamu přehrávání. Třída PlayList interně uchovává záznamy svých písní pomocí soukromé proměnné Array:
public class PlayList
{
private var _songs:Array;
private var _currentSort:SortProperty = null;
private var _needToSort:Boolean = false;
...
}
Vedle proměnné třídy Array _songs, která je používána třídou PlayList pro uchovávání záznamů svého seznamu
písní, uchovávají dvě další soukromé proměnné záznam toho, zda je třeba seznam třídit (_needToSort) a podle které
vlastnosti je seznam písní v daný čas tříděn (_currentSort).
Jako u všech objektů je prohlášení instance třídy Array pouze polovinou procesu vytváření třídy Array. Před získáním
přístupu k vlastnostem nebo metodám instance třídy Array musí být konkretizováno, která z nich je provedena v
konstruktoru třídy PlayList.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 175
Práce s poli
public function PlayList()
{
this._songs = new Array();
// Set the initial sorting.
this.sortList(SortProperty.TITLE);
}
První řádek konstruktoru konkretizuje proměnnou _songs a ta je poté připravena k použití. Dále je volána metoda
sortList() pro nastavení počáteční metody, podle které má být provedeno třídění.
Přidání písně do seznamu
Jestliže uživatel přidá do aplikace novou píseň, kód v záznamu dat vytvoří volání metody třídy PlayList addSong().
/**
* Adds a song to the playlist.
*/
public function addSong(song:Song):void
{
this._songs.push(song);
this._needToSort = true;
}
Uvnitř addSong() je volána metoda pole _songs nazvaná push() přidávající objekt Song, který byl předán do
addSong() jako nový prvek v daném poli. V případě metody push() je nový prvek přidán na konec pole, bez ohledu
na třídění, které mohlo být použito již dříve. To znamená, že po volání metody push() již seznam písní
pravděpodobně nebude tříděn správně, takže proměnná _needToSort je nastavena na hodnotu true. Teoreticky by
mohla být metoda sortList() volána okamžitě a nebylo by tak třeba uchovávat záznam toho, zda je seznam tříděn
či nikoliv. V praxi nicméně není třeba třídit seznam písní až do okamžiku těsně před jeho získáním. Rozlišením operací
třídění aplikace neprovede třídění, které není nutné, jestliže je například několik tříd přidáno do seznamu před jeho
získáním.
Třídění seznamu písní
Protože jsou instance třídy Song spravované seznamem přehrávání složitými objekty, mohou si uživatelé aplikace přát
třídit seznam přehrávání podle různých vlastností, například názvu písně nebo roku vydání. V aplikaci PlayList má
úloha třídění seznamu písní tři části: identifikace vlastnosti, podle které by měl být seznam tříděn, určení voleb třídění,
které je třeba použít při třídění dané vlastnosti a samotné provedení operace třídění.
Vlastnosti pro třídění
Objekt Song uchovává záznam o několika vlastnostech, včetně názvu písně, interpreta, roku vydání, názvu souboru a
uživatelem vybraných skupiny žánrů, do které daná třída patří. Z výše uvedených vlastností mají pouze první tři
praktické využití při třídění. Pro usnadnění práce vývojářů obsahuje daný příklad třídu SortProperty, která se chová
jako vyčíslení s hodnotami představujícími vlastnosti dostupné pro třídění.
public static const TITLE:SortProperty = new SortProperty("title");
public static const ARTIST:SortProperty = new SortProperty("artist");
public static const YEAR:SortProperty = new SortProperty("year");
Třída SortProperty obsahuje tři konstanty TITLE, ARTIST a YEAR a každá z nich uchovává String obsahující skutečný
název vlastnosti přidružené třídy Song, kterou lze použít pro třídění. Ve zbytku kódu, kdykoliv je určena vlastnost
třídění, je třídění provedeno pomocí člena vyčíslení. Například v konstruktoru PlayList je seznam zpočátku tříděn
voláním metody sortList(), a to následovně:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 176
Práce s poli
// Set the initial sorting.
this.sortList(SortProperty.TITLE);
Protože je vlastnost pro třídění určena jako SortProperty.TITLE, jsou písně tříděny pole svého názvu.
Třídění dle vlastnosti a určení voleb třídění
Práce vlastního třídění seznamu písní je provedena třídou PlayList v metodě sortList(), a to následovně:
/**
* Sorts the list of songs according to the specified property.
*/
public function sortList(sortProperty:SortProperty):void
{
...
var sortOptions:uint;
switch (sortProperty)
{
case SortProperty.TITLE:
sortOptions = Array.CASEINSENSITIVE;
break;
case SortProperty.ARTIST:
sortOptions = Array.CASEINSENSITIVE;
break;
case SortProperty.YEAR:
sortOptions = Array.NUMERIC;
break;
}
// Perform the actual sorting of the data.
this._songs.sortOn(sortProperty.propertyName, sortOptions);
// Save the current sort property.
this._currentSort = sortProperty;
// Record that the list is sorted.
this._needToSort = false;
}
Během třídění podle názvu nebo interpreta je vhodné třídit abecedně, ale při třídění na základě roku je logičtější
provést číselné třídění. Příkaz switch se používá pro definování vhodné volby třídění, uložené v proměnné
sortOptions, podle hodnoty určené v parametru sortProperty. Zde jsou opět pojmenované členy vyčíslení použity
pro rozlišení mezi vlastnostmi, spíše než pevně kódované hodnoty.
S určenou vlastností třídění a volbami třídění je pole _songs vlastně tříděno voláním své metody sortOn()a předáním
těchto dvou hodnot jako parametrů. Aktuální vlastnost třídění je zaznamenána stejně jako fakt, že daná píseň je
aktuálně tříděna.
Kombinování prvků pole do řetězce odděleného znakem
Vedle používání pole k uchovávání seznamu písní ve třídě PlayList, jsou v tomto příkladě pole také použita ve třídě
Song pro usnadnění správy seznamu žánrů, do kterého daná píseň patří. Věnujte pozornost tomuto výstřižku z
definice třídy Song:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 177
Práce s poli
private var _genres:String;
public function Song(title:String, artist:String, year:uint, filename:String, genres:Array)
{
...
// Genres are passed in as an array
// but stored as a semicolon-separated string.
this._genres = genres.join(";");
}
Při vytváření nové instance Song je parametr genres používaný pro učení žánru (nebo žánrů), do kterého daná píseň
patří, definován jako instance třída Array. Je proto výhodné seskupit více žánrů dohromady do jediné proměnné,
kterou lze předat konstruktoru. Nicméně třída Song interně uchovává žánry v soukromé proměnné _genres jako
instanci řetězce odděleného středníkem. Parametr Array je převeden do řetězce odděleného středníkem voláním své
metody join() s hodnotou řetězce literálu ";" jako určeného oddělovače.
Dle stejného důkazu mechanismy přístupu genres umožňují nastavení nebo dosazení žánrů jako třídu Array:
public function get genres():Array
{
// Genres are stored as a semicolon-separated String,
// so they need to be transformed into an Array to pass them back out.
return this._genres.split(";");
}
public function set genres(value:Array):void
{
// Genres are passed in as an array,
// but stored as a semicolon-separated string.
this._genres = value.join(";");
}
Mechanismus přístupu genresset se chová stejně jako konstruktor; přijímá pole, volá metodu join() a převádí jej
na řetězec oddělený středníkem. Mechanismus přístupu get provede opačnou operaci: volána je metoda proměnné
_genres s názvem split() a rozdělí String do pole hodnot pomocí určeného oddělovače (hodnoty řetězce literálu
";" jako dříve).
178
Kapitola 9: Zpracování chyb
Zpracování chyb znamená, že se do aplikace začlení logika, která zpracuje neboli opraví chybu vygenerovanou buďto
během kompilování aplikace nebo za běhu již zkompilované aplikace. Když aplikace zpracovává chyby, něco se stane
jako odezva na zjištění chyby, na rozdíl od tichého selhání procesu, při němž k této chybě došlo, bez jakékoliv odezvy.
Při správném použití pomáhá zpracování chyb chránit příslušnou aplikaci a její uživatele proti jinak neočekávanému
chování.
Zpracování chyb je však velmi obsáhlá kategorie zahrnující odezvy na různé druhy chyb vyvolaných během
kompilování nebo za běhu. Tato kapitola je zaměřena na zpracování chyb vzniklých za běhu (různých druhů chyb,
které mohou být vygenerovány) a na výhody nového systému zpracování chyb v jazyce ActionScript 3.0. Dále je v této
kapitole vysvětlen postup při implementaci vlastních strategií pro zpracování chyb v příslušné aplikaci.
Základy zpracování chyb
Úvod do zpracování chyb
Chyba chodu programu je porucha, která nastane v kódu jazyka ActionScript a zastaví provádění jeho obsahu v
aplikaci Adobe® Flash® Player nebo Adobe® AIR™. Chcete-li uživatelům zajistit hladké provádění kódu jazyka
ActionScript, musíte ve vlastní aplikaci napsat kód, který chybu zpracuje – opraví ji, obejde ji nebo alespoň uživatele
upozorní, že k ní došlo. Tento proces se nazývá zpracování chyb.
Zpracování chyb je velmi obsáhlá kategorie zahrnující odezvy na různé druhy chyb vyvolaných během kompilování
nebo za běhu. Chyby, k nimž dojde během kompilování, se obvykle snáze identifikují – je nezbytné je opravit, aby bylo
možné dokončit proces vytváření souboru SWF. Tato kapitola se nezabývá chybami kompilace. Další informace o
psaní kódu, který neobsahuje chyby kompilace naleznete v sekcích „Jazyk ActionScript a jeho syntaxe“ na stránce 37a
„Objektově orientované programování v jazyce ActionScript“ na stránce 89. Tato kapitola je zaměřena na chyby chodu
programu.
Chyby chodu programu může být obtížnější zjistit, protože aby k nim vůbec došlo, musí se provádět chybný kód. Máli segment programu několik větví kódu, např. příkaz if..then..else, je zapotřebí otestovat všechny možné
podmínky se všemi možnými vstupními hodnotami, které mohou použít skuteční uživatelé, aby bylo možné potvrdit,
že se v příslušném kódu nevyskytují chyby.
Chyby chodu programu lze rozdělit do dvou kategorií: chyby programu jsou chyby v kódu jazyka ActionScript, např.
určení nesprávného datového typu u parametru metody; logické chyby jsou chyby v logice (kontrola dat a manipulace
s hodnotami) programu, např. použití nesprávného vzorce k výpočtu výše úroků v bankovní aplikaci. Opět platí, že
tyto typy chyb lze často odhalit a opravit předem důkladným otestováním aplikace.
V ideálním případě budou všechny chyby odhaleny a odstraněny z aplikace ještě před jejím vydáním koncovým
uživatelům. Ne všechny chyby je však možné předvídat nebo jim zamezit. Předpokládejme například, že aplikace
jazyka ActionScript načte informace z určitého webového místa, které nemáte pod kontrolou. Pokud se stane, že toto
webové místo nebude k dispozici, nebude se ta část aplikace, která je závislá na těchto externích datech, chovat správně.
K nejdůležitějším aspektům zpracování chyb patří příprava na tyto neznámé případy a jejich postupné zpracování, aby
uživatelé mohli i nadále příslušnou aplikaci používat, nebo alespoň obdrželi přátelskou chybovou zprávu s
vysvětlením, proč aplikace nefunguje.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 179
Zpracování chyb
Chyby chodu programu jsou v jazyce ActionScript vyjádřeny dvěma způsoby:
• Třídy chyb: K celé řadě chyb je přiřazena třída chyb. Když dojde k chybě, aplikace Flash Player nebo Adobe AIR
vytvoří instanci určité třídy chyb, která je přiřazena k této konkrétní chybě. Příslušný kód může použít informace
obsažené v tomto objektu chyby k zajištění vhodné odezvy na chybu.
• Události chyb: Někdy dojde k chybě ve chvíli, kdy by aplikace Flash Player nebo Adobe AIR normálně spustila
událost. V takových případech spustí aplikace Flash Player a Adobe AIR místo toho událost chyby. Stejně jako
ostatní události má i každá událost chyby přiřazenu třídu a aplikace Flash Player a Adobe AIR předávají instanci
této třídy do metod, které jsou přihlášeny k této události chyby.
Chcete-li určit, zda může určitá metoda spustit chybu nebo událost chyby, přečtěte si zadání této metody v Referenční
příručce jazyka ActionScript 3.0 a jeho součástí.
Běžné úlohy zpracování chyb
Zde jsou uvedeny nejběžnější úlohy týkající se chyb, které může být zapotřebí provést u příslušného kódu:
• Psaní kódu pro zpracování chyb
• Testování výskytu, zachycení a opětné vyvolání chyb
• Definování vlastní třídy chyb
• Reagování na události chyb a stavů
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Asynchronní: Příkaz programu, např. volání metody, který nezajistí okamžitý výsledek. Místo toho poskytne
výsledek (nebo chybu) ve formě události.
• Zachycení: Když dojde k výjimce (nebo k chybě chodu programu) a příslušný kód si výjimku uvědomí, říká se, že
kód výjimku zachytí. Jakmile je výjimka zachycena, přestanou aplikace Flash Player a Adobe AIR upozorňovat
zbývající kód jazyka ActionScript na tuto výjimku.
• Ladicí verze: Speciální verze aplikace Flash Player nebo Adobe AIR (ADL) obsahující kód pro upozornění uživatelů
na chyby chodu programu. Ve standardní verzi aplikace Flash Player nebo Adobe AIR (kterou má většina
uživatelů) se chyby, jež nejsou zpracovány kódem jazyka ActionScript, ignorují. V ladicích verzích (které jsou
součástí aplikací Adobe Flash CS4 Professional a Adobe Flex) se zobrazí výstražná zpráva, když dojde k výskytu
nezpracovávané chyby.
• Výjimka: Chyba, k níž dojde za běhu programu, nebo kterou prostředí běhu programu (tj. Flash Player nebo Adobe
AIR) nedokáže samostatně vyřešit.
• Opětné vyvolání: Když kód výjimku zachytí, aplikace Flash Player nebo Adobe AIR již neupozorňuje ostatní
objekty na tuto výjimku. Pokud je důležité, aby byly ostatní objekty na výjimku upozorněny, musí ji kód znovu
vyvolat a tím znovu spustit proces upozornění.
• Synchronní: Příkaz programu, např. volání metody, který zajistí okamžitý výsledek (neboli okamžitě vyvolá chybu),
což znamená, že tuto odezvu je možné použít ve stejném bloku kódu.
• Vyvolání: Upozornění aplikace Flash Player nebo Adobe AIR (a následkem toho i upozornění ostatních objektů a
kódu jazyka ActionScript), že došlo k chybě, se nazývá vyvolání chyby.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 180
Zpracování chyb
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. V
podstatě všechny výpisy kódů uvedené v této kapitole zahrnují příslušné volání funkce trace(). Návod na vyzkoušení
kódů uvedených v této kapitole:
1 Vytvořte prázdný dokument Flash.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
Výsledky funkcí trace() uvedených kódů uvidíte v panelu Výstup.
Některé výpisy kódů uvedené dále jsou složitější a jsou napsány jako třída. Postup při testování těchto příkladů:
1 Vytvořte prázdný dokument Flash a uložte ho ve svém počítači.
2 Vytvořte nový soubor ActionScript a uložte ho do stejného adresáře jako dokument Flash. Název souboru by měl
být stejný jako název třídy ve výpisu kódu. Jestliže například výpis kódu definuje třídu s názvem ErrorTest, použijte
k uložení souboru ActionScript název ErrorTest.as.
3 Zkopírujte výpis kódu do souboru ActionScript a soubor uložte.
4 V dokumentu Flash klepněte na prázdnou část Plochy nebo pracovní oblasti a aktivujte Inspektor vlastností
dokumentu.
5 V Inspektoru vlastností zadejte do pole Třída dokumentu název třídy ActionScript vykopírovaný z textu.
6 Spusťte program pomocí volby Ovládání > Testovat film.
Výsledky příkladu se zobrazí v panelu Výstup (pokud je v příkladu použita funkce trace()) nebo v textovém poli
vytvořeném kódem příkladu.
Tyto postupy pro testování vzorových výpisů kódů jsou podrobněji popsány v sekci „Testování příkladů kódu v této
kapitole“ na stránce 34.
Typy chyb
Při vyvíjení a spouštění aplikací narazíte na různé typy chyb a na terminologii související s chybami. V následujícím
soupise jsou vysvětleny hlavní typy chyb a termíny:
• Chyby kompilace vyvolává kompilátor ActionScript během kompilování kódu. K chybám kompilace dochází, když
potíže se syntaxí v příslušném kódu zamezí vytvoření aplikace.
• Chyby chodu programu vznikají při spuštění aplikace po jejím zkompilování. Chyby chodu programu jsou chyby,
k nimž dochází během přehrávání souboru SWF v aplikaci Adobe Flash Player nebo Adobe AIR. Ve většině případů
je možné chyby chodu programu zpracovat hned při jejich výskytu, nahlásit je uživateli a podniknout kroky pro
zajištění nepřetržitého chodu aplikace. Jestliže se jedná o závažnou chybu, např. nelze navázat připojení ke
vzdálenému webovému místu nebo načíst požadovaná data, je možné prostřednictvím zpracování chyb umožnit
aplikaci postupné dokončení operace.
• Synchronní chyby jsou chyby chodu programu, k nimž dochází při zavolání funkce – když například zkusíte použít
určitou metodu a argument předaný metodě je neplatný, takže aplikace Flash Player nebo Adobe AIR vyvolá
výjimku. Většina chyb vzniká synchronně – při vykonávání příkazu – a postup řízení ihned přejde k
nejvhodnějšímu příkazu catch.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 181
Zpracování chyb
Následující výpis kódu například vyvolá chybu chodu programu, protože metoda browse() není zavolána před
tím, než se program pokusí odeslat soubor:
var fileRef:FileReference = new FileReference();
try
{
fileRef.upload("http://www.yourdomain.com/fileupload.cfm");
}
catch (error:IllegalOperationError)
{
trace(error);
// Error #2037: Functions called in incorrect sequence, or earlier
// call was unsuccessful.
}
V tomto případě vznikne chyba chodu programu synchronně, neboť aplikace Flash Player zjistila, že metoda
browse() nebyla zavolána před tím, než proběhl pokus o odeslání souboru.
Podrobné informace týkající se zpracování synchronních chyb naleznete v sekci „Zpracování synchronních chyb v
aplikaci“ na stránce 184.
• Asynchronní chyby jsou chyby chodu programu, k nimž dochází na různých místech během chodu programu.
Generují události a zachycují je posluchači událostí. Asynchronní operace je taková, při níž funkce spustí operaci,
ale nečeká na její dokončení. Lze vytvořit posluchače událostí chyb, který počká, až aplikace nebo uživatel zkusí
provést nějakou operaci, a pokud tato operace selže, lze zachytit chybu pomocí posluchače událostí a reagovat na
událost chyby. Posluchač událostí pak zavolá funkci zpracování události, aby vhodným způsobem reagovala na
událost chyby. Zpracování události může například spustit dialogový rámeček, který uživatele vyzve k vyřešení
chyby.
Posuďte výše uvedený příklad synchronní chyby při odesílání souboru. Jestliže před zahájením odesílání souboru
úspěšně zavoláte metodu browse(), aplikace Flash Player odešle několik událostí. Při zahájení odesílání se
například odešle událost open. Po úspěšném dokončení odeslání souboru bude odeslána událost complete.
Vzhledem k tomu, že zpracování chyb je asynchronní (tj. neprobíhá v určitou, známou, předem definovanou
dobu), je třeba poslouchat tyto specifické události pomocí metody addEventListener(), jak je znázorněno v
následujícím kódu:
var fileRef:FileReference = new FileReference();
fileRef.addEventListener(Event.SELECT, selectHandler);
fileRef.addEventListener(Event.OPEN, openHandler);
fileRef.addEventListener(Event.COMPLETE, completeHandler);
fileRef.browse();
function selectHandler(event:Event):void
{
trace("...select...");
var request:URLRequest = new URLRequest("http://www.yourdomain.com/fileupload.cfm");
request.method = URLRequestMethod.POST;
event.target.upload(request.url);
}
function openHandler(event:Event):void
{
trace("...open...");
}
function completeHandler(event:Event):void
{
trace("...complete...");
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 182
Zpracování chyb
Podrobné informace týkající se zpracování asynchronních chyb naleznete v sekci „Reakce na chybové události a
stavy“ na stránce 189.
• Nezachycené výjimky jsou chyby vyvolané bez odpovídající logiky (např. příkazu catch), která by na ně reagovala.
Pokud aplikace vyvolá chybu a na aktuální nebo vyšší úrovni se nenachází žádný příkaz catch nebo metoda
zpracování události vhodná ke zpracování této chyby, je chyba považována za nezachycenou výjimku.
Aplikace Flash Player nezachycené výjimky za běhu standardně ignoruje a zkouší pokračovat v přehrávání, pokud
chyba nezastaví aktuální soubor SWF, protože uživatelé nemusí být nutně schopni chybu sami vyřešit. Proces
ignorování nezachycené chyby se nazývá „tiché selhání“ a může zkomplikovat ladění aplikací. Ladicí verze aplikace
Flash Player reaguje na nezachycenou chybu ukončením aktuálního skriptu a zobrazením nezachycené chyby ve
výstupu příkazu trace nebo zapsáním chybové zprávy do souboru záznamu. Jestliže je objekt výjimky instance
třídy Error nebo některé z jejích podtříd, vyvolá se metoda getStackTrace() a informace sledování zásobníku se
rovněž zobrazí ve výstupu příkazu trace nebo v souboru záznamu. Další informace týkající se použití ladicí verze
aplikace Flash Player naleznete v sekci „Práce s ladicími verzemi aplikací Flash Player a AIR“ na stránce 183.
Zpracování chyb v jazyce ActionScript 3.0
Vzhledem k tomu, že řada aplikací může běžet i bez začlenění logiky pro zpracování chyb, mají vývojáři tendenci
odkládat začlenění zpracování chyb do svých aplikací. Bez zpracování chyb se však může aplikace snadno zastavit nebo
může uživateli zmařit plány, pokud něco nebude fungovat tak, jak má. Jazyk ActionScript 2.0 má třídu Error, ve které
lze do vlastních funkcí začlenit logiku k vyvolání výjimky s určitou zprávou. Jelikož je zpracování chyb velmi důležité
pro vytvoření uživatelsky přívětivé aplikace, zahrnuje jazyk ActionScript 3.0 rozšířenou architekturu k zachycení chyb.
Poznámka: Přestože Referenční příručka jazyka ActionScript 3.0 a jeho komponent dokumentuje výjimky vyvolané
celou řadou metod, nemusí zahrnovat všechny výjimky, které u jednotlivých metod přicházejí v úvahu. Metoda může
vyvolat výjimku kvůli syntaktickým chybám či jiným potížím, jež nejsou v popisu metody explicitně uvedeny, a to i v
případě, že popis zahrnuje výčet některých výjimek, které může metoda vyvolat.
Elementy zpracování událostí v jazyce ActionScript 3.0
Jazyk ActionScript 3.0 obsahuje celou řadu nástrojů pro zpracování chyb, včetně:
• Třídy chyb. Jazyk ActionScript 3.0 zahrnuje široké rozpětí tříd Error k rozšíření rozsahu situací, které mohou
vyprodukovat objekty chyb. Každá třída Error pomáhá aplikaci zpracovat a reagovat na určité chyby, ať už se jedná
o systémové chyby (např. stav MemoryError), chyby v kódování (např. stav ArgumentError), chyby v síťovém
propojení nebo v komunikaci (např. stav URIError) či jiné situace. Další informace o jednotlivých třídách naleznete
v sekci „Porovnání tříd Error“ na stránce 192.
• Méně tichých selhání. V dřívějších verzích aplikace Flash Player se chyby generovaly a hlásily pouze při explicitním
použití příkazu throw. U přehrávače Flash Player verze 9 a pozdější a programu Adobe AIR nativní metody a
vlastnosti jazyka ActionScript vyvolávají chyby chodu programu, díky nimž lze tyto výjimky zpracovat mnohem
efektivněji hned při jejich výskytu a následně na jednotlivé výjimky individuálně reagovat.
• Zobrazení jasných chybových zpráv během ladění. Při použití ladicí verze aplikace Flash Player nebo Adobe AIR se
při potížích s kódem nebo v problematických situacích vygenerují robustní chybové zprávy, pomocí nichž lze
snadno odhalit příčinu selhání určitého bloku kódu. Tím se opravování chyb značně zefektivní. Další informace
naleznete v sekci „Práce s ladicími verzemi aplikací Flash Player a AIR“ na stránce 183.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 183
Zpracování chyb
• Díky přesným chybám se mohou uživatelům za běhu zobrazovat jasné chybové zprávy. V předchozích verzích
aplikace Flash Player vracela metoda FileReference.upload() Booleovskou hodnotu false, pokud bylo volání
metody upload() neúspěšné, což značilo jednu z pěti možných chyb. Jestliže dojde k chybě při volání metody
upload() v jazyce ActionScript 3.0, lze vyvolat jednu ze čtyř specifických chyb, takže se uživatelům mohou
zobrazovat přesnější chybové zprávy.
• Přesnější zpracování chyb. V řadě běžných situací se zobrazují odlišné chyby. V jazyce ActionScript 2.0 má
například před vyplněním objektu FileReference vlastnost name hodnotu null (takže před tím, než bude možné
vlastnost name použít nebo zobrazit, je třeba zajistit její nastavení na jinou hodnotu než null). Pokud se v jazyce
ActionScript 3.0 pokusíte vstoupit do vlastnosti name dříve, než bude vyplněna, vyvolá aplikace Flash Player nebo
AIR chybu IllegalOperationError, která značí, že nebyla nastavena hodnota. Ke zpracování chyby lze použít bloky
try..catch..finally. Další informace naleznete v sekci „Použití příkazů try..catch..finally“ na stránce 184.
• Žádné výrazné zhoršení výkonnosti. Zpracování chyb pomocí bloků try..catch..finally nevyžaduje oproti
předchozím verzím jazyka ActionScript žádné nebo jen minimální zdroje navíc.
• Třída ErrorEvent umožňující vytvoření posluchačů pro specifické události asynchronních chyb. Další informace
naleznete v sekci „Reakce na chybové události a stavy“ na stránce 189.
Strategie zpracování chyb
Dokud aplikace nenarazí na problematický stav, může úspěšně fungovat i v případě, že do příslušného kódu nebude
začleněna logika zpracování chyb. Jestliže však nebudou chyby aktivně zpracovány a v aplikaci dojde k potížím,
uživatelé se nedozví důvod selhání aplikace.
Zpracování chyb je možné v aplikaci řešit několika způsoby. V následujícím výčtu jsou shrnuty tři základní možnosti
zpracování chyb:
• Použití příkazů try..catch..finally . Ty zachytí synchronní chyby hned při jejich výskytu. Příkazy lze vnořit
do hierarchie za účelem zachycení výjimek na různých úrovních provádění kódu. Další informace naleznete v sekci
„Použití příkazů try..catch..finally“ na stránce 184.
• Vytvoření vlastních objektů chyb. Pomocí třídy Error lze vytvořit vlastní objekty chyb sloužící ke sledování
specifických operací v aplikaci, jež nejsou pokryty vestavěnými typy chyb. Potom lze u vlastních objektů chyb
použít příkazy try..catch..finally. Další informace naleznete v sekci „Vytvoření vlastních tříd chyb“ na
stránce 188.
• Vytvoření posluchačů a zpracování událostí k zajištění odezvy na události chyb. Pomocí této strategie lze vytvořit
globální zpracování chyb, které umožní zpracování podobných událostí bez duplikování příliš velké části kódu v
blocích try..catch..finally. U tohoto přístupu je rovněž vyšší pravděpodobnost zachycení asynchronních
chyb. Další informace naleznete v sekci „Reakce na chybové události a stavy“ na stránce 189.
Práce s ladicími verzemi aplikací Flash Player a AIR
Aplikace Adobe poskytuje vývojářům speciální verze aplikací Flash Player a Adobe AIR usnadňující ladění. Kopii
ladicí verze aplikace Flash Player získáte při instalaci softwaru Adobe Flash CS4 Professional nebo Adobe Flex Builder
3. Verzi ladiče také získáte z verze aplikace Adobe AIR, která se nazývá ADL, když nainstalujete některý z těchto
nástrojů nebo jako součást sady SDK aplikace Adobe AIR.
Mezi tím, jakým způsobem označují chyby ladicí verze a standardní verze aplikací Flash Player a Adobe AIR, je velký
rozdíl. Ladicí verze zobrazují typ chyby (např. obecná chyba Error, IOError nebo EOFError), číslo chyby a lidmi
čitelnou chybovou zprávu. Standardní verze zobrazují pouze typ a číslo chyby. Posuďte například následující kód:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 184
Zpracování chyb
try
{
tf.text = myByteArray.readBoolean();
}
catch (error:EOFError)
{
tf.text = error.toString();
}
Kdyby metoda readBoolean() vyvolala v ladicí verzi aplikace Flash Player chybu EOFError, zobrazila by se v
textovém poli tf následující zpráva: „EOFError: Error #2030: End of file was encountered.“
Stejný kód by ve standardní verzi aplikace Flash Player nebo Adobe AIR zobrazil následující text: „EOFError: Error
#2030“.
Za účelem omezení zdrojů informací a velikosti ve standardních verzích na minimum nejsou k dispozici řetězce
chybových zpráv. Číslo chyby lze vyhledat v dokumentaci (přílohy Referenční příručky jazyka ActionScript 3.0 a jeho
komponent) a dát je do vzájemného vztahu s chybovou zprávou. Případně je možné chybu reprodukovat pomocí ladicí
verze aplikace Flash Player nebo AIR a zobrazit celou zprávu.
Zpracování synchronních chyb v aplikaci
Nejběžnějším zpracováním chyb je logika synchronního zpracování chyb, kde se do kódu vkládají příkazy pro
zachycení synchronních chyb za běhu. Při tomto typu zpracování chyb dokáže aplikace zaregistrovat chyby chodu
programu a obnovit svoji činnost, když dojde k selhání funkcí. Logika pro zachycení synchronní chyby zahrnuje
příkazy try..catch..finally, které doslova vyzkouší operaci, zachytí odpověď aplikace Flash Player nebo Adobe
AIR na chybu a nakonec provedou jinou operaci za účelem zpracování neúspěšné operace.
Použití příkazů try..catch..finally
Při práci se synchronními chybami chodu programu použijte příkazy try..catch..finally k zachycení chyb. Když
dojde k chybě chodu programu, aplikace Flash Player nebo Adobe AIR vyvolá výjimku, což znamená, že přeruší
normální provádění kódu a vytvoří speciální objekt typu Error. Objekt Error se pak vyvolá do prvního dostupného
bloku catch.
Příkaz try ohraničuje příkazy, u nichž může docházet k chybám. Příkaz catch se vždy používá s příkazem try. Budeli v některém příkazu v bloku příkazů try zjištěna chyba, provedou se příkazy catch připojené k tomuto příkazu try.
Příkaz finally ohraničuje příkazy, které se provedou bez ohledu na to, zda v bloku try dojde k chybě či nikoliv.
Pokud k žádné chybě nedojde, příkazy uvnitř bloku finally se provedou, jakmile budou dokončeny příkazy bloku
try. V případě výskytu chyby se nejprve provede příslušný příkaz catch, po němž budou následovat příkazy v bloku
finally.
Následující kód ilustruje syntaxi pro použití příkazů try..catch..finally:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 185
Zpracování chyb
try
{
// some code that could throw an error
}
catch (err:Error)
{
// code to react to the error
}
finally
{
// Code that runs whether or not an error was thrown. This code can clean
// up after the error, or take steps to keep the application running.
}
Jednotlivé příkazy catch identifikují určité typy výjimek, který zpracovávají. Příkaz catch může určovat jen třídy
chyb, která jsou podtřídami třídy Error. Jednotlivé příkazy catch se postupně zkontrolují. Provede se pouze první
příkaz catch, který odpovídá vyvolanému typu chyby. Jinými slovy, jestliže se nejprve zkontroluje třída Error vyšší
úrovně a pak podtřída třídy Error, bude odpovídat jen třída Error vyšší úrovně. Tato skutečnost je znázorněna v
následujícím kódu:
try
{
throw new ArgumentError("I am an ArgumentError");
}
catch (error:Error)
{
trace("<Error> " + error.message);
}
catch (error:ArgumentError)
{
trace("<ArgumentError> " + error.message);
}
Předchozí kód zobrazí následující výstup:
<Error> I am an ArgumentError
Aby byla správně zachycena chyba ArgumentError, musí být nejprve uvedeny nejběžnější typy chyb a teprve potom
obecnější typy chyb, jak znázorňuje následující kód:
try
{
throw new ArgumentError("I am an ArgumentError");
}
catch (error:ArgumentError)
{
trace("<ArgumentError> " + error.message);
}
catch (error:Error)
{
trace("<Error> " + error.message);
}
Řada metod a vlastností v rozhraní API aplikace Flash Player vyvolává chyby chodu programu v případě, že během
provádění narazí na chybu. Například metoda close() ve třídě Sound vyvolá chybu IOError, pokud není schopna
zavřít zvukový stream, jak ilustruje následující kód:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 186
Zpracování chyb
var mySound:Sound = new Sound();
try
{
mySound.close();
}
catch (error:IOError)
{
// Error #2029: This URLStream object does not have an open stream.
}
Až se blíže seznámíte s Referenční příručkou jazyka ActionScript 3.0 a jeho komponent, zjistíte, které metody
vyvolávají výjimky, jak je podrobně uvedeno v popisu jednotlivých metod.
Příkaz throw
Aplikace Flash Player a Adobe AIR vyvolávají výjimky, když za běhu narazí na chyby v příslušné aplikaci. Kromě toho
lze výjimky vyvolat explicitně pomocí příkazu throw. Při explicitním vyvolávání chyb Adobe doporučuje vyvolávat
instance třídy Error nebo jejích podtříd. Následující kód znázorňuje příkaz throw, který vyvolá instanci třídy Error
MyErr a případně vyvolá funkci myFunction() jako reakci na vyvolání chyby:
var MyError:Error = new Error("Encountered an error with the numUsers value", 99);
var numUsers:uint = 0;
try
{
if (numUsers == 0)
{
trace("numUsers equals 0");
}
}
catch (error:uint)
{
throw MyError; // Catch unsigned integer errors.
}
catch (error:int)
{
throw MyError; // Catch integer errors.
}
catch (error:Number)
{
throw MyError; // Catch number errors.
}
catch (error:*)
{
throw MyError; // Catch any other error.
}
finally
{
myFunction(); // Perform any necessary cleanup here.
}
Všimněte si, že příkazy catch jsou uspořádány tak, aby nejpřesnější datové typy byly uvedeny jako první. Kdyby by
byl nejprve uveden příkaz catch pro datový typ Number, nebyl by nikdy proveden příkaz catch pro datový typ uint
ani příkaz catch pro datový typ int.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 187
Zpracování chyb
Poznámka: V programovacím jazyce Java musí každá funkce, která může vyvolat výjimku, tuto skutečnost deklarovat,
s uvedením tříd výjimek, jež dokáže vyvolat, v klauzuli throws připojené k deklaraci této funkce. V jazyce ActionScript
není zapotřebí deklarovat výjimky, které může funkce vyvolat.
Zobrazení jednoduché chybové zprávy
Jedním z největších přínosů nového modelu událostí výjimek a chyb je, že lze uživatelům sdělit, kdy a proč akce selhala.
Vaším úkolem je napsat kód pro zobrazení této zprávy a nabídnutí možných reakcí.
Následující kód znázorňuje jednoduchý příkaz try..catch k zobrazení chyby v textovém poli:
package
{
import flash.display.Sprite;
import flash.text.TextField;
public class SimpleError extends Sprite
{
public var employee:XML =
<EmpCode>
<costCenter>1234</costCenter>
<costCenter>1-234</costCenter>
</EmpCode>;
public function SimpleError()
{
try
{
if (employee.costCenter.length() != 1)
{
throw new Error("Error, employee must have exactly one cost center assigned.");
}
}
catch (error:Error)
{
var errorMessage:TextField = new TextField();
errorMessage.autoSize = TextFieldAutoSize.LEFT;
errorMessage.textColor = 0xFF0000;
errorMessage.text = error.message;
addChild(errorMessage);
}
}
}
}
Pomocí pestré škály tříd chyb a vestavěných chyb kompilátoru nabízí jazyk ActionScript 3.0 více informací o příčinách
selhání činnosti než předchozí verze jazyka ActionScript. Díky tomu lze vytvářet stabilnější aplikace s lepším
zpracováním chyb.
Opětné vyvolání chyb
Při vytváření aplikací může nastat několik případů, kdy je zapotřebí znovu vyvolat chybu, pokud nejste schopni tuto
chybu řádně zpracovat. Následující kód například znázorňuje vnořený blok try..catch, který znovu vyvolá vlastní
chybu ApplicationError, pokud vnořený blok catch není schopen tuto chybu zpracovat:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 188
Zpracování chyb
try
{
try
{
trace("<< try >>");
throw new ArgumentError("some error which will be rethrown");
}
catch (error:ApplicationError)
{
trace("<< catch >> " + error);
trace("<< throw >>");
throw error;
}
catch (error:Error)
{
trace("<< Error >> " + error);
}
}
catch (error:ApplicationError)
{
trace("<< catch >> " + error);
}
Výstup předcházejícího zlomku kódu by byl následující:
<<
<<
<<
<<
try >>
catch >> ApplicationError: some error which will be rethrown
throw >>
catch >> ApplicationError: some error which will be rethrown
Vnořený blok try vyvolá vlastní chybu ApplicationError, která bude zachycena následujícím blokem catch. Tento
vnořený blok catch může zkusit chybu zpracovat a pokud se mu to nepodaří, může vyvolat objekt ApplicationError
do uzavírajícího bloku try..catch.
Vytvoření vlastních tříd chyb
V jazyce ActionScript je možné rozšířit jednu ze standardních tříd Error a vytvořit vlastní specializované třídy chyb.
K vytvoření vlastních tříd chyb existuje řada důvodů:
• Určení specifických chyb nebo skupin chyb, které jsou jedinečné pro příslušnou aplikaci.
Například můžete chtít provést různé akce u chyb vyvolaných vlastním kódem, kromě těch, které zachytí aplikace
Flash Player nebo Adobe AIR. Můžete vytvořit podtřídu třídy Error pro sledování nového datového typu chyb v
blocích try..catch.
• Zajištění jedinečných schopností zobrazení chyb vygenerovaných příslušnou aplikací.
Například je možné vytvořit novou metodu toString(), která zformátuje chybové zprávy určitým způsobem.
Rovněž lze definovat metodu lookupErrorString(), která na základě jazykových preferencí uživatele načte pro
chybový kód správnou zprávu.
Specializovaná třída chyb musí rozšiřovat základní třídu Error jazyka ActionScript. Zde je příklad specializované třídy
AppError, která rozšiřuje třídu Error:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 189
Zpracování chyb
public class AppError extends Error
{
public function AppError(message:String, errorID:int)
{
super(message, errorID);
}
}
Následující příklad ilustruje použití třídy AppError ve vlastním projektu:
try
{
throw new AppError("Encountered Custom AppError", 29);
}
catch (error:AppError)
{
trace(error.errorID + ": " + error.message)
}
Poznámka: Chcete-li ve vlastní podtřídě nahradit metodu Error.toString(), musíte jí přiřadit jeden z parametrů
...(zbytek). Specifikace jazyka ECMAScript, na které je jazyk ActionScript 3.0 založen, definuje metodu
Error.toString() a jazyk ActionScript 3.0 ji definuje stejně pro zpětnou kompatibilitu. Při nahrazení metody
Error.toString() je proto zapotřebí přesně sladit parametry. Není žádoucí předávat jakékoliv parametry do metody
toString() za běhu, neboť tyto parametry se ignorují.
Reakce na chybové události a stavy
Jedním z nejnápadnějších vylepšení zpracování chyb v jazyce ActionScript 3.0 je podpora zpracování událostí chyb,
díky němuž lze reagovat na asynchronní chyby chodu programu. (Definici asynchronních chyb naleznete v sekci
„Typy chyb“ na stránce 180.)
Lze vytvářet posluchače a zpracování událostí k zajištění odezvy na události chyb. Řada tříd odesílá události chyb
stejným způsobem jako ostatní události. Instance třídy XMLSocket například obvykle odesílá tři typy událostí:
Event.CLOSE, Event.CONNECT a DataEvent.DATA. Pokud však nastanou potíže, může třída XMLSocket odeslat
chybu IOErrorEvent.IOError nebo SecurityErrorEvent.SECURITY_ERROR. Další informace týkající se
posluchačů a zpracování událostí naleznete v sekci „Zpracování událostí“ na stránce 243.
Události chyb spadají do jedné z následujících kategorií:
• Události chyb rozšiřující třídu ErrorEvent
Třída flash.events.ErrorEvent obsahuje vlastnosti a metody pro řízení chyb chodu programu týkajících se operací
síťového propojení nebo komunikace. Třídy AsyncErrorEvent, IOErrorEvent a SecurityErrorEvent rozšiřují třídu
ErrorEvent. Při použití ladicí verze aplikace Flash Player nebo Adobe AIR bude dialogový rámeček za běhu
informovat o všech událostech chyb bez funkcí posluchače, na něž přehrávač narazí.
• Události chyb založené na stavu
Události chyb založené na stavu se vztahují k vlastnostem netStatus a status u síťových a komunikačních tříd.
Když v aplikaci Flash Player nebo Adobe AIR nastanou potíže při čtení či zápisu dat, nastaví se vlastnosti
netStatus.info.level nebo status.level (v závislosti na použitém objektu třídy) na hodnotu "error". Na
tuto chybu reagujete tím, že zkontrolujete, zda vlastnost level ve funkci zpracování událostí obsahuje hodnotu
"error".
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 190
Zpracování chyb
Práce s událostmi chyb
Třída ErrorEvent a její podtřídy obsahují typy chyb pro zpracování chyb odeslaných aplikací Flash Player nebo Adobe
AIR při pokusu o čtení nebo zapisování dat.
V následujícím příkladu se použije příkaz try..catch i zpracování událostí chyb k zobrazení všech chyb zjištěných
při pokusu o čtení lokálního souboru. Na místech označených komentářem „your error-handling code here“ lze přidat
kód pro složitější zpracování a poskytnout tak uživateli různé možnosti, nebo zpracovat chyby automaticky.
package
{
import
import
import
import
import
import
import
import
import
flash.display.Sprite;
flash.errors.IOError;
flash.events.IOErrorEvent;
flash.events.TextEvent;
flash.media.Sound;
flash.media.SoundChannel;
flash.net.URLRequest;
flash.text.TextField;
flash.text.TextFieldAutoSize;
public class LinkEventExample extends Sprite
{
private var myMP3:Sound;
public function LinkEventExample()
{
myMP3 = new Sound();
var list:TextField = new TextField();
list.autoSize = TextFieldAutoSize.LEFT;
list.multiline = true;
list.htmlText = "<a href=\"event:track1.mp3\">Track 1</a><br>";
list.htmlText += "<a href=\"event:track2.mp3\">Track 2</a><br>";
addEventListener(TextEvent.LINK, linkHandler);
addChild(list);
}
private function playMP3(mp3:String):void
{
try
{
myMP3.load(new URLRequest(mp3));
myMP3.play();
}
catch (err:Error)
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 191
Zpracování chyb
{
trace(err.message);
// your error-handling code here
}
myMP3.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
}
private function linkHandler(linkEvent:TextEvent):void
{
playMP3(linkEvent.text);
// your error-handling code here
}
private function errorHandler(errorEvent:IOErrorEvent):void
{
trace(errorEvent.text);
// your error-handling code here
}
}
}
Práce s událostmi změny stavu
Aplikace Flash Player a Adobe AIR dynamicky mění hodnotu vlastností netStatus.info.level nebo
status.level u tříd, jež podporují vlastnost level. Třídy, které mají vlastnost netStatus.info.level, jsou
NetConnection, NetStream a SharedObject. Třídy, jež mají vlastnost status.level jsou HTTPStatusEvent, Camera,
Microphone a LocalConnection. Je možné napsat funkci zpracování za účelem reagování na změnu hodnoty level a
sledování chyb komunikace.
V následujícím příkladu slouží funkce netStatusHandler() k testování hodnoty vlastnosti level. Pokud vlastnost
level značí, že byla nalezena chyba, kód sleduje zprávu „Video stream failed“.
package
{
import
import
import
import
import
import
flash.display.Sprite;
flash.events.NetStatusEvent;
flash.events.SecurityErrorEvent;
flash.media.Video;
flash.net.NetConnection;
flash.net.NetStream;
public class VideoExample extends Sprite
{
private var videoUrl:String = "Video.flv";
private var connection:NetConnection;
private var stream:NetStream;
public function VideoExample()
{
connection = new NetConnection();
connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
connection.connect(null);
}
private function netStatusHandler(event:NetStatusEvent):void
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 192
Zpracování chyb
{
if (event.info.level == "error")
{
trace("Video stream failed")
}
else
{
connectStream();
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void
{
trace("securityErrorHandler: " + event);
}
private function connectStream():void
{
var stream:NetStream = new NetStream(connection);
var video:Video = new Video();
video.attachNetStream(stream);
stream.play(videoUrl);
addChild(video);
}
}
}
Porovnání tříd Error
Jazyk ActionScript poskytuje několik předdefinovaných tříd Error. Řadu těchto tříd používají aplikace Flash Player a
Adobe AIR, stejné třídy Error je však rovněž možné použít ve vlastním kódu. V jazyce ActionScript 3.0 jsou k dispozici
dva hlavní typy tříd Error: základní třídy Error jazyka ActionScript a třídy Error balíčku flash.error. Základní třídy
Error předepisuje Specifikace jazyka ECMAScript (ECMA-262), vydání 3. Balíček flash.error obsahuje další třídy
zavedené pro usnadnění vývoje a ladění aplikací v jazyce ActionScript 3.0.
Základní třídy Error v jazyce ECMAScript
Mezi základní třídy chyb v jazyce ECMAScript patří třídy Error, EvalError, RangeError, ReferenceError, SyntaxError,
TypeError a URIError. Každá z těchto tříd je umístěna v jmenném prostoru na nejvyšší úrovni.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 193
Zpracování chyb
Název třídy
Popis
Poznámky
Error
Třídu Error lze použít k vyvolání výjimek. Jedná se o
základní třídu pro ostatní třídy výjimek definované v
jazyce ECMAScript: EvalError, RangeError,
ReferenceError, SyntaxError, TypeError a URIError.
Třída Error slouží jako základní třída pro všechny chyby chodu
programu vyvolané aplikacemi Flash® Player a Adobe® AIR®, a
jde o doporučenou základní třídu pro vlastní třídy chyb.
EvalError
Výjimka EvalError se vyvolá v případě předání
parametrů do konstruktoru třídy Function, nebo
pokud kód uživatele volá funkci eval().
V jazyce ActionScript 3.0 byla podpora funkce eval()
odstraněna a při pokusu o použití této funkce se vyvolá chyba.
RangeError
Výjimka RangeError se vyvolá, jestliže číselná
hodnota leží mimo přijatelný rozsah.
Výjimku RangeError by například vyvolala třída Timer, pokud by
prodleva byla negativní nebo by nebyla konečná. Výjimka
RangeError může být rovněž vyvolána při pokusu o přidání
objektu zobrazení v neplatné hloubce.
ReferenceError
Výjimka ReferenceError se vyvolá při pokusu o
provedení odkazu na nedefinovanou vlastnost u
uzavřeného (nedynamického) objektu. Verze
kompilátoru jazyka ActionScript starší než
ActionScript 3.0 nevyvolaly chybu při pokusu o
přístup do vlastnosti s hodnotou undefined.
Nicméně v této situaci jazyk ActionScript 3.0
vygeneruje výjimku ReferenceError.
Výjimky pro nedefinované proměnné ukazují na možné chyby,
což pomáhá zlepšit kvalitu softwaru. Pokud však nejste zvyklí,
že je zapotřebí proměnné inicializovat, může toto nové chování
jazyka ActionScript vyžadovat změnu obvyklých postupů při
kódování.
Dřívější verze aplikace Flash Player používaly funkci eval() k
zajištění přístupu do proměnných, vlastností, objektů či
filmových klipů podle názvu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 194
Zpracování chyb
Název třídy
Popis
Poznámky
SyntaxError
Výjimka SyntaxError se vyvolá, když v kódu jazyka
ActionScript dojde k chybě analýzy.
Chyba SyntaxError může být vyvolána za následujících
okolností:
Další informace naleznete v sekci 15.11.6.4
specifikace jazyka ECMAScript (ECMA-262), vydání 3
na adrese www.ecmainternational.org/publications/standards/Ecma262.htm, jakož i v sekci 10.3.1 specifikace jazyka
ECMAScript pro XML (E4X) (ECMA-357, vydání 2) na
adrese www.ecmainternational.org/publications/standards/Ecma357.htm.
•
Skript jazyka ActionScript vyvolá výjimku SyntaxError, když je
neplatný regulární výraz analyzovaný třídou RegExp.
•
Skript jazyka ActionScript vyvolá výjimku SyntaxError, když je
neplatný XML analyzovaný třídou XMLDocument.
Výjimka TypeError se vyvolá, když je skutečný typ
operandu odlišný od očekávaného typu.
Chyba TypeError může být vyvolána za následujících okolností:
TypeError
Další informace naleznete v sekci 15.11.6.5
specifikace jazyka ECMAScript na adrese www.ecmainternational.org/publications/standards/Ecma262.htm, jakož i v sekci 10.3 specifikace jazyka E4X na
adrese www.ecmainternational.org/publications/standards/Ecma357.htm.
URIError
•
Aktuální parametr funkce nebo metody nemůže být vnucen
určitému typu parametru.
•
Proměnné je přiřazena hodnota, která nemůže být vnucena
typu proměnné.
•
Pravá strana operátoru is nebo instanceof není platného
typu.
•
Klíčové slovo super je nesprávně použito.
•
Vyhledávání vlastnosti má za výsledek více než jedno spojení
a proto je nejednoznačné.
•
Metoda je uplatňována na nekompatibilní objekt. Výjimka
TypeError se například vyvolá, když je metoda třídy RegExp
připojena na nechráněný objekt a pak uplatněna.
Výjimka URIError se vyvolá, když je jedna z funkcí pro Chyba URIError může být vyvolána za následujících okolností:
zpracování globálního URI použita způsobem, který
Pro funkci rozhraní API v aplikaci Flash Player je zadán neplatný
není kompatibilní s její definicí.
URI místo očekávaného platného URI, např.
Socket.connect().
Další informace naleznete v sekci 15.11.6.6
specifikace jazyka ECMAScript na adrese www.ecmainternational.org/publications/standards/Ecma262.htm.
Základní třídy Error v jazyce ActionScript
Kromě základních tříd Error v jazyce ECMAScript přidává jazyk ActionScript řadu vlastních tříd pro chyby specifické
pro jazyk ActionScript a funkčnost zpracování chyb.
Vzhledem k tomu, že tyto třídy v jazyce ActionScript jsou rozšířením specifikace jazyka ECMAScript, vydání 3, a
mohou být zajímavým doplňkem specifikace, jsou uchovávány na nejvyšší úrovni místo toho, aby byly umístěny v
balíčku jako flash.error.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 195
Zpracování chyb
Název třídy
Popis
Poznámky
ArgumentError
Třída ArgumentError představuje chybu, která se
Příklady chyb argumentů mohou být následující:
objeví, když hodnoty parametrů použité během volání
• Pro metodu bylo zadáno příliš málo nebo příliš mnoho
funkce neodpovídají parametrům definovaným pro
argumentů.
tuto funkci.
•
SecurityError
VerifyError
Výjimka SecurityError se vyvolá, když dojde k narušení
bezpečnosti a přístup je zamítnut.
Výjimka VerifyError se vyvolá, když je nalezen chybný
nebo poškozený soubor SWF.
Argument měl být podle očekávání členem výčtu a
nebyl.
Příklady chyb zabezpečení mohou být následující:
•
Neoprávněný přístup k vlastnosti nebo je volání
metody provedeno přes hranice rozsahu zabezpečení.
•
Byl učiněn pokus přístupu k URL, nedovolený rozsahem
zabezpečení
•
Došlo k pokusu připojení soketu na port, ale nezbytný
soubor zásad nebyl k dispozici.
•
Byl učiněn pokus přístupu k uživatelově kameře nebo
mikrofonu, žádost o přístup k zařízení byla odmítnuta
uživatelem.
Když soubor SWF načítá jiný soubor SWF, může nadřazený
soubor SWF zachytit výjimku VerifyError vygenerovanou
načteným souborem SWF.
Třídy Error v balíčku flash.error
Balíček flash.error obsahuje třídy Error, které jsou považovány za součást rozhraní API aplikace Flash Player. Na rozdíl
od tříd Error, jež byly právě popsány, balíček flash.error oznamuje chyby specifické pro aplikaci Flash Player nebo
Adobe AIR.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 196
Zpracování chyb
Název třídy
Popis
Poznámky
EOFError
Výjimka EOFError se vyvolá, když se uživatel
pokouší číst přes konec dostupných dat.
Například chyba EOFError je vrácena v případě, že je
zavolána jedna z metod čtení v rozhraní IDataInput a
nejsou k dispozici dostatečná data, která by požadavek
na čtení uspokojila.
IllegalOperationError
Výjimka IllegalOperationError se vyvolá, když není Příklady chyb neplatných operací zahrnují:
implementována některá metoda nebo příslušná
• Základní třída, například DisplayObjectContainer,
implementace nepokrývá aktuální použití.
poskytuje více funkcí, než kolik jich může
podporovat třída Stage. Když se například pokusíte
získat nebo nastavit masku na ploše (pomocí
metody stage.mask), vyvolá aplikace Flash Player
nebo Adobe AIR výjimku IllegalOperationError se
zprávou „The Stage class does not implement this
property or method“.
•
Podtřída zdědí metodu, kterou nepotřebuje a
nechce podporovat.
•
Jisté metody přístupnosti jsou volány v okamžiku,
když je aplikace Flash Player sestavena bez možnosti
přístupu.
•
Funkce jen pro vytváření se vyvolávají z běhových
verzí aplikace Flash Player.
•
Snažíte se nastavit název objektu umístěného na
časové ose.
IOError
Výjimka IOError se vyvolá, když nastane určitý typ
výjimky V/V.
Tato chyba se zobrazí například při pokusu o čtení a
zápis na socketu, který není připojen nebo byl
odpojen.
MemoryError
Výjimka MemoryError bude vyvolána, když je
požadavek na alokování paměti neúspěšný.
Verze ActionScript Virtual Machine 2 implicitně
nestanoví limit velikosti paměti, kterou může program
jazyka ActionScript přiřazovat. U stolních počítačů se
chyby přidělení paměti vyskytují jen zřídka. K chybě
dojde, když systém není schopen přidělit paměť
potřebnou pro danou operaci. Proto u stolního
počítače tato výjimka nastane jen výjimečně, pokud
není požadavek na přidělení paměti extrémně velký.
Například požadavek na 3 miliardy bytů je
nesplnitelný, neboť 32bitový program Microsoft®
Windows® má přístup jen k 2 GB adresového prostoru.
ScriptTimeoutError
Výjimka ScriptTimeoutError se vyvolá po uplynutí
15 sekundového intervalu časového limitu skriptu.
Zachycením výjimky ScriptTimeoutError lze
zpracovat časový limit skriptu elegantněji. Není-li
k dispozici zpracování výjimek, funkce zpracování
nezachycených výjimek zobrazí dialogové okno s
chybovou zprávou.
Aby nemohl zlomyslný vývojář výjimku zachytit a
zůstat v nekonečné smyčce, může být zachycena
pouze první výjimka ScriptTimeoutError vyvolaná v
průběhu určitého skriptu. Následující výjimku
ScriptTimeoutError nemůže příslušný kód zachytit,
proto ihned přejde ke zpracování nezachycené
výjimky.
StackOverflowError
Výjimka StackOverflowError se vyvolá po
vyčerpání zásobníku, který je k dispozici pro daný
skript.
Výjimka StackOverflowError může značit, že nastala
nekonečná rekurze.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 197
Zpracování chyb
Příklad: použití třídy CustomErrors
V použití třídy CustomErrors jsou znázorněny techniky práce s vlastními chybami při vytváření aplikace. Tyto
techniky jsou následující:
• Ověření paketu XML
• Zápis vlastní chyby
• Vyvolání vlastních chyb
• Upozornění uživatelů při vyvolání chyby
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Aplikační soubory CustomErrors se nacházejí ve složce Samples/CustomError. Aplikace sestává z následujících
souborů:
Soubor
Popis
CustomErrors.mxml
Hlavní aplikační soubor v aplikaci Flash (FLA) nebo Flex (MXML)
nebo
CustomErrors.fla
com/example/programmingas3/errors/ApplicationError.as
Třída, která slouží jako základní třída chyb pro třídu FatalError i
WarningError.
com/example/programmingas3/errors/FatalError.as
Třída definující chybu FatalError, jež může být vyvolána aplikací. Tato
třída rozšiřuje vlastní třídu ApplicationError.
com/example/programmingas3/errors/Validator.as
Třída definující jedinou metodu, která ověří paket XML zaměstnance
zadaný uživatelem.
com/example/programmingas3/errors/WarningError.as
Třída definující chybu WarningError, jež může být vyvolána aplikací. Tato
třída rozšiřuje vlastní třídu ApplicationError.
Přehled použití třídy CustomErrors
Po načtení aplikace se vyvolá metoda initApp() v programu Flex nebo se provede kód v časové ose (není funkcí) v
aplikaci Flash. Tento kód definuje vzorový paket XML, který bude ověřen třídou Validator. Spustí se následující kód:
employeeXML =
<employee id="12345">
<firstName>John</firstName>
<lastName>Doe</lastName>
<costCenter>12345</costCenter>
<costCenter>67890</costCenter>
</employee>;
}
Paket XML se pak zobrazí v instanci komponenty TextArea na ploše. To umožní úpravu paketu XML před tím, než
proběhne pokus o obnovení jeho platnosti.
Po klepnutí na tlačítko Ověřit se zavolá metoda validateData(). Tato metoda ověří platnost paketu XML
zaměstnance pomocí metody validateEmployeeXML() ve třídě Validator. Následující kód znázorňuje metodu
validateData():
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 198
Zpracování chyb
function validateData():void
{
try
{
var tempXML:XML = XML(xmlText.text);
Validator.validateEmployeeXML(tempXML);
status.text = "The XML was successfully validated.";
}
catch (error:FatalError)
{
showFatalError(error);
}
catch (error:WarningError)
{
showWarningError(error);
}
catch (error:Error)
{
showGenericError(error);
}
}
Nejprve se vytvoří dočasný objekt XML pomocí obsahu instance komponenty TextArea xmlText. Potom se vyvolá
metoda validateEmployeeXML() ve vlastní třídě Validator (com.example.programmingas3/errors/Validator.as) a
odešle dočasný objekt XML jako parametr. Jestliže je paket XML platný, zobrazí instance komponenty Label status
úspěšnou zprávu a aplikace se ukončí. Pokud metoda validateEmployeeXML() vyvolá vlastní chybu (tzn. dojde k
chybě FatalError, WarningError nebo k obecné chybě Error), provede se odpovídající příkaz catch , který zavolá
metodu showFatalError(), showWarningError() nebo showGenericError(). Každá z těchto metod zobrazí
příslušnou zprávu v textové oblasti s názvem statusText a upozorní uživatele na konkrétní vzniklou chybu. Každá
metoda rovněž aktualizuje instanci komponenty Label status specifickou zprávou.
Jestliže během pokusu o ověření paketu XML zaměstnance dojde k závažné chybě, deaktivuje se chybová zpráva
zobrazená v textové oblasti statusText, instance komponenty TextArea xmlText a instance komponenty Button
validateBtn, jak je znázorněno v následujícím kódu:
function showFatalError(error:FatalError):void
{
var message:String = error.message + "\n\n";
var title:String = error.getTitle();
statusText.text = message + " " + title + "\n\nThis application has ended.";
this.xmlText.enabled = false;
this.validateBtn.enabled = false;
hideButtons();
}
Pokud místo závažné chyby dojde k chybě upozornění, zobrazí se chybová zpráva v instanci objektu TextArea
statusText, ale instance komponent TextField a Button xmlText nebudou deaktivovány. Metoda
showWarningError() zobrazuje vlastní chybovou zprávu v textové oblasti statusText. Zpráva se rovněž uživatele
dotáže, zda má pokračovat ověřování XML nebo zda má být skript ukončen. Následující výpisek znázorňuje metodu
showWarningError():
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 199
Zpracování chyb
function showWarningError(error:WarningError):void
{
var message:String = error.message + "\n\n" + "Do you want to exit this application?";
showButtons();
var title:String = error.getTitle();
statusText.text = message;
}
Po klepnutí na tlačítko Ano nebo Ne se vyvolá metoda closeHandler(). Následující výpisek znázorňuje metodu
closeHandler():
function closeHandler(event:CloseEvent):void
{
switch (event.detail)
{
case yesButton:
showFatalError(new FatalError(9999));
break;
case noButton:
statusText.text = "";
hideButtons();
break;
}
}
Jestliže se uživatel rozhodne skript ukončit klepnutím na tlačítko Ano, vyvolá se chyba FatalError, která způsobí
ukončení aplikace.
Vytvoření vlastního validátoru
Vlastní třída Validator obsahuje jedinou metodu, validateEmployeeXML(). Metoda validateEmployeeXML()
převezme jediný argument employee, což je paket XML, který se má ověřit. Metoda validateEmployeeXML() je
následující:
public static function validateEmployeeXML(employee:XML):void
{
// checks for the integrity of items in the XML
if (employee.costCenter.length() < 1)
{
throw new FatalError(9000);
}
if (employee.costCenter.length() > 1)
{
throw new WarningError(9001);
}
if (employee.ssn.length() != 1)
{
throw new FatalError(9002);
}
}
Aby bylo možné provést ověření, musí zaměstnanec patřit do jednoho (a pouze jednoho) nákladového střediska.
Pokud zaměstnanec do žádného nákladového střediska nepatří, vyvolá metoda chybu FatalError, která probublá až do
metody validateData() v hlavním aplikačním souboru. Patří-li zaměstnanec do více než jednoho nákladového
střediska, vyvolá se chyba WarningError. Konečná kontrola ve validátoru XML ověří, zda má uživatele definováno
právě jedno číslo sociálního pojištění (uzel ssn v paketu XML). Jestliže není k dispozici právě jeden uzel ssn, vyvolá
se chyba FatalError.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 200
Zpracování chyb
Do metody validateEmployeeXML() lze přidat další kontroly, např. pro zajištění, aby uzel ssn obsahoval platné číslo
nebo aby měl zaměstnanec definováno alespoň jedno telefonní číslo a e-mailovou adresu a aby obě hodnoty byly
platné. Rovněž je možné upravit XML, aby každý zaměstnanec měl jedinečné ID a určoval ID svého správce.
Definice třídy ApplicationError
Třída ApplicationError slouží jako základní třída pro třídu FatalError i WarningError. Třída ApplicationError
rozšiřuje třídu Error a definuje vlastní metody a vlastnosti, včetně ID chyby, závažnosti chyby a objektu XML, který
obsahuje vlastní kódy chyb a chybové zprávy. Tato třída rovněž definuje dvě statické konstanty, které slouží k
definování závažnosti jednotlivých typů chyb.
Metoda konstruktoru třídy ApplicationError je následující:
public function ApplicationError()
{
messages =
<errors>
<error code="9000">
<![CDATA[Employee must be assigned to a cost center.]]>
</error>
<error code="9001">
<![CDATA[Employee must be assigned to only one cost center.]]>
</error>
<error code="9002">
<![CDATA[Employee must have one and only one SSN.]]>
</error>
<error code="9999">
<![CDATA[The application has been stopped.]]>
</error>
</errors>;
}
Každý uzel chyby v objektu XML obsahuje jedinečný číselný kód a chybovou zprávu. Chybové zprávy lze snadno
vyhledat podle jejich chybových kódů pomocí jazyka E4X, jak je znázorněno v následující metodě
getMessageText():
public function getMessageText(id:int):String
{
var message:XMLList = messages.error.(@code == id);
return message[0].text();
}
Metoda getMessageText() převezme jediný argument celého čísla, id, a vrátí řetězec. Argument id je chybový kód
pro chybu, která se má vyhledat. Například při odeslání id 9001 se načte chyba, která říká, že zaměstnanci musí být
přiřazeni pouze k jednomu nákladovému středisku. Má-li více chyb stejný chybový kód, vrátí ActionScript chybovou
zprávu pouze pro první nalezený výsledek (message[0] v načteném objektu XMLList).
Následující metoda v této třídě, getTitle(), nepřebírá žádné parametry a vrací řetězcovou hodnotu obsahující ID
chyby pro tuto konkrétní chybu. Tato hodnota slouží pro snadnou identifikaci přesné chyby, k níž došlo při ověřování
platnosti paketu XML. Následující výpisek znázorňuje metodu getTitle():
public function getTitle():String
{
return "Error #" + id;
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 201
Zpracování chyb
Poslední metodou ve třídě ApplicationError je toString(). Tatometoda nahradí funkci definovanou ve třídě Error,
aby bylo možné přizpůsobit vzhled chybové zprávy. Metoda vrací řetězec, který identifikuje specifické číslo chyby a
chybovou zprávu, jež byla zobrazena.
public override function toString():String
{
return "[APPLICATION ERROR #" + id + "] " + message;
}
Definice třídy FatalError
Třída FatalError rozšiřuje vlastní třídu ApplicationError a definuje tři metody: konstruktor FatalError, getTitle() a
toString(). První metoda, konstruktor FatalError, převezme jediný argument celého čísla, errorID, nastaví
závažnost chyby pomocí statických konstantních hodnot definovaných ve třídě ApplicationError a získá chybovou
zprávu určité chyby zavoláním metody getMessageText() ve třídě ApplicationError. Konstruktor FatalError je
následující:
public function FatalError(errorID:int)
{
id = errorID;
severity = ApplicationError.FATAL;
message = getMessageText(errorID);
}
Další metoda ve třídě FatalError, getTitle(), nahradí metodu getTitle() definovanou dříve ve třídě
ApplicationError a k názvu připojí text „-- FATAL“, který uživatele informuje, že došlo k závažné chybě. Metoda
getTitle() je následující:
public override function getTitle():String
{
return "Error #" + id + " -- FATAL";
}
Poslední metoda v této třídě, toString(), nahradí metodu toString() definovanou ve třídě ApplicationError.
Metoda toString() je následující:
public override function toString():String
{
return "[FATAL ERROR #" + id + "] " + message;
}
Definice třídy WarningError
Třída WarningError rozšiřuje třídu ApplicationError a je téměř stejná jako třída FatalError až na to, že obsahuje dvě
drobné změny v řetězci a nastavuje závažnost chyby na ApplicationError.WARNING místo
ApplicationError.FATAL, jak je znázorněno v následujícím kódu:
public function WarningError(errorID:int)
{
id = errorID;
severity = ApplicationError.WARNING;
message = super.getMessageText(errorID);
}
202
Kapitola 10: Používání regulárních výrazů
Regulární výraz popisuje vzorec, který se používá k vyhledání a manipulaci se shodným textem v řetězcích. Regulární
výrazy se podobají řetězcům, ale mohou zahrnovat speciální kódy pro popis vzorců a opakování. Například následující
regulární výraz se shoduje s řetězcem, který začíná znakem A a následuje jedna nebo více sekvenčních číslic:
/A\d+/
Tato kapitola popisuje základní syntaxi pro konstruování regulárních výrazů. Regulární výrazy mohou být nicméně
velice složité a mohou zahrnovat mnoho malých detailů. Podrobné zdroje o regulárních výrazech naleznete na webu
a v knihkupectvích. Mějte na paměti, že odlišná programovací rozhraní implementují regulární výrazy různým
způsobem. Jazyk ActionScript 3.0 implementuje regulární výrazy dle definice v specifikaci jazyka ECMAScript, vydání
3. (ECMA-262).
Základní informace o regulárních výrazech
Úvod do použití regulárních výrazů
Regulární výraz popisuje vzorec znaků. Regulární výrazy se obvykle používají k ověření, zda textové hodnoty
odpovídají zvláštnímu vzorci (například ověření, zda uživatelem zadané telefonní číslo má správný počet číslic) nebo
pro nahrazení částí hodnoty textu, která odpovídá zvláštnímu vzorci.
Regulární výrazy mohou být jednoduché. Například předpokládejme, že si přejete potvrdit, zda určitý řetězec
odpovídá „ABC“, nebo si přejete nahradit každý výskyt „ABC“ v řetězci jiným textem. V takovém případě byste mohli
použít následující regulární výraz, který definuje vzorec skládající se z písmen A, B a C v sekvenci:
/ABC/
Všimněte si, že literál regulárního výrazu je vymezen pomocí znaku lomítka (/).
Vzorce regulárních výrazů mohou být také složité a jejich vzhled může být někdy kryptický, jako například následující
výraz, který odpovídá platné e-mailové adrese:
/([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}/
Regulární výrazy nejběžněji použijete pro vyhledání vzorců z řetězců a pro nahrazení znaků. V těchto případech
vytvoříte objekt regulárního výrazu a použijete jej jako parametr pro jednu z několika metod třídy String. Následující
metody třídy String přebírají regulární výrazy jako parametry: match(), replace(), search() a split(). Více
informací o těchto metodách naleznete v části „Vyhledání vzorků v řetězcích a nahrazení podřetězců“ na stránce 144.
Třída RegExp zahrnuje následující metody: test() a exec(). Více informací naleznete v části „Metody pro použití
regulárních výrazů s řetězci“ na stránce 217.
Běžné úlohy regulárních výrazů.
Pro regulární výrazy existuje několik běžných použití, které jsou v této kapitole podrobně popsány:
• Vytvoření vzorce regulárního výrazu
• Používání zvláštních znaků ve vzorcích
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 203
Používání regulárních výrazů
• Identifikace pořadí více znaků (například „dvoumístné číslo“ nebo „mezi sedmi a pěti písmeny“)
• Identifikace libovolných znaků v rozpětí písmen nebo čísel (například „libovolné písmeno od a do m“)
• Identifikace znaku v množině možných znaků
• Identifikace dílčích sekvencí (segmenty v rámci vzorce)
• Propojování a nahrazování textu na základě vzorců
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny používané v této kapitole:
• Znak escape: Znak určující, že následující znak by měl být zpracován jako metaznak spíše než znak literálu. V
syntaxi regulárních výrazů je znakem escape znak zpětného lomítka (\), takže zpětné lomítko následované dalších
znakem je speciální kód spíše než kód samotný.
• Příznak: Znak, který určuje některé možnosti použití vzorce regulárního výrazu, například zda rozlišit mezi
velkými a malými znaky.
• Metaznak: Znak, který má zvláštní význam ve vzorci regulárního výrazu, oproti literální reprezentaci daného znaku
ve vzorci.
• Kvantifikátor: Znak (nebo několik znaků) určující, kolikrát je třeba část daného vzorce zopakovat. Kvantifikátor lze
například použít pro určení, že poštovní směrovací číslo Spojených států by mělo obsahovat pět nebo devět čísel.
• Regulární výraz: Příkaz programu definující vzorec znaků, které lze použít pro potvrzení, zda se jiné řetězce shodují
s daných vzorcem nebo pro nahrazení částí řetězce.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Protože
se ukázky kódu v této kapitole primárně skládají ze vzorců regulárních výrazů, zahrnuje testování příkladů několik
kroků:
1 Vytvořte nový dokument Flash.
2 Zvolte klíčový snímek a otevřete panel Akce.
3 Vytvořte proměnnou RegExp (regulární výraz), například následující:
var pattern:RegExp = /ABC/;
4 Zkopírujte vzorec z příkladu a přiřaďte jej jako hodnotu proměnné RegExp. Například v předcházejícím řádku
kódu je vzorec součástí kódu napravo od znaménka rovnosti a neobsahuje středník (/ABC/).
5 Vytvořte jednu nebo více proměnných řetězce, které obsahují řetězce vhodné pro testování vašich regulárních
výrazů. Jestliže například vytváříte regulární výraz pro textování platných e-mailových adres, vytvořte nové
proměnné řetězce, které obsahují platné a špatné e-mailové adresy:
var goodEmail:String = "[email protected]";
var badEmail:String = "5@$2.99";
6 Přidejte řádky kódu pro testování proměnných řetězce a určete, zda se shodují se vzorcem regulárních výrazů. Tyto
budou hodnotami, který budete chtít získat jako výstup na obrazovce pomocí funkce trace() nebo jejich zapsáním
do textového pole na ploše.
trace(goodEmail, " is valid:", pattern.test(goodEmail));
trace(badEmail, " is valid:", pattern.test(badEmail));
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 204
Používání regulárních výrazů
Předpokládejme například, že pattern definuje vzorec regulárního výrazu pro platnou e-mailovou adresu,
předcházející řádky kódu zapisují tento text do panelu Výstup:
[email protected] is valid: true
5@$2.99 is valid: false
Více informací o testování hodnot zapsáním hodnot do instance textového pole na ploše nebo použitím funkce
trace() pro vytištění hodnot na panel Výstup naleznete v části „Testování příkladů kódu v této kapitole“ na
stránce 34.
Syntaxe regulárního výrazu
Tato část popisuje všechny prvky syntaxe regulárního výrazu jazyka ActionScript. Jak zjistíte, regulární výrazy mohou
být složité a mohou obsahovat mnoho malých detailů. Podrobné zdroje o regulárních výrazech naleznete na webu a v
knihkupectvích. Mějte na paměti, že odlišná programovací rozhraní implementují regulární výrazy různým
způsobem. Jazyk ActionScript 3.0 implementuje regulární výrazy dle definice v specifikaci jazyka ECMAScript, vydání
3. (ECMA-262).
Obecně používáte regulární výrazy, které se shodují se složitými vzorci více než s jednoduchým řetězcem znaků.
Například následující regulární výraz definuje vzorec skládající se z písmen A, B a C v sekvenci následované libovolnou
číslicí:
/ABC\d/
Kód \d představuje „libovolnou číslici“. Znak zpětného lomítka (\) se nazývá znak escape a v kombinaci se znakem,
který za ním následuje (v tomto případě písmeno d), má v regulárním výrazu zvláštní význam. Tato kapitola popisuje
tyto sekvence znaků escape a jiných prvků syntaxe regulárního výrazu.
Následující regulární výraz definuje vzorec písmen ABC následovaný libovolným počtem číslic (všimněte si
hvězdičky):
/ABC\d*/
Znak hvězdičky (*) je metaznak. Metaznak je znak, který má v regulárním výrazu speciální význam. Hvězdička je
speciální typ metaznaku nazvanýkvantifikátor, který se používá ke kvantifikaci množství opakování znaku nebo
skupiny znaků. Další informace naleznete v části „Kvantifikátory“ na stránce 209.
Vedle tohoto vzorce může regulární výraz obsahovat příznaky, které specifikují, jak má být regulární výraz přiřazen.
Například následující regulární výraz používá příznak i, který specifikuje, že regulární výraz ignoruje rozlišení velkých
a malých písmen v odpovídajících řetězcích:
/ABC\d*/i
Více informací naleznete v části „Příznaky a vlastnosti“ na stránce 214.
Regulární výrazy můžete použít s následujícími metodami třídy String: match(), replace() a search(). Více
informací o těchto metodách naleznete v části „Vyhledání vzorků v řetězcích a nahrazení podřetězců“ na stránce 144.
Vytvoření instance regulárního výrazu
Pro vytvoření instance regulárního výrazu existují dva způsoby. Jedním způsobem je použití znaků lomítka /) k
vymezení regulárního výrazu; dalším způsobem je použití konstruktoru new. Například následující regulární výrazy
jsou rovnocenné:
var pattern1:RegExp = /bob/i;
var pattern2:RegExp = new RegExp("bob", "i");
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 205
Používání regulárních výrazů
Lomítka vymezí literál regulárního výrazu stejným způsobem jako uvozovky vymezují literál řetězce. Část regulárního
výrazu mezi lomítky definuje vzorec. Regulární výraz může také po závěrečném vymezujícím lomítku zahrnovat
příznaky. Tyto příznaky jsou považovány za součást regulárního výrazu, ale jsou odděleny od jeho vzorce.
Při používání konstruktoru new použijete k definování regulárního výrazu dva řetězce. První řetězec definuje vzorec a
druhý řetězec definuje příznaky, viz následující příklad:
var pattern2:RegExp = new RegExp("bob", "i");
Při zahrnutí lomítka do regulárního výrazu, který je definován pomocí vymezovačů lomítka, musíte před lomítko
nejprve umístit znak escape(\) zpětného lomítka. Například následující regulární výraz odpovídá vzorci 1/2:
var pattern:RegExp = /1\/2/;
Chcete-li zahrnout uvozovky do regulárního výrazu, který je definován s konstruktorem new, musíte před uvozovky
přidat znak escape zpětného lomítka (\) (jako při definování libovolného literálu String). Například následující
regulární výrazy odpovídají vzorci eat at "joe's":
var pattern1:RegExp = new RegExp("eat at \"joe's\"", "");
var pattern2:RegExp = new RegExp('eat at "joe\'s"', "");
Znak escape zpětného lomítka nepoužívejte s uvozovkami v regulárních výrazech, které jsou definovány pomocí
vymezovačů obyčejného lomítka. Obdobně nepoužívejte znaky escape s lomítkem v regulárních výrazech, které jsou
definovány konstruktorem new. Následující regulární výrazy jsou ekvivalentní a definují vzorec 1/2 "joe's":
var pattern1:RegExp = /1\/2 "joe's"/;
var pattern2:RegExp = new RegExp("1/2 \"joe's\"", "");
var pattern3:RegExp = new RegExp('1/2 "joe\'s"', '');
Také v regulárním výrazu, který je definován konstruktoremnew, napište při použití metasekvence začínající zpětným
lomítkem (\ ) znak zpětného lomítka dvakrát, jako třeba u metasekvence \d (která odpovídá každému číslu):
var pattern:RegExp = new RegExp("\\d+", ""); // matches one or more digits
Znak zpětného lomítka musíte napsat dvakrát, protože první parametr metody konstruktora RegExp() je řetězec a v
řetězcovém literálu musíte napsat znak zpětného lomítka dvakrát, aby byl rozeznatelný jako jediný znak zpětného
lomítka.
Následující části popisují syntaxi pro definování vzorců regulárních výrazů.
Více informací o příznacích naleznete v části „Příznaky a vlastnosti“ na stránce 214.
Znaky, metaznaky a metasekvence
Nejjednodušší regulární výraz je ten, který odpovídá sekvenci znaků, viz následující příklad:
var pattern:RegExp = /hello/;
Nicméně následující znaky, známé jako metaznaky, mají v regulárních výrazech speciální význam:
^ $ \ . * + ? ( ) [ ] { } |
Například následující regulární výraz se shoduje s písmenem A následovaným nulou nebo více instancemi písmene B
(metaznak hvězdičky označuje opakování) následovanými písmenem C:
/AB*C/
Chcete-li zahrnout metaznak do vzorce regulárního výrazu bez jeho speciálního významu, musíte použít znak escape
zpětného lomítka (\). Například následující regulární výraz se shoduje s písmenem A následovaným písmenem B,
následovaným hvězdičkou a písmenem C:
var pattern:RegExp = /AB\*C/;
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 206
Používání regulárních výrazů
Metasekvence, podobně jako metaznak, má v regulárním výrazu speciální význam. Metasekvence se skládá s více než
jednoho znaku. V následujících částech jsou uvedeny podrobnosti o používání metaznaků a metasekvencí.
O metaznacích
Následující tabulka poskytuje souhrn metaznaků, které lze použít v regulárních výrazech:
Metaznak
Popis
^ (stříška)
Souhlasné hodnoty na začátku řetězce. Je-li nastaven příznak m (multiline), shoduje se stříška také se
začátkem řádku (viz „Příznaky a vlastnosti“ na stránce 214). Všimněte si, že pokud je stříška použita na
začátku třídy znaků, určuje negaci, nikoliv začátek řetězce. Pro více informací viz „Třídy znaků“ na
stránce 208.
$ (znak dolaru)
Souhlasné hodnoty na konci řetězce. Je-li nastaven příznak m (multiline), znak $ se shoduje také s pozicí
před znakem nového řádku (\n). Více informací naleznete v části „Příznaky a vlastnosti“ na stránce 214.
\ (zpětné lomítko)
Ukončí speciální význam metaznaku speciálních znaků
Znak zpětného lomítka můžete také použít, jestliže si přejete použít znak lomítka v literálu regulárního
výrazu, viz /1\/2/ (pro shodu se znakem 1 následovaným znakem lomítka, následovaným znakem 2).
. (tečka)
Shoduje se s jakýmkoliv jediným znakem.
Tečka odpovídá znaku nového řádku (\n) pouze je-li nastavený příznak s (dotall). Více informací
naleznete v části „Příznaky a vlastnosti“ na stránce 214.
* (hvězda)
Spáruje se s předcházející položkou neopakovanou nebo opakovanou.
Další informace naleznete v části „Kvantifikátory“ na stránce 209.
+ (plus)
Spáruje se s předcházející položkou opakovanou jednou nebo vícekrát.
Další informace naleznete v části „Kvantifikátory“ na stránce 209.
? (otazník)
Spáruje se s předcházející položku neopakovanou nebo opakovanou jednou.
Další informace naleznete v části „Kvantifikátory“ na stránce 209.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 207
Používání regulárních výrazů
Metaznak
Popis
(a)
Definuje skupiny v rámci regulárního výrazu. Skupiny lze použít k následujícím akcím:
•
Pro ohraničení rozsahu znaku alternace |: /(a|b|c)d/
•
Pro definování rozsahu kvantifikátoru: /(walla.){1,2}/
•
Ve zpětných referencích. Například \1 v následujícím regulárním výrazu se shoduje s čímkoliv, co se
shoduje s první skupinou závorek daného vzorce:
•
/(\w*) is repeated: \1/
Další informace viz „Skupiny“ na stránce 211.
[a]
Definuje třídu znaku, která definuje možné shody pro jediný znak:
/[aeiou]/ spáruje se s libovolným ze specifikovaných znaků.
V rámci tříd znaků můžete pomocí pomlčky (-) určit rozsah znaků:
/[A-Z0-9]/ se shoduje s velkým písmenem A až Z nebo s číslem 0 až 9.
V rámci třídy znaků vložte zpětné lomítko pro ukončení znaků ] a
- znaky:
/[+\-]\d+/ se shoduje buď s + nebo - před jednou nebo více číslicemi.
V rámci tříd znaků jsou jiné znaky, které jsou běžně metaznaky, zpracovávány jako běžné znaky (nikoliv
metaznaky), bez nutnosti zpětného lomítka:
/[$]/£ se shoduje buď s $ nebo £.
Pro více informací viz „Třídy znaků“ na stránce 208.
| (spojovací znak)
Používá se pro alternaci, pro souhlas buď s částí levé strany nebo s částí pravé strany:
/abc|xyz/ se shoduje buď s abc nebo xyz.
O metasekvencích
Metasekvence jsou sekvence znaků, které mají ve vzorci regulárních výrazů speciální význam. Následující tabulka tyto
znaky popisuje:
Metasekvence
Popis
{n}
Určuje numerický kvantifikátor nebo rozsah kvantifikátoru pro předchozí položku:
{n,}
/A{27}/ se shoduje se znakem A, který je opakován 27x.
a
/A{3,}/ se shoduje se znakem A, který je opakován 3x.
{n,n}
/A{3,5}/ se shoduje se znakem A, který je opakován 3x až 5x.
Další informace naleznete v části „Kvantifikátory“ na stránce 209.
\b
Shoduje se s pozicí mezi znakem sova a znakem jiným než znakem slova. Jestliže je první nebo poslední znak
v řetězci znak slova, shoduje se také se začátkem nebo koncem řetězce.
\B
Shoduje se s pozicí mezi dvěma znaky slova. Shoduje se také s pozicí mezi dvěma znaky, které nejsou znaky
slova.
\d
Shoduje se s desítkovou číslicí.
\D
Shoduje se s jakýmkoliv znakem jiným než číslice.
\f
Shoduje se se znakem kanálu formuláře.
\n
Shoduje se se znakem nového řádku.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 208
Používání regulárních výrazů
Metasekvence
Popis
\r
Shoduje se s návratovým znakem.
\s
Shoduje se s libovolným znakem bílého místa (mezera, tabulátor, nový řádek nebo návratový znak).
\S
Shoduje se s jakýmkoliv znakem jiným než znakem bílého místa
\t
Shoduje se se znakem tabulátoru.
\unnnn
Spáruje znak Unicode s kódem znaku určeným hexadecimálním číslem nnnn. Například \u263a je znak
smajlíka.
\v
Shoduje se se znakem vertikálního kanálu.
\w
Shoduje se se znakem slova (AZ–, az–, 0-9 nebo _). Všimněte si, že \w se neshoduje s neanglickými znaky,
například s é , ñ neboç.
\W
Shoduje se s jakýmkoliv znakem jiným než znakem slova.
\\xnn
Spáruje znak s určenou hodnotou ASCII, dle definice hexadecimálního čísla nn.
Třídy znaků
Třídy znaků můžete použít pro určení seznamu znaků, které odpovídají jedné poloze v regulárním výrazu. Třídy
znaků lze definovat pomocí hranatých závorek ( [ a ] ). Například následující regulární výraz definuje třídu znaků,
která se shoduje s bag, beg, big, bognebo bug:
/b[aeiou]g/
Escape sekvence v třídách znaků
Většina metaznaků a metasekvencí, které mají v regulárních výrazech běžně speciální význam, nemají tyto stejné
významy uvnitř třídy znaků. Například v regulárním výrazu je hvězdička použita pro opakování, ale to neplatí pro
hvězdičku ve třídě znaků. Následující třída znaků se literálově shoduje s hvězdičkou, společně s libovolným jiným
uvedeným znakem:
/[abc*123]/
Nicméně tři znaky uvedené v následující tabulce fungují jako metaznaky, se speciálním významem ve třídách znaků:
Metaznak
Metaznaky ve třídách znaků
]
Definuje konec třídy znaku.
-
Definuje rozmezí znaků (viz následující část „Rozmezí znaků ve třídách znaků“).
\
Definuje metasekvence a ruší speciální význam metaznaků.
Aby mohly být jakékoliv z těchto znaků rozpoznány jako znaky literálu (bez speciálního významu metaznaku), musíte
před tyto znaky umístit znak escape zpětného lomítka. Například následující regulární výraz zahrnuje třídu znaku,
která se shoduje s jakýmkoliv ze čtyř symbolů ($, \, ]nebo -):
/[$\\\]\-]/
Vedle metaznaků, které si zachovávají své speciální významy, fungují ve třídách znaků následující metasekvence:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 209
Používání regulárních výrazů
Metasekvence
Metaznaky ve třídách znaků
\n
Shoduje se se znakem nového řádku.
\r
Shoduje se se znakem vrácení.
\t
Shoduje se se znakem tabulátoru.
\unnnn
Spáruje znak s určenou hodnotou bodu kódu Unicode (dle definice hexadecimálního čísla nnnn).
\\xnn
Spáruje znak s určenou hodnotou ASCII (dle definice hexadecimálního čísla nn).
Jiné metasekvence a metaznaky regulárního výrazu jsou ve třídě znaku zpracovávány jako běžné znaky.
Rozmezí znaků ve třídách znaků
Pro určení rozmezí znaků, například A-Z, a-z nebo0-9, použijte pomlčku. Tyto znaky musí představovat platné
rozmezí znakové sady. Například následující třída znaků se shoduje s jakýmkoliv znakem v rozmezí a-z nebo s
jakoukoliv číslicí:
/[a-z0-9]/
Pro určení rozmezí dle hodnoty ASCII můžete také použít kód znaku ASCII \\xnn. Například následující třída znaků
se shoduje s jakýmkoliv znakem ze sady rozšířených znaků ASCII (například é a ê ):
\\x
Negované třídy znaků
Jestliže na začátku třídy znaku použijete znak stříšky (^), bude daná třída negována - jakýkoliv neuvedený znak bude
považován za shodu. Následující třída znaků se shoduje s jakýmkoliv znakem, s výjimkou malého písmena (az–) nebo
číslice:
/[^a-z0-9]/
Pro určení negace musíte znak stříšky (^) zapsat na začátek třídy znaků. V opačném případě jednoduše přidáte znak
stříšky ke znakům ve třídě znaků. Například následující třída znaků se shoduje s jakýmkoliv ze znaků symbolů, včetně
stříšky:
/[!.,#+*%$&^]/
Kvantifikátory
Kvantifikátory se používají pro určení opakování znaků nebo sekvencí ve vzorcích, a to následovně:
Metaznak kvantifikátoru
Popis
* (hvězda)
Spáruje se s předcházející položkou neopakovanou nebo opakovanou.
+ (plus)
Spáruje se s předcházející položkou opakovanou jednou nebo vícekrát.
? (otazník)
Spáruje se s předcházející položku neopakovanou nebo opakovanou jednou.
{n}
Určuje numerický kvantifikátor nebo rozsah kvantifikátoru pro předchozí položku:
{n,}
/A{27}/ se shoduje se znakem A, který je opakován 27x.
a
/A{3,}/ se shoduje se znakem A, který je opakován 3x nebo vícekrát.
{n,n}
/A{3,5}/ se shoduje se znakem A, který je opakován 3x až 5x.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 210
Používání regulárních výrazů
Kvantifikátor můžete použít na jediný znak, na třídu znaků nebo na skupinu:
•
/a+/ se shoduje se znakem a, který je opakován jednou nebo vícekrát.
•
/\d+/ odpovídá dvou nebo více číslicím.
•
/[abc]+/ odpovídá opakování jednoho nebo více znaků a každý z těchto znaku je buď a, b nebo c.
•
/(very, )*/ se shoduje s very následovaným čárkou a mezerou, které nejsou opakovány nebo jsou opakovány
vícekrát.
Kvantifikátory lze použít uvnitř seskupení kulatých závorek, na které jsou použity kvantifikátory. Například
následující kvantifikátor se shoduje s řetězci, například word a word-word-word:
/\w+(-\w+)*/
Regulární výrazy implicitně provádějí to, co se označuje za chamtivé srovnávání. Jakýkoliv dílčí vzorec v regulárním
výrazu (například .*) se snaží přiřadit se k co nejvíce znakům v řetězci před tím, než přejde k další části regulárního
výrazu. Zvažte například následující regulární výraz a řetězec:
var pattern:RegExp = /<p>.*<\/p>/;
str:String = "<p>Paragraph 1</p> <p>Paragraph 2</p>";
Regulární výraz se shoduje s celým řetězcem:
<p>Paragraph 1</p> <p>Paragraph 2</p>
Nicméně předpokládejme, že si přejete přiřadit pouze jedno seskupení <p>...</p>. Použít k tomu můžete následující:
<p>Paragraph 1</p>
Přidáním otazníku (?) za libovolný kvantifikátor jej změníte na to, čemu se říká líný kvantifikátor. Například
následující regulární výraz, který používá líný *? kvantifikátor, se shoduje s <p> následovaným minimálním možným
počtem znaků (líným), následovaným </p>:
/<p>.*?<\/p>/
O kvantifikátorech je třeba si zapamatovat následující body:
• Kvantifikátory {0} a {0,0} nevyřazují ze shody položku.
• Nekombinujte více kvantifikátorů, např. /abc+*/.
• znak tečka (.) nerozdělí řádky, pokud není nastaven příznak s (dotall), i v případě, že následuje kvantifikátor *.
Posuďte například následující kód:
var str:String = "<p>Test\n";
str += "Multiline</p>";
var re:RegExp = /<p>.*<\/p>/;
trace(str.match(re)); // null;
re = /<p>.*<\/p>/s;
trace(str.match(re));
// output: <p>Test
//
Multiline</p>
Více informací naleznete v části „Příznaky a vlastnosti“ na stránce 214.
Alternace
Spojovací znak | použijte v regulárním výrazu pro to, aby vyhledávač regulárního výrazu zvážil alternativy pro shodu.
Například následující regulární výraz odpovídá jakémukoliv ze slov cat, dog, pig, rat:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 211
Používání regulárních výrazů
var pattern:RegExp = /cat|dog|pig|rat/;
Pro definici skupin za účelem omezení rozsahu měniče | můžete použít kulaté závorky. Následující regulární výraz se
shoduje s cat a následně nap nebo nip:
var pattern:RegExp = /cat(nap|nip)/;
Další informace viz „Skupiny“ na stránce 211.
Následující dva regulární výrazy, jeden používající měnič |, druhý používající třídu znaků (definovanou pomocí [ a ]
), jsou ekvivalentní:
/1|3|5|7|9/
/[13579]/
Pro více informací viz „Třídy znaků“ na stránce 208.
Skupiny
Skupinu můžete v regulárním výraze určit pomocí kulatých závorek, viz dále:
/class-(\d*)/
Skupina je dílčí částí vzorce. Skupiny můžete použít k následujícím akcím:
• Pro použití kvantifikátoru na více než jeden znak.
• Pro načrtnutí dílčích vzorců, které budou použity s alternací (pomocí znaku |).
• Zachycení shod dílčích řetězců (například použitím \1 v regulárním výrazu pro přiřazení předešle přiřazené
skupiny nebo pomocí $1 obdobně v metodě replace() třídy String).
V následujících částech jsou uvedeny podrobnosti k těmto použitím skupin.
Používání skupin s kvantifikátory
Jestliže nepoužijete skupinu, kvantifikátor se použije na znak nebo třídu znaků, která mu předchází, viz následující
ukázka:
var pattern:RegExp = /ab*/ ;
// matches the character a followed by
// zero or more occurrences of the character b
pattern = /a\d+/;
// matches the character a followed by
// one or more digits
pattern = /a[123]{1,3}/;
// matches the character a followed by
// one to three occurrences of either 1, 2, or 3
Skupinu můžete nicméně použít k aplikaci kvantifikátoru na více než jeden znak nebo třídu znaků:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 212
Používání regulárních výrazů
var pattern:RegExp = /(ab)*/;
// matches zero or more occurrences of the character a
// followed by the character b, such as ababab
pattern = /(a\d)+/;
// matches one or more occurrences of the character a followed by
// a digit, such as a1a5a8a3
pattern = /(spam ){1,3}/;
// matches 1 to 3 occurrences of the word spam followed by a space
Více informací o kvantifikátorech naleznete v části „Kvantifikátory“ na stránce 209.
Použití skupin se znakem měniče (|)
Skupiny můžete použít k definici skupin znaků, na které si přejete použít znak měniče (|), a to následovně:
var pattern:RegExp = /cat|dog/;
// matches cat or dog
pattern = /ca(t|d)og/;
// matches catog or cadog
Používání skupin pro zachycení shod dílčího řetězce
Když ve vzorci definujete standardní skupinu kulatých závorek, můžete se na ni později odkázat v regulárním výrazu.
Tomu se říká zpětná referencea takové typy skupin jsou známé jako skupiny se zachycením. Například v následujícím
regulárním výrazu se sekvence \1 shoduje s čímkoliv, co dílčí řetězec přiřadil skupině kulatých závorek zachycení:
var pattern:RegExp = /(\d+)-by-\1/;
// matches the following: 48-by-48
V regulárním výrazu můžete určit až 99 takových zpětných referencí, a to zadáním \1, \2, ... , \99.
Obdobně můžete v metodě replace() třídy String použít $1$99– pro vložení zachycených shod dílčího řetězce
skupiny do nahrazujícího řetězce:
var pattern:RegExp = /Hi, (\w+)\./;
var str:String = "Hi, Bob.";
trace(str.replace(pattern, "$1, hello."));
// output: Bob, hello.
Jestliže používáte skupiny zachycení, vrátí metodaexec() třídy RegExp a metoda match() třídy String dílčí řetězce,
které odpovídají skupinám zachycení.
var pattern:RegExp = /(\w+)@(\w+).(\w+)/;
var str:String = "[email protected]";
trace(pattern.exec(str));
// [email protected],bob,example,com
Používání skupin bez zachycení a skupin dopředného vyhledávání
Skupina bez zachycení je skupina, která se používá pouze pro seskupování; není „shromažďována“ a neshoduje se s
očíslovanými zpětnými referencemi. Pro definici skupin bez zachycení použijte (?: a ), následovně:
var pattern = /(?:com|org|net);
Všimněte si například rozdílu mezi umístěním (com|org) ve skupině zachycení oproti skupině bez zachycení
(metoda exec() uvádí skupiny zachycení po kompletní shodě):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 213
Používání regulárních výrazů
var pattern:RegExp = /(\w+)@(\w+).(com|org)/;
var str:String = "[email protected]";
trace(pattern.exec(str));
// [email protected],bob,example,com
//noncapturing:
var pattern:RegExp = /(\w+)@(\w+).(?:com|org)/;
var str:String = "[email protected]";
trace(pattern.exec(str));
// [email protected],bob,example
Zvláštním typem skupiny bez zachycení je skupina dopředného vyhledávání, která má dva typy: pozitivní skupina
dopředného vyhledávání a negativní skupina dopředného vyhledávání.
Pro definici pozitivní skupiny dopředného vyhledávání použijte (?= a ), což určuje, že dílčí vzorec ve skupině musí
odpovídat poloze. Nicméně část řetězce, která odpovídá pozitivní skupině dopředného vyhledávání, se může shodovat
se zbylými vzorci v regulárním výrazu. Například protože (?=e) je pozitivní skupina dopředného vyhledávání, znak
e, který se s ní shoduje, může být ve shodě s následnou částí regulárního výrazu - v tomto případě se skupinou
zachycení, \w*):
var pattern:RegExp = /sh(?=e)(\w*)/i;
var str:String = "Shelly sells seashells by the seashore";
trace(pattern.exec(str));
// Shelly,elly
Pro definici negativní skupiny dopředného vyhledávání použijte (?! a ), což určuje, že dílčí vzorec ve skupině
nesmíodpovídat poloze. Například:
var pattern:RegExp = /sh(?!e)(\w*)/i;
var str:String = "She sells seashells by the seashore";
trace(pattern.exec(str));
// shore,ore
Používání pojmenovaných skupin
Pojmenovaná skupina je typ skupiny v regulárním výrazu, které je udělen pojmenovaný identifikátor. Pro definici
pojmenované skupiny použijte (?P<name> a ). Například následující regulární výraz zahrnuje pojmenovanou
skupinu s identifikátorem nazvaným digits:
var pattern = /[a-z]+(?P<digits>\d+)[a-z]+/;
Při použití metody exec() je shodná pojmenovaná skupina přidána jako vlastnost pole result:
var myPattern:RegExp = /([a-z]+)(?P<digits>\d+)[a-z]+/;
var str:String = "a123bcd";
var result:Array = myPattern.exec(str);
trace(result.digits); // 123
Zde je další příklad, který používá dvě pojmenované skupiny, s identifikátory name a dom:
var emailPattern:RegExp =
/(?P<name>(\w|[_.\-])+)@(?P<dom>((\w|-)+))+\.\w{2,4}+/;
var address:String = "[email protected]";
var result:Array = emailPattern.exec(address);
trace(result.name); // bob
trace(result.dom); // example
Poznámka: Pojmenované skupiny nejsou součástí specifikací jazyka ECMAScript. Jedná se o funkci přidanou do jazyka
ActionScript 3.0.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 214
Používání regulárních výrazů
Příznaky a vlastnosti
Následující tabulka uvádí pět příznaků, které lze nastavit pro regulární výrazy. Ke každému příznaku lze získat přístup
jako k vlastnosti objektu regulárního výrazu.
Příznak
Vlastnost
Popis
g
global
Odpovídá více než jedné shodě.
i
ignoreCase
Shody citlivé na velikost písma Platí pro znaky A - Z a a - z, ale nikoliv pro rozšířené znaky, například É a
é .
m
multiline
Je-li tento příznak nastaven, mohou se $ a ^ shodovat se začátkem řádku, respektive s koncem řádku.
s
dotall
Je-li tento příznak nastaven, může . (tečka) odpovídat znaku nového řádku (\n).
x
extended
Povoluje rozšířené regulární výrazy. Do regulárního výrazu můžete zadat mezery, které jsou jako součást
vzorce ignorovány. Tím můžete zapsat kód regulárního výrazu čitelněji.
Upozorňujeme, že tyto vlastnosti jsou určené pouze ke čtení. Příznaky (g, i, m, s, x) můžete nastavit při nastavování
proměnné regulárního výrazu, a to následovně:
var re:RegExp = /abc/gimsx;
Pojmenované vlastnosti nemůžete nicméně nastavit přímo. Následující kód například vygeneruje chybu:
var re:RegExp = /abc/;
re.global = true; // This generates an error.
Pokud jste příznaky neurčili v deklaraci regulárního výrazu, příznaky nejsou implicitně nastaveny a odpovídající
vlastnosti jsou také nataveny na hodnotu false.
Dále existují dvě další vlastnosti regulárního výrazu:
• Vlastnost lastIndex určuje pozici indexu v řetězci, která bude použita pro další volání metody exec() nebo
test() regulárního výrazu.
• Vlastnost source určuje řetězec, který definuje část vzorce regulárního výrazu.
Příznak g (global)
Jestliže příznak g (global) není obsažen, regulární výraz nebude odpovídat více než jedné shodě. Například pokud
příznak g není zahrnut do regulárního výrazu, metoda String.match() vrátí pouze jeden shodný dílčí řetězec:
var str:String = "she sells seashells by the seashore.";
var pattern:RegExp = /sh\w*/;
trace(str.match(pattern)) // output: she
Je-li příznak g nastaven, metoda Sting.match() vrátí více shod, viz níže:
var str:String = "she sells seashells by the seashore.";
var pattern:RegExp = /sh\w*/g;
// The same pattern, but this time the g flag IS set.
trace(str.match(pattern)); // output: she,shells,shore
Příznak i (ignoreCase)
Shody regulárních výrazů implicitně zohledňují velká a malá písmena. Jestliže nastavíte příznak i (ignoreCase), bude
zohlednění malých a velkých písmen ignorováno. Například malé písmeno s v regulárním výrazu se neshoduje s
velkým písmenem S, prvním znakem řetězce:
var str:String = "She sells seashells by the seashore.";
trace(str.search(/sh/)); // output: 13 -- Not the first character
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 215
Používání regulárních výrazů
Je-li příznak i nastaven, regulární výraz se neshoduje s velkým písmenem S:
var str:String = "She sells seashells by the seashore.";
trace(str.search(/sh/i)); // output: 0
Příznak i ignoruje zohlednění velkých a malých písmen pouze pro znaky A–Z a a–z, ale nikoliv pro rozšířené znaky,
například É a é .
Příznak m (multiline)
Jestliže příznak m (multiline) není nastaven, znak ^ se shoduje se začátkem řetězce a znak $ se shoduje s koncem
řetězce. Je-li příznak m nastaven, shodují se tyto znaky se začátkem řádku, respektive s koncem řádku. Zvažte
následující řetězec, který zahrnuje znak nového řádku:
var str:String = "Test\n";
str += "Multiline";
trace(str.match(/^\w*/g)); // Match a word at the beginning of the string.
Ačkoliv je příznak g (global) v regulárním výrazu nastaven, metoda match() se shoduje pouze s jedním dílčím
řetězcem, protože pro znak ^existuje pouze jedna shoda - začátek řetězce. Výstup je následující:
Test
Zde je stejný kód s nastaveným příznakem m:
var str:String = "Test\n";
str += "Multiline";
trace(str.match(/^\w*/gm)); // Match a word at the beginning of lines.
Výstup tentokrát zahrnuje slova na začátku obou řádků:
Test,Multiline
Všimněte si, že pouze znak \n označuje konec řádku. Následující znaky konec řádku neoznačují:
• Znak vrácení (\r)
• Znak oddělovače řádku Unicode(\u2028)
• Znak oddělovače odstavce Unicode (\u2029)
Příznak s (dotall)
Jestliže příznak s (dotall nebo „dot all“) není nastaven, tečka (.) ve vzorci regulárního výrazu neodpovídá znaku
nového řádku (\n). Pro následující příklad tedy neexistuje žádná shoda:
var str:String = "<p>Test\n";
str += "Multiline</p>";
var re:RegExp = /<p>.*?<\/p>/;
trace(str.match(re));
Je-li příznak s nicméně nastaven, tečka se shoduje se znakem nového řádku:
var str:String = "<p>Test\n";
str += "Multiline</p>";
var re:RegExp = /<p>.*?<\/p>/s;
trace(str.match(re));
V tomto případě je shodou celý řetězec v rámci tagu <p>, včetně znaku nového řádku:
<p>Test
Multiline</p>
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 216
Používání regulárních výrazů
Příznak x (extended)
Regulární výrazy mohou být obtížné pro čtení, zvláště pokud obsahují mnoho metasymbolů a metasekvencí.
Například:
/<p(>|(\s*[^>]*>)).*?<\/p>/gi
Jestliže příznak x (extended) použijete v regulárním výrazu, budou jakákoliv prázdná místa, která zadáte do vzorce,
ignorována. Například následující regulární výraz je identický s předcházejícím příkladem:
/
<p
(>
|
(\s*
[^>]*
>))
.*?
<\/p>
/gix
Jestliže jste příznak x nastavili a přejete si jej přiřadit znaku prázdného místa, umístěte před prázdné místo zpětné
lomítko. Například následující dva regulární výrazy jsou rovnocenné:
/foo bar/
/foo \ bar/x
Vlastnost lastIndex
Vlastnost lastIndex určuje indexovou polohu v řetězci, ve které se má zahájit další hledání. Tato vlastnost ovlivňuje
metody exec() a test() volané na regulárním výrazu, který má příznak g nastaven na true. Posuďte například
následující kód:
var pattern:RegExp = /p\w*/gi;
var str:String = "Pedro Piper picked a peck of pickled peppers.";
trace(pattern.lastIndex);
var result:Object = pattern.exec(str);
while (result != null)
{
trace(pattern.lastIndex);
result = pattern.exec(str);
}
Vlastnost lastIndex je implicitně nastavena na hodnotu 0 (pro zahájení vyhledávání na začátku řetězce). Po každé
shodě je tato vlastnost nastavena na indexovou pozici za shodou. Proto je výstup pro předešlý kód následující:
0
5
11
18
25
36
44
Jestliže je příznak global nastaven na false, metody exec() a test() nepoužijí nebo nenastaví vlastnost
lastIndex.
Metody match(), replace()a search() třídy String zahájí veškerá vyhledávání na začátku řetězce, bez ohledu na
nastavení vlastnosti lastIndex regulárního výrazu použitého ve volání dané metody. (Nicméně metoda match()
nenastaví vlastnost lastIndex na hodnotu 0.)
Můžete nastavit vlastnost lastIndex tak, aby přizpůsobila počáteční pozici v řetězci pro porovnávání regulárního
výrazu.
Vlastnost zdroje
Vlastnost source určuje řetězec, který definuje část vzorce regulárního výrazu. Například:
var pattern:RegExp = /foo/gi;
trace(pattern.source); // foo
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 217
Používání regulárních výrazů
Metody pro použití regulárních výrazů s řetězci
Třída RegExp zahrnuje dvě metody: exec() a test().
Vedle metod exec() a test() třídy RegExp zahrnuje třída String následující metody, které vám umožňují přiřadit
regulární výrazy v řetězcích: match(), replace(), search() a splice().
Metoda test()
Metoda test() třídy RegExp jednoduše zkontroluje dodaný řetězec, zda obsahuje shodu pro daný regulární výraz.
Viz. následující kód:
var pattern:RegExp = /Class-\w/;
var str = "Class-A";
trace(pattern.test(str)); // output: true
Metoda exec()
Metoda exec() třídy RegExp zkontroluje dodaný řetězec, zda obsahuje shodu regulárního výrazu, a vrátí pole s
následujícími hodnotami:
• Odpovídajícím dílčím řetězcem
• Shody dílčího řetězce pro jakékoliv skupiny kulatých závorek v regulárním výrazu
Pole obsahuje také vlastnost index, která určuje indexovou pozici začátku shody dílčího řetězce.
Posuďte například následující kód:
var pattern:RegExp = /\d{3}\-\d{3}-\d{4}/; //U.S phone number
var str:String = "phone: 415-555-1212";
var result:Array = pattern.exec(str);
trace(result.index, " - ", result);
// 7-415-555-1212
Použijte několikrát hodnotu exec() pro přiřazení několika dílčích řetězců, je-li pro daný regulární výraz nastaven
příznak g (global):
var pattern:RegExp = /\w*sh\w*/gi;
var str:String = "She sells seashells by the seashore";
var result:Array = pattern.exec(str);
while (result != null)
{
trace(result.index, "\t", pattern.lastIndex, "\t", result);
result = pattern.exec(str);
}
//output:
// 0 3 She
// 10 19 seashells
// 27 35 seashore
Metody řetězců, které používají parametry RegExp
Následující metody třídy String přebírají regulární výrazy jako parametry: match(), replace(), search() a
split(). Více informací o těchto metodách naleznete v části „Vyhledání vzorků v řetězcích a nahrazení podřetězců“
na stránce 144.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 218
Používání regulárních výrazů
Příklad: analyzátor Wiki
Tento jednoduchý příklad konverze textu Wiki ukazuje několik využití regulárních výrazů:
• Převedení řádků textu, které odpovídají zdrojovému vzorci Wiki na příslušné výstupní řetězce HTML.
• Použití regulárního výrazu pro převedení vzorců URL na hyperlinkové tagy HTML <a>.
• Použití regulárního výrazu pro převedení řetězců amerického dolaru (například "$9.95") na řetězce Euro
(například "8.24 €").
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace WikiEditor lze nalézt ve složce Samples/WikiEditor. Aplikace sestává z následujících souborů:
Soubor
Popis
WikiEditor.mxml
Hlavní soubor aplikace v programu Flash (FLA) nebo Flex
(MXML).
nebo
WikiEditor.fla
com/example/programmingas3/regExpExamples/WikiParser.as
Třída, která zahrnuje metody používající regulární výrazy
pro převedení vzorců vstupního textu Wiki na
ekvivalentní výstup HTML.
com/example/programmingas3/regExpExamples/URLParser.as
Třída obsahující metody používající regulární výrazy pro
převedení řetězců URL na hyperlinkové tagy HTML <a>.
com/example/programmingas3/regExpExamples/CurrencyConverter.as
Třída obsahující metody používající regulární výrazy pro
převedení řetězců amerického dolaru na Euro.
Definice třídy WikiParser
Třída WikiParser zahrnuje metody, které převádějí vstupní text Wiki na ekvivalentní výstup HTML. Nejedná se o
masivní aplikaci převodu Wiki, ale ukazuje některá dobrá využití regulárních výrazů pro párování vzorců a převod
řetězců.
Funkce konstruktoru, společně s metodousetWikiData(), jednoduše inicializuje ukázkový řetězec vstupního textu
Wiki, a to následovně:
public function WikiParser()
{
wikiData = setWikiData();
}
Když uživatel ve vzorové aplikaci klepne na tlačítko Test, aplikace iniciuje metodu parseWikiString() objektu
WikiParser. Tato metoda volá několik jiných metod, které zase sestaví výsledný řetězec HTML.
public function parseWikiString(wikiString:String):String
{
var result:String = parseBold(wikiString);
result = parseItalic(result);
result = linesToParagraphs(result);
result = parseBullets(result);
return result;
}
Každá z volaných metod - parseBold(), parseItalic(), linesToParagraphs() a parseBullets() - používají
metodu replace() řetězce pro nahrazení shodných vzorců, definovaných regulárním výrazem, pro převedení vstupu
textu Wiki do textu formátovaného v HTML.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 219
Používání regulárních výrazů
Převedení vzorců tučného písma a kurzívy
Metoda parseBold() vyhledá textový vzorec Wiki tučného textu (například '''foo''') a převede jej do ekvivalentu
HTML (například <b>foo</b>), následovně:
private function parseBold(input:String):String
{
var pattern:RegExp = /'''(.*?)'''/g;
return input.replace(pattern, "<b>$1</b>");
}
Všimněte si, že část regulárního výrazu (.?*) odpovídá libovolnému počtu znaků (*) mezi dvěma definujícími '''
vzorci. Kvantifikátor ? provede přiřazení nechamtivě, takže například pro řetězec '''aaa''' bbb '''ccc''' bude
první souhlasný řetězec'''aaa''' a nikoliv celý řetězec (který začíná a končí vzorcem ''').
Kulaté závorky v regulárním výrazu definují skupinu zachycení a metoda replace() odkazuje na tuto skupinu
pomocí kódu $1 v náhradním řetězci. Příznak g (global) v regulárním výrazu zajistí, že metoda replace() nahradí
všechny shody v řetězci (ne pouze první shodu).
Metoda parseItalic() pracuje podobně jako metoda parseBold() s výjimkou, že jako oddělovač pro text kurzívy
vyhledá dva apostrofy ('') (nikoliv tři):
private function parseItalic(input:String):String
{
var pattern:RegExp = /''(.*?)''/g;
return input.replace(pattern, "<i>$1</i>");
}
Převádění vzorků odrážek
Jak ukazuje následující příklad, metoda parseBullet() vyhledá vzorec řádku odrážky Wiki (například * foo) a
převede jej do ekvivalentu HTML (například <li>foo</li>):
private function parseBullets(input:String):String
{
var pattern:RegExp = /^\*(.*)/gm;
return input.replace(pattern, "<li>$1</li>");
}
Symbol ^ na začátku regulárního výrazu se shoduje se začátkem řádku. Příznak m (multiline) v regulárním výrazu
způsobí, že se bude regulární výraz shodovat se symbolem ^ oproti začátku řádku, ne pouze jednoduše se začátkem
řetězce.
Vzorec \* se shoduje se znakem hvězdičky (zpětné lomítko je použito pro označení hvězdičky literálu namísto *
kvantifikátoru).
Kulaté závorky v regulárním výrazu definují skupinu zachycení a metoda replace() odkazuje na tuto skupinu
pomocí kódu $1 v náhradním řetězci. Příznak g (global) v regulárním výrazu zajistí, že metoda replace() nahradí
všechny shody v řetězci (ne pouze první shodu).
Převádění vzorců odstavce Wiki
Metoda linesToParagraphs() převede každý řádek ve vstupním řetězci Wiki na tag odstavce HTML <p>. Tyto
řádky v metodě vyskriptují prázdné řádky ze vstupního řetězce Wiki:
var pattern:RegExp = /^$/gm;
var result:String = input.replace(pattern, "");
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 220
Používání regulárních výrazů
Symboly ^ a $ regulárního výrazu se shodují se začátkem a koncem řádku. Příznak m (multiline) v regulárním výrazu
způsobí, že se bude regulární výraz shodovat se symbolem ^ oproti začátku řádku, ne pouze jednoduše se začátkem
řetězce.
Metoda replace() nahradí všechny shodující se dílčí řetězce (prázdné řádky) prázdným řetězcem (""). Příznak g
(global) v regulárním výrazu zajistí, že metoda replace() nahradí všechny shody v řetězci (ne pouze první shodu).
Převádění URL na tagy HTML <a>
Když uživatel klepne v ukázkové aplikaci na tlačítko Test, jestliže zaškrtl políčko urlToATag, aplikace volá statickou
metodu URLParser.urlToATag() pro převedení řetězců URL ze vstupního řetězce Wiki na tagy HTML <a>.
var
var
var
var
var
protocol:String = "((?:http|ftp)://)";
urlPart:String = "([a-z0-9_-]+\.[a-z0-9_-]+)";
optionalUrlPart:String = "(\.[a-z0-9_-]*)";
urlPattern:RegExp = new RegExp(protocol + urlPart + optionalUrlPart, "ig");
result:String = input.replace(urlPattern, "<a href='$1$2$3'><u>$1$2$3</u></a>");
Funkce konstruktoru RegExp() se používá pro sestavení regulárního výrazu (urlPattern) z několika složkových
částí. Tyto složkové části jsou každá řetězcem, který definuje část vzorce regulárního výrazu.
První část vzorce regulárního výrazu, definovaná řetězcem protocol, definuje protokol URL: buď http:// nebo
ftp://. Kulaté závorky definují skupinu bez zachycení, označenou symbolem ? symbol. To znamená, že kulaté
závorky jsou jednoduše použity k definování skupiny pro vzorec alternace |; skupina se nebude shodovat s kódy
zpětné reference ($1, $2, $3) v náhradním řetězci metody replace().
Každá z dalších složkových částí regulárního výrazu používá skupiny zachycení (označené ve vzorci kulatými
závorkami), které jsou poté použity v kódech zpětné reference ($1, $2, $3) v náhradním řetězci metody replace().
Část vzorce definovaná řetězcem urlPart se shoduje minimálně s jedním z následujících znaků: a-z, 0-9, _ nebo -.
Kvantifikátor + označuje, že byl přiřazen minimálně jeden znak. \. označuje požadovaný znak tečky (.). A zbytek se
shoduje s dalším řetězcem minimálně s jedním z těchto znaků: a-z, 0-9, _ nebo -.
Část vzorce definovaná řetězcem optionalUrlPart se shoduje s nulou nebo více následujících prvků: tečka (.) znak
následovaný libovolným počtem alfanumerických znaků (včetně _ a -). Kvantifikátor * označuje, že bylo přiřazeno
nula nebo více znaků.
Volání metody replace() použije regulární výraz a pomocí zpětných referencí sestaví náhradní řetězec HTML.
Metoda urlToATag() poté volá metodu emailToATag(), která používá podobné techniky pro nahrazení vzorců emailu hyperlinkovými řetězci HTML <a>. Regulární výrazy použité pro přiřazení HTTP, FTP a URL e-mailu v tomto
ukázkovém souboru jsou za účelem znázornění jednoduché; pro přesnější přiřazení takových URL existují o mnoho
komplikovanější regulované výrazy.
Převedení řetězců amerického dolaru na řetězce Euro.
Když uživatel klepne v ukázkové aplikaci na tlačítko Test, jestliže zaškrtl políčko dollarToEuro , aplikace volá
statickou metodu CurrencyConverter.usdToEuro() pro převedení řetězců amerického dolaru (například "$9.95")
na řetězce Euro (například "8.24 €"), a to následovně:
var usdPrice:RegExp = /\$([\d,]+.\d+)+/g;
return input.replace(usdPrice, usdStrToEuroStr);
První řádek definuje jednoduchý vzorec pro přiřazení řetězců amerického dolaru. Všimněte si, že znaku $ předchází
znak escape zpětného lomítka (\).
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 221
Používání regulárních výrazů
Metoda replace() používá regulární výraz jako objekt přiřazení vzorce a volá funkci usdStrToEuroStr() pro
stanovení náhradního řetězce (hodnota v Eur).
Je-li jako druhý parametr metody replace() použit název funkce, jsou následující hodnoty předány jako parametry
volané funkci:
• Vyhovující část řetězce.
• Libovolná zachycená skupina kulatých závorek se shoduje. Počet argumentů předaných tímto způsobem se bude
měnit v závislosti na počtu zachycených shod skupiny kulatých závorek. Počet zachycených shod skupiny kulatých
závorek můžete určit ověřením arguments.length - 3 uvnitř kódu funkce.
• Indexová pozice v řetězci, kde začíná shoda.
• Úplný řetězec.
Metoda usdStrToEuroStr() převede vzorce řetězce amerického dolaru na řetězce Euro, a to následovně:
private function usdToEuro(...args):String
{
var usd:String = args[1];
usd = usd.replace(",", "");
var exchangeRate:Number = 0.828017;
var euro:Number = Number(usd) * exchangeRate;
trace(usd, Number(usd), euro);
const euroSymbol:String = String.fromCharCode(8364); // €
return euro.toFixed(2) + " " + euroSymbol;
}
Všimněte si, že args[1] představuje zachycenou skupinu přiřazenou pomocí regulárního výrazu usdPrice. Jedná se
o numerickou část řetězce amerického dolaru: tj. částku v dolarech se znakem $. Metoda použije převod směnného
kurzu a vrátí výsledný řetězec (s koncovým symbolem € namísto vedoucího symbolu $).
222
Kapitola 11: Práce s jazykem XML
ActionScript 3.0 obsahuje skupinu tříd založených na specifikaci ECMAScript pro XML (E4X) (ECMA-357, vydání
2). Tyto třídy zahrnují výkonné a snadno použitelné funkce pro práci s daty XML. Pomocí E4X budete schopni vytvořit
kód s daty XML rychleji než s předchozími programovacími postupy. Další výhodou je to, že vytvořený kód bude snáze
čitelný.
Tato kapitola popisuje způsob použití specifikace E4X ke zpracování dat XML.
Základy jazyka XML
Úvod do práce s jazykem XML
Jazyk XML představuje standardní způsob vyjádření strukturovaných informací, aby byly snadno zpracovatelné pro
počítače a poměrně snadno zapisovatelné a pochopitelné pro lidi. XML je zkratka pro eXtensible Markup Language
(rozšiřitelný značkovací jazyk). Standard XML je dostupný na adrese www.w3.org/XML/.
XML nabízí standardní a pohodlný způsob kategorizace dat, aby byla snáze čitelná, přístupná a zpracovatelná. XML
používá podobnou stromovou strukturu a strukturu tagů jako jazyk HTML. Zde je jednoduchá ukázka dat XML:
<song>
<title>What you know?</title>
<artist>Steve and the flubberblubs</artist>
<year>1989</year>
<lastplayed>2006-10-17-08:31</lastplayed>
</song>
Data XML mohou být také mnohem složitější, s tagy vnořenými do jiných tagů, jakož i atributy a dalšími strukturními
komponentami. Zde je složitější ukázka dat XML:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 223
Práce s jazykem XML
<album>
<title>Questions, unanswered</title>
<artist>Steve and the flubberblubs</artist>
<year>1989</year>
<tracks>
<song tracknumber="1" length="4:05">
<title>What do you know?</title>
<artist>Steve and the flubberblubs</artist>
<lastplayed>2006-10-17-08:31</lastplayed>
</song>
<song tracknumber="2" length="3:45">
<title>Who do you know?</title>
<artist>Steve and the flubberblubs</artist>
<lastplayed>2006-10-17-08:35</lastplayed>
</song>
<song tracknumber="3" length="5:14">
<title>When do you know?</title>
<artist>Steve and the flubberblubs</artist>
<lastplayed>2006-10-17-08:39</lastplayed>
</song>
<song tracknumber="4" length="4:19">
<title>Do you know?</title>
<artist>Steve and the flubberblubs</artist>
<lastplayed>2006-10-17-08:44</lastplayed>
</song>
</tracks>
</album>
Všimněte si, že tento dokument XML v sobě zahrnuje další kompletní struktury XML (např. tagy song s jejich
podřízenými objekty). Znázorňuje také další struktury XML, jako jsou atributy (tracknumber a length uvnitř tagů
song) a tagy, jež obsahují další tagy spíše než data (např. tag tracks).
Začínáme s jazykem XML
Nemáte-li s jazykem XML žádné nebo máte jen malé zkušenosti, zde je stručný popis nejčastějších aspektů dat XML.
Data XML jsou napsána jako prostý text, se specifickou syntaxí pro uspořádání informací do strukturovaného
formátu. Jediná sada dat XML se obecně označuje jako dokument XML. Ve formátu XML jsou data uspořádána do
elementů (což mohou být jednotlivé datové položky nebo kontejnery pro další elementy) za použití hierarchické
struktury. Každý dokument XML má jediný element jako položku nejvyšší úrovně nebo hlavní položku. Uvnitř tohoto
kořenového elementu může být jediná informace, ale pravděpodobněji v něm budou další elementy, které zase
obsahují jiné elementy atd. Tento dokument XML například obsahuje informace o hudebním albu:
<song tracknumber="1" length="4:05">
<title>What do you know?</title>
<artist>Steve and the flubberblubs</artist>
<mood>Happy</mood>
<lastplayed>2006-10-17-08:31</lastplayed>
</song>
Jednotlivé elementy jsou odlišeny sadou tagů – název elementu uzavřený v lomených závorkách (znaménka méně než
a více než). Počáteční tag, který označuje začátek elementu, má název elementu:
<title>
Koncový tag, jenž označuje konec elementu, má před názvem elementu lomítko:
</title>
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 224
Práce s jazykem XML
Jestliže element nemá žádný obsah, může být zapsán jako prázdný element (někdy zvaný samouzavírací element). V
jazyce XML je tento element:
<lastplayed/>
stejný jako tento element:
<lastplayed></lastplayed>
Kromě obsahu elementu umístěného mezi počátečním a koncovým tagem může element zahrnovat také další
hodnoty, označované jako atributy, které jsou definovány v počátečním tagu elementu. Tento element XML například
definuje jediný atribut s názvem length, jehož hodnota je "4:19":
<song length="4:19"></song>
Každý element XML má obsah, což je buďto jediná hodnota, jeden či více elementů XML nebo nic (u prázdného
elementu).
Další informace o jazyce XML
Jestliže chcete získat více informací o práci s jazykem XML, je k dispozici celá řada dalších publikací a zdrojů
obsahujících další podrobnosti o jazyce XML, včetně následujících webových míst:
• Výuková lekce XML W3Schools: http://w3schools.com/xml/
• XML.com: http://www.xml.com/
• Výukové lekce XMLpitstop, seznamy diskusí a další zdroje: http://xmlpitstop.com/
Třídy ActionScript pro práci s jazykem XML
ActionScript 3.0 obsahuje několik tříd, které slouží pro práci s informacemi strukturovanými pomocí jazyka XML.
Dvě hlavní třídy jsou následující:
• XML: Představuje jediný element XML, což může být dokument XML s několika podřízenými dokumenty, nebo
element s jedinou hodnotou uvnitř dokumentu.
• XMLList: Představuje sadu elementů XML. Objekt XMLList se používá v případě, že existuje více elementů XML
na stejné úrovni (obsažených stejným nadřízeným objektem v hierarchii dokumentů XML). Instance objektu
XMLList například představuje nejsnazší způsob zpracování následující sady elementů XML (pravděpodobně
obsažených v dokumentu XML):
<artist type="composer">Fred Wilson</artist>
<artist type="conductor">James Schmidt</artist>
<artist type="soloist">Susan Harriet Thurndon</artist>
Pro pokročilejší použití zahrnující jmenné prostory XML obsahuje ActionScript také třídy Namespace a QName. Další
informace naleznete v sekci „Použití jmenných prostorů XML“ na stránce 237.
Kromě těchto vestavěných tříd pro práci s jazykem XML zahrnuje ActionScript 3.0 také několik operátorů
poskytujících specifickou funkčnost pro přístup k datům XML a jejich zpracování. Tento přístup k práci s jazykem
XML pomocí těchto tříd a operátorů se nazývá ECMAScript pro XML (E4X) podle definice ve specifikaci ECMA-357,
vydání 2.
Běžné úlohy XML
Při práci s jazykem XML v jazyce ActionScript se budou pravděpodobně provádět následující úlohy:
• Tvorba dokumentu XML (přidání elementů a hodnot)
• Přístup k elementům XML, hodnotám a atributům
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 225
Práce s jazykem XML
• Filtrování (vyhledávání) elementů XML
• Opakování sady elementů XML
• Převádění dat mezi třídami XML a třídou String
• Práce s jmennými prostory XML
• Načtení externích souborů XML
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny používané v této kapitole:
• Element: Jediná položka v dokumentu XML, identifikovaná jako obsah umístěný mezi počátečním tagem a
koncovým tagem (včetně samotných tagů). Elementy XML mohou obsahovat textová data či jiné elementy, nebo
mohou být prázdné.
• Prázdný element: Element XML, který neobsahuje žádné podřízené elementy. Prázdné elementy jsou často napsány
jako samouzavírací tagy (např. <element/>).
• Dokument: Jediná struktury XML. Dokument XML může obsahovat libovolný počet elementů (nebo jej může
tvořit pouze jediný prázdný element), ale musí mít jeden element nejvyšší úrovně, který bude obsahovat všechny
ostatní elementy v tomto dokumentu.
• Uzel: Jiný název pro element XML.
• Atribut: Pojmenovaná hodnota přiřazená k elementu, která je zapsána do počátečního tagu elementu ve formátu
attributename="value" místo toho, aby byla zapsána jako samostatný podřízený element vnořený v elementu.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. V
podstatě všechny výpisy kódů uvedené v této kapitole již zahrnují příslušné volání funkce trace(). Návod na
vyzkoušení kódů uvedených v této kapitole:
1 Vytvořte prázdný dokument Flash.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
Výsledky funkcetrace() se zobrazí v panelu Výstup.
Tyto a další postupy pro testování vzorových výpisů kódů jsou podrobněji popsány v sekci „Testování příkladů kódu
v této kapitole“ na stránce 34.
Přístup E4X ke zpracování XML
Specifikace ECMAScript pro XML definuje sadu tříd a funkce pro práci s daty XML. Tyto třídy a funkce se společně
nazývají E4X.ActionScript 3.0 zahrnuje následující třídy E4X: XML, XMLList, QName a Namespace.
Při navrhování metod, vlastností a operátorů tříd E4X byly sledovány následující cíle:
• Jednoduchost – Tam, kde je to možné, E4X usnadňuje zápis a pochopení kódu pro práci s daty XML.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 226
Práce s jazykem XML
• Jednotnost – Metody a argumenty v pozadí E4X jsou vnitřně jednotné a jsou v souladu s ostatními částmi jazyka
ActionScript.
• Povědomost – Data XML se zpracovávají pomocí dobře známých operátorů, jako je např. operátor tečka (.)
operátor.
Poznámka: V jazyce ActionScript 2.0 byla k dispozici třída XML. V jazyce ActionScript 3.0 byla tato třída přejmenována
na XMLDocument, aby nedocházelo ke konfliktům s třídou XML jazyka ActionScript 3.0, která je součástí E4X. Starší
třídy – XMLDocument, XMLNode, XMLParser a XMLTag – jsou v jazyce ActionScript 3.0 obsaženy v balíčku flash.xml,
a to zejména kvůli podpoře starších verzí. Nové třídy E4X jsou základní třídy, takže k jejich použití není zapotřebí
provádět import balíčku. Tato kapitola se nezabývá podrobnostmi o starších třídách XML verze ActionScript 2.0.
Podrobnosti o nich naleznete v sekci věnované balíčku balík flash.xml v Referenční příručce jazyka ActionScript 3.0 a jeho
komponent.
Zde je příklad zpracování dat pomocí E4X:
var myXML:XML =
<order>
<item id='1'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<item id='2'>
<menuName>fries</menuName>
<price>1.45</price>
</item>
</order>
Aplikace bude často načítat data XML z externího zdroje, např. z webové služby nebo kanálu RSS. Kvůli větší
srozumitelnosti však příklady v této kapitole přiřazují data XML jako literály.
Jak je znázorněno v následujícím kódu, E4X zahrnuje několik intuitivních operátorů, např. operátory tečka (.) a
identifikátor atributu (@), pro přístup k vlastnostem a atributům v jazyce XML:
trace(myXML.item[0].menuName); // Output: burger
trace(myXML.item.(@id==2).menuName); // Output: fries
trace(myXML.item.(menuName=="burger").price); // Output: 3.95
Metoda appendChild() slouží k přiřazení nového podřízeného uzlu k objektu XML, jak ilustruje následující
výstřižek:
var newItem:XML =
<item id="3">
<menuName>medium cola</menuName>
<price>1.25</price>
</item>
myXML.appendChild(newItem);
Operátory @ a .slouží nejen ke čtení dat, ale také k přiřazování dat, jako v následujícím příkladu:
myXML.item[0].menuName="regular burger";
myXML.item[1].menuName="small fries";
myXML.item[2].menuName="medium cola";
myXML.item.(menuName=="regular burger").@quantity = "2";
myXML.item.(menuName=="small fries").@quantity = "2";
myXML.item.(menuName=="medium cola").@quantity = "2";
Pomocí smyčky for lze iterovat uzly XML následujícím způsobem:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 227
Práce s jazykem XML
var total:Number = 0;
for each (var property:XML in myXML.item)
{
var q:int = Number(property.@quantity);
var p:Number = Number(property.price);
var itemTotal:Number = q * p;
total += itemTotal;
trace(q + " " + property.menuName + " $" + itemTotal.toFixed(2))
}
trace("Total: $", total.toFixed(2));
Objekty XML
Objekt XML může představovat element XML, atribut, komentář, příkaz zpracování nebo textový element.
Objekt XML je klasifikován jako objekt s jednoduchým obsahem nebo komplexním obsahem. Objekt XML, který má
podřízené uzly, je klasifikován jako objekt s komplexním obsahem. O objekt s jednoduchým obsahem se jedná v
případě, že jde o jeden z následujících objektů XML: atribut, komentář, příkaz zpracování nebo textový uzel.
Následující objekt XML má například komplexní obsah, včetně komentáře a příkazu zpracování:
XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
var x1:XML =
<order>
<!--This is a comment. -->
<?PROC_INSTR sample ?>
<item id='1'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<item id='2'>
<menuName>fries</menuName>
<price>1.45</price>
</item>
</order>
Jak je znázorněno v následujícím příkladu, pomocí metod comments() a processingInstructions() lze vytvářet
nové objekty XML, komentář a příkaz zpracování:
var x2:XML = x1.comments()[0];
var x3:XML = x1.processingInstructions()[0];
Vlastnosti XML
Třída XML má pět statických vlastností:
• Vlastnosti ignoreComments a ignoreProcessingInstructions určují, zda jsou při analýze objektu XML
ignorovány komentáře nebo příkazy zpracování.
• Vlastnost ignoreWhitespace určuje, zda budou ignorovány znaky prázdných míst uvnitř tagů elementů a
vnořené výrazy, které jsou odděleny pouze znaky prázdných míst.
• Vlastnosti prettyIndentaprettyPrinting slouží k formátování textu vráceného metodami toString() a
toXMLString() třídy XML.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 228
Práce s jazykem XML
Pro podrobnosti o těchto vlastnostech viz Referenční příručka jazyka ActionScript 3.0 a jeho komponent.
Metody XML
Následující metody umožňují práci s hierarchickou strukturou objektů XML:
•
appendChild()
•
child()
•
childIndex()
•
children()
•
descendants()
•
elements()
•
insertChildAfter()
•
insertChildBefore()
•
parent()
•
prependChild()
Následující metody umožňují práci s atributy objektu XML:
•
attribute()
•
attributes()
Následující metody umožňují práci s vlastnostmi objektu XML:
•
hasOwnProperty()
•
propertyIsEnumerable()
•
replace()
•
setChildren()
Následující metody jsou určeny pro práci s kvalifikovanými názvy a jmennými prostory:
•
addNamespace()
•
inScopeNamespaces()
•
localName()
•
name()
•
namespace()
•
namespaceDeclarations()
•
removeNamespace()
•
setLocalName()
•
setName()
•
setNamespace()
Následující metody umožňují zpracování a stanovení určitých typů obsahu XML:
•
comments()
•
hasComplexContent()
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 229
Práce s jazykem XML
•
hasSimpleContent()
•
nodeKind()
•
processingInstructions()
•
text()
Následující metody slouží k převádění na řetězce a k formátování objektů XML:
•
defaultSettings()
•
setSettings()
•
settings()
•
normalize()
•
toString()
•
toXMLString()
K dispozici je i několik dalších metod:
•
contains()
•
copy()
•
valueOf()
•
length()
Pro podrobnosti o těchto metodách viz Referenční příručka jazyka ActionScript 3.0 a jeho komponent.
Objekty XMLList
Instance XMLList představuje libovolnou kolekci objektů XML. Může obsahovat úplné dokumenty XML, fragmenty
XML nebo výsledky dotazu XML.
Následující metody umožňují práci s hierarchickou strukturou objektů XMLList:
•
child()
•
children()
•
descendants()
•
elements()
•
parent()
Následující metody umožňují práci s atributy objektu XMLList:
•
attribute()
•
attributes()
Následující metody umožňují práci s vlastnostmi objektu XMLList:
•
hasOwnProperty()
•
propertyIsEnumerable()
Následující metody umožňují zpracování a stanovení určitých typů obsahu XML:
•
comments()
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 230
Práce s jazykem XML
•
hasComplexContent()
•
hasSimpleContent()
•
processingInstructions()
•
text()
Následující metody slouží k převádění na řetězce a k formátování objektu XMLList:
•
normalize()
•
toString()
•
toXMLString()
K dispozici je i několik dalších metod:
•
contains()
•
copy()
•
length()
•
valueOf()
Pro podrobnosti o těchto metodách viz Referenční příručka jazyka ActionScript 3.0 a jeho komponent.
Pro objekt XMLList obsahující přesně jeden element XML lze použít všechny vlastnosti a metody třídy XML, neboť
objekt XMLList s jedním elementem XML je považován za objekt XML. Například v následujícím kódu, jelikož
doc.div je objekt XMLList obsahující jeden element, lze použít metodu appendChild() ze třídy XML:
var doc:XML =
<body>
<div>
<p>Hello</p>
</div>
</body>;
doc.div.appendChild(<p>World</p>);
Seznam vlastností a metod XML naleznete v sekci „Objekty XML“ na stránce 227.
Inicializace proměnných XML
Objektu XML lze přiřadit literál XML následujícím způsobem:
var myXML:XML =
<order>
<item id='1'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<item id='2'>
<menuName>fries</menuName>
<price>1.45</price>
</item>
</order>
Jak ilustruje následující výstřižek, pomocí konstruktoru new lze vytvořit instanci objektu XML z řetězce obsahujícího
data XML:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 231
Práce s jazykem XML
var str:String = "<order><item id='1'><menuName>burger</menuName>"
+ "<price>3.95</price></item></order>";
var myXML:XML = new XML(str);
Nejsou-li data XML v řetězci správně zformovaná (např. pokud chybí koncový tag), dojde k chybě chodu programu.
Data lze do objektu XML rovněž předávat podle odkazu (z jiných proměnných), jak znázorňuje následující příklad:
var tagname:String = "item";
var attributename:String = "id";
var attributevalue:String = "5";
var content:String = "Chicken";
var x:XML = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
trace(x.toXMLString())
// Output: <item id="5">Chicken</item>
K načítání dat XML z URL slouží třída URLLoader, jak ilustruje následující příklad:
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
var externalXML:XML;
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest("xmlFile.xml");
loader.load(request);
loader.addEventListener(Event.COMPLETE, onComplete);
function onComplete(event:Event):void
{
var loader:URLLoader = event.target as URLLoader;
if (loader != null)
{
externalXML = new XML(loader.data);
trace(externalXML.toXMLString());
}
else
{
trace("loader is not a URLLoader!");
}
}
Ke čtení dat XML ze soketového připojení použijte třídu XMLSocket. Další informace naleznete u třídy třída
XMLSocket v Referenční příručce jazyka ActionScript 3.0 a jeho komponent.
Sestavování a transformace objektů XML
Pomocí metody prependChild() nebo appendChild() lze přidat vlastnost na začátek nebo na konec seznamu
vlastností objektu XML, jak znázorňuje následující příklad:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 232
Práce s jazykem XML
var
var
var
x =
x =
x =
x1:XML = <p>Line 1</p>
x2:XML = <p>Line 2</p>
x:XML = <body></body>
x.appendChild(x1);
x.appendChild(x2);
x.prependChild(<p>Line 0</p>);
// x == <body><p>Line 0</p><p>Line 1</p><p>Line 2</p></body>
Pomocí metody insertChildBefore() nebo insertChildAfter() lze přidat vlastnost před nebo za určenou
vlastnost následujícím způsobem:
var x:XML =
<body>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</body>
var newNode:XML = <p>Paragraph 1.5</p>
x = x.insertChildAfter(x.p[0], newNode)
x = x.insertChildBefore(x.p[2], <p>Paragraph 1.75</p>)
Jak je znázorněno v následujícím příkladu, při sestavování objektů XML je rovněž možné použít operátory složené
závorky ( { a } ) k předávání dat podle odkazu (z jiných proměnných):
var ids:Array = [121, 122, 123];
var names:Array = [["Murphy","Pat"], ["Thibaut","Jean"], ["Smith","Vijay"]]
var x:XML = new XML("<employeeList></employeeList>");
for (var i:int = 0; i < 3; i++)
{
var newnode:XML = new XML();
newnode =
<employee id={ids[i]}>
<last>{names[i][0]}</last>
<first>{names[i][1]}</first>
</employee>;
x = x.appendChild(newnode)
}
Pomocí operátoru = lze objektu XML přiřadit vlastnosti a atributy, jako v následujícím příkladu:
var x:XML =
<employee>
<lastname>Smith</lastname>
</employee>
x.firstname = "Jean";
x.@id = "239";
To nastaví objekt XMLx následujícím způsobem:
<employee id="239">
<lastname>Smith</lastname>
<firstname>Jean</firstname>
</employee>
Operátory + a += slouží k zřetězení objektů XMLList:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 233
Práce s jazykem XML
var x1:XML = <a>test1</a>
var x2:XML = <b>test2</b>
var xList:XMLList = x1 + x2;
xList += <c>test3</c>
To nastaví objekt XMLList xList následujícím způsobem:
<a>test1</a>
<b>test2</b>
<c>test3</c>
Procházení struktur XML
Jednou z výkonných funkcí jazyka XML je jeho schopnost poskytovat složitá, vnořená data pomocí lineárního řetězce
textových znaků. Po načtení dat do objektu XML ActionScript tato data analyzuje a načte jejich hierarchickou
strukturu do paměti (nebo vyvolá chybu chodu programu, pokud nejsou data XML správně zformovaná).
Operátory a metody objektů XML a XMLList usnadňují procházení struktury dat XML.
Operátor tečka (.) a operátor dceřiného mechanismu přístupu (..) slouží pro přístup k podřízeným vlastnostem
objektu XML. Zvažte následující objekt XML:
var myXML:XML =
<order>
<book ISBN="0942407296">
<title>Baking Extravagant Pastries with Kumquats</title>
<author>
<lastName>Contino</lastName>
<firstName>Chuck</firstName>
</author>
<pageCount>238</pageCount>
</book>
<book ISBN="0865436401">
<title>Emu Care and Breeding</title>
<editor>
<lastName>Case</lastName>
<firstName>Justin</firstName>
</editor>
<pageCount>115</pageCount>
</book>
</order>
Objekt myXML.book je objekt XMLList obsahující podřízené vlastnosti objektu myXML s názvem book. Jedná se o dva
objekty XML odpovídající dvěma vlastnostem book objektu myXML.
Objekt myXML..lastName je objekt XMLList obsahující všechny podřízené vlastnosti s názvem lastName. Jedná se o
dva objekty XML odpovídající dvěma vlastnostem lastName objektu myXML.
Objekt myXML.book.editor.lastName je objekt XMLList obsahující všechny podřízené objekty s názvem lastName
podřízených objektů s názvem editor podřízených objektů s názvembook objektu myXML: v tomto případě se jedná o
objekt XMLList obsahující pouze jeden objekt XML (vlastnost lastName s hodnotou „Case“).
Přístup k nadřízeným a podřízeným uzlům
Metoda parent() vrátí nadřízený objekt objektu XML.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 234
Práce s jazykem XML
Pomocí ordinálních hodnot indexu podřízeného seznamu lze získat přístup k určitým podřízeným objektům. Zvažte
například objekt XML myXML, který má dvě podřízené vlastnosti s názvem book. Každá podřízená vlastnost s názvem
book má přiřazeno pořadové číslo:
myXML.book[0]
myXML.book[1]
Chcete-li získat přístup k určitému prapotomkovi, můžete určit pořadová čísla pro název podřízeného objektu i
prapotomka:
myXML.book[0].title[0]
Jestliže však existuje jen jeden podřízený objekt objektu x.book[0] s názvem title, lze odkaz na index vynechat:
myXML.book[0].title
Stejně tak, pokud existuje jen jeden podřízený objekt „book“ objektu x a pokud má tento podřízený objekt jen jeden
objekt „title“, lze vynechat oba odkazy na index takto:
myXML.book.title
Metodu child() lze použít pro přechod k podřízeným objektům, jejichž názvy jsou založeny na proměnné nebo
výrazu, jak znázorňuje následující příklad:
var myXML:XML =
<order>
<book>
<title>Dictionary</title>
</book>
</order>;
var childName:String = "book";
trace(myXML.child(childName).title) // output: Dictionary
Přístup k atributům
Symbol @ (operátor identifikátor atributu) slouží pro přístup k atributům v objektu XML nebo XMLList, jak ilustruje
následující kód:
var employee:XML =
<employee id="6401" code="233">
<lastName>Wu</lastName>
<firstName>Erin</firstName>
</employee>;
trace(employee.@id); // 6401
Zástupný znak * lze použít se symbolem @ pro přístup ke všem atributům objektu XML nebo XMLList, jako v
následujícím kódu:
var employee:XML =
<employee id="6401" code="233">
<lastName>Wu</lastName>
<firstName>Erin</firstName>
</employee>;
trace(employee.@*.toXMLString());
// 6401
// 233
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 235
Práce s jazykem XML
Pomocí metody attribute() nebo attributes() lze získat přístup k určitému atributu nebo ke všem atributům
objektu XML nebo XMLList, jako v následujícím kódu:
var employee:XML =
<employee id="6401" code="233">
<lastName>Wu</lastName>
<firstName>Erin</firstName>
</employee>;
trace(employee.attribute("id")); // 6401
trace(employee.attribute("*").toXMLString());
// 6401
// 233
trace(employee.attributes().toXMLString());
// 6401
// 233
Všimněte si, že pro přístup k atributům je rovněž možné použít syntaxi znázorněnou v následujícím příkladu:
employee.attribute("id")
employee["@id"]
employee.@["id"]
Každý z nich se rovná employee.@id. Použití syntaxe employee.@id je však vhodnější.
Filtrování podle hodnoty atributu nebo elementu
Pomocí operátorů závorky – ( a ) – lze filtrovat elementy s určitým názvem elementu nebo s určitou hodnotou
atributu. Zvažte následující objekt XML:
var x:XML =
<employeeList>
<employee id="347">
<lastName>Zmed</lastName>
<firstName>Sue</firstName>
<position>Data analyst</position>
</employee>
<employee id="348">
<lastName>McGee</lastName>
<firstName>Chuck</firstName>
<position>Jr. data analyst</position>
</employee>
</employeeList>
Platné jsou všechny následující výrazy:
•
x.employee.(lastName == "McGee") – Toto je druhý uzel employee.
•
x.employee.(lastName == "McGee").firstName – Toto je vlastnost firstName druhého uzlu employee.
•
x.employee.(lastName == "McGee").@id – Toto je hodnota atributu id druhého uzlu employee.
•
x.employee.(@id == 347) – První uzel employee.
•
x.employee.(@id == 347).lastName – Toto je vlastnost lastName prvního uzlu employee.
•
x.employee.(@id > 300) – Toto je objekt XMLList s oběma vlastnostmi employee.
•
x.employee.(position.toString().search("analyst") > -1) – Toto je objekt XMLList s oběma
vlastnostmi position.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 236
Práce s jazykem XML
Jestliže se pokusíte filtrovat atributy nebo elementy, které neexistují, aplikace Flash® Player a Adobe® AIR™ vyvolají
výjimku. Například poslední řádek následujícího kódu vygeneruje chybu, protože ve druhém elementu p neexistuje
žádný atribut id:
var doc:XML =
<body>
<p id='123'>Hello, <b>Bob</b>.</p>
<p>Hello.</p>
</body>;
trace(doc.p.(@id == '123'));
Stejně tak vygeneruje chybu i poslední řádek následujícího kódu, neboť neexistuje žádná vlastnost b druhého elementu p:
var doc:XML =
<body>
<p id='123'>Hello, <b>Bob</b>.</p>
<p>Hello.</p>
</body>;
trace(doc.p.(b == 'Bob'));
Aby k těmto chybám nedošlo, lze identifikovat vlastnosti, jež mají odpovídající atributy nebo elementy, pomocí metod
attribute() a elements(), jako v následujícím kódu:
var doc:XML =
<body>
<p id='123'>Hello, <b>Bob</b>.</p>
<p>Hello.</p>
</body>;
trace(doc.p.(attribute('id') == '123'));
trace(doc.p.(elements('b') == 'Bob'));
Rovněž lze použít metodu hasOwnProperty(), jako v následujícím kódu:
var doc:XML =
<body>
<p id='123'>Hello, <b>Bob</b>.</p>
<p>Hello.</p>
</body>;
trace(doc.p.(hasOwnProperty('@id') && @id == '123'));
trace(doc.p.(hasOwnProperty('b') && b == 'Bob'));
Použití příkazů for..in a for each..in
ActionScript 3.0 zahrnuje příkaz for..in a příkaz for each..in umožňující iteraci objektů XMLList. Zvažte
například následující objekt XML myXML a objekt XMLList myXML.item. Objekt XMLList myXML.item tvoří dva uzly
item objektu XML.
var myXML:XML =
<order>
<item id='1' quantity='2'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<item id='2' quantity='2'>
<menuName>fries</menuName>
<price>1.45</price>
</item>
</order>;
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 237
Práce s jazykem XML
Příkaz for..in umožňuje iteraci přes sadu názvů vlastností v objektu XMLList:
var total:Number = 0;
for (var pname:String in myXML.item)
{
total += myXML.item.@quantity[pname] * myXML.item.price[pname];
}
Příkaz for each..inumožňuje iteraci vlastností v objektu XMLList:
var total2:Number = 0;
for each (var prop:XML in myXML.item)
{
total2 += prop.@quantity * prop.price;
}
Použití jmenných prostorů XML
Jmenné prostory v objektu XML (nebo v dokumentu) označují typ dat, která tento objekt obsahuje. Například při
odesílání dat XML do webové služby používající protokol zpráv SOAP se deklaruje jmenný prostor v počátečním tagu
objektu XML:
var message:XML =
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body xmlns:w="http://www.test.com/weather/">
<w:getWeatherResponse>
<w:tempurature >78</w:tempurature>
</w:getWeatherResponse>
</soap:Body>
</soap:Envelope>;
Jmenný prostor má předponu soap a URI definující jmenný prostor
http://schemas.xmlsoap.org/soap/envelope/.
ActionScript 3.0 obsahuje třídu Namespace pro práci s jmennými prostory XML. Pro objekt XML v předchozím
příkladu lze třídu Namespace použít následujícím způsobem:
var soapNS:Namespace = message.namespace("soap");
trace(soapNS); // Output: http://schemas.xmlsoap.org/soap/envelope/
var wNS:Namespace = new Namespace("w", "http://www.test.com/weather/");
message.addNamespace(wNS);
var encodingStyle:XMLList = message.@soapNS::encodingStyle;
var body:XMLList = message.soapNS::Body;
message.soapNS::Body.wNS::GetWeatherResponse.wNS::tempurature = "78";
Třída XML zahrnuje následující metody pro práci s jmennými prostory: addNamespace(), inScopeNamespaces(),
localName(), name(), namespace(), namespaceDeclarations(), removeNamespace(), setLocalName(),
setName() a setNamespace().
Instrukce default xml namespace umožňuje přiřazení výchozího jmenného prostoru pro objekty XML. Například
v následujícím kódu mají oba objekty x1 i x2 stejný výchozí jmenný prostor:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 238
Práce s jazykem XML
var ns1:Namespace = new Namespace("http://www.example.com/namespaces/");
default xml namespace = ns1;
var x1:XML = <test1 />;
var x2:XML = <test2 />;
Převod typu XML
Objekty XML a objekty XMLList lze převádět na hodnoty String. Stejně tak je možné převádět řetězce na objekty XML
a XMLList. Rovněž je třeba mít na paměti, že všechny hodnoty atributů XML, názvy a textové hodnoty jsou řetězce.
Následující sekce pojednávají o všech těchto formách převodu typu XML.
Převádění objektů XML a XMLList na řetězce
Třídy XML a XMLList zahrnují metodu toString() a metodu toXMLString(). Metoda toXMLString() vrátí řetězec
zahrnující všechny tagy, atributy, deklarace jmenných prostorů a obsah objektu XML. U objektů XML s komplexním
obsahem (podřízené elementy) má metoda toString() stejný efekt jako metoda toXMLString() . U objektů XML
s jednoduchým obsahem (ty obsahují pouze jeden textový element) vrátí metoda toString() jen textový obsah
elementu, jak je znázorněno v následujícím příkladu:
var myXML:XML =
<order>
<item id='1' quantity='2'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<order>;
trace(myXML.item[0].menuName.toXMLString());
// <menuName>burger</menuName>
trace(myXML.item[0].menuName.toString());
// burger
Pokud použijete metodu trace() bez určení metody toString() nebo toXMLString(), budou data standardně
převedena pomocí metody toString(), jak ilustruje tento kód:
var myXML:XML =
<order>
<item id='1' quantity='2'>
<menuName>burger</menuName>
<price>3.95</price>
</item>
<order>;
trace(myXML.item[0].menuName);
// burger
Při použití metody trace() k ladění kódu je často vhodné použít metodu toXMLString(), protože metoda trace()
tak vygeneruje kompletnější data.
Převádění řetězců na objekty XML
Pomocí konstruktoru new XML() lze z řetězce vytvořit objekt XML následujícím způsobem:
var x:XML = new XML("<a>test</a>");
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 239
Práce s jazykem XML
Jestliže se pokusíte převést řetězec na XML z řetězce představujícího neplatný nebo nesprávně zformovaný objekt
XML, bude vyvolána výjimka:
var x:XML = new XML("<a>test"); // throws an error
Převádění hodnot atributů, názvů a textových hodnot z řetězců
Všechny hodnoty atributů XML, názvy a textové hodnoty jsou datové typy String a může být zapotřebí je převést na
jiné datové typy. Následující kód například převádí textové hodnoty na čísla pomocí funkce Number():
var myXML:XML =
<order>
<item>
<price>3.95</price>
</item>
<item>
<price>1.00</price>
</item>
</order>;
var total:XML = <total>0</total>;
myXML.appendChild(total);
for each (var item:XML in myXML.item)
{
myXML.total.children()[0] = Number(myXML.total.children()[0])
+ Number(item.price.children()[0]);
}
trace(myXML.total); // 4.35;
Kdyby nebyla v tomto kódu použita funkce Number(), kód by interpretoval operátor + jako operátor zřetězení řetězců
a metoda trace() v posledním řádku by pak vygenerovala následující výsledek:
01.003.95
Čtení externích dokumentů XML
Pomocí třídy URLLoader lze načíst data XML z URL. Chcete-li použít následující kód ve vlastní aplikaci, nahraďte
hodnotu XML_URL v tomto příkladu platnou adresou URL:
var myXML:XML = new XML();
var XML_URL:String = "http://www.example.com/Sample3.xml";
var myXMLURL:URLRequest = new URLRequest(XML_URL);
var myLoader:URLLoader = new URLLoader(myXMLURL);
myLoader.addEventListener("complete", xmlLoaded);
function xmlLoaded(event:Event):void
{
myXML = XML(myLoader.data);
trace("Data loaded.");
}
Pomocí třídy XMLSocket lze rovněž vytvořit asynchronní soketové připojení XML k serveru. Pro více informací viz
Referenční příručka jazyka ActionScript 3.0 a jeho komponent.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 240
Práce s jazykem XML
Příklad: Načtení dat RSS z Internetu
Vzorová aplikace RSSViewer znázorňuje několik funkcí pro práci s daty XML v jazyce ActionScript, včetně
následujících:
• Použití metod XML k procházení dat XML ve formě kanálu RSS.
• Použití metod XML k sestavování dat XML ve formě HTML pro jejich použití v textovém poli.
Formát RSS se obecně používá k publikování zpráv pomocí XML. Jednoduchý datový soubor RSS může vypadat
například takto:
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Alaska - Weather</title>
<link>http://www.nws.noaa.gov/alerts/ak.html</link>
<description>Alaska - Watches, Warnings and Advisories</description>
<item>
<title>
Short Term Forecast - Taiya Inlet, Klondike Highway (Alaska)
</title>
<link>
http://www.nws.noaa.gov/alerts/ak.html#A18.AJKNK.1900
</link>
<description>
Short Term Forecast Issued At: 2005-04-11T19:00:00
Expired At: 2005-04-12T01:00:00 Issuing Weather Forecast Office
Homepage: http://pajk.arh.noaa.gov
</description>
</item>
<item>
<title>
Short Term Forecast - Haines Borough (Alaska)
</title>
<link>
http://www.nws.noaa.gov/alerts/ak.html#AKZ019.AJKNOWAJK.190000
</link>
<description>
Short Term Forecast Issued At: 2005-04-11T19:00:00
Expired At: 2005-04-12T01:00:00 Issuing Weather Forecast Office
Homepage: http://pajk.arh.noaa.gov
</description>
</item>
</channel>
</rss>
Aplikace SimpleRSS čte data RSS z Internetu, analyzuje data pro titulky (nadpisy), odkazy a popisy a potom tato data
vrátí. Třída SimpleRSSUI poskytuje uživatelské rozhraní a volá třídu SimpleRSS, která provede veškeré zpracování XML.
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Aplikační soubory RSSViewer jsou umístěny ve složce Samples/RSSViewer. Aplikace sestává z následujících souborů:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 241
Práce s jazykem XML
Soubor
Popis
RSSViewer.mxml
Hlavní soubor aplikace v programu Flash (FLA) nebo Flex (MXML).
nebo
RSSViewer.fla
com/example/programmingas3/rssViewer/RSSParser.as
Třída obsahující metody, které pomocí E4X procházejí data RSS (XML) a
generují odpovídající HTML představující tato data.
RSSData/ak.rss
Vzorový soubor RSS. Tato aplikace je vytvořena tak, aby četla data RSS z
webu, na kanálu Flex RSS hostovaném aplikací Adobe. Aplikaci je však možné
snadno změnit, aby četla data RSS z tohoto dokumentu, který používá
poněkud odlišné schéma než kanál Flex RSS.
Čtení a analýza dat XML
Třída RSSParser zahrnuje metodu xmlLoaded(), která převádí vstupní data RSS uložená v proměnné rssXML na
řetězec obsahující výstup rssOutput zformátovaný pomocí HTML.
Kód nastaví na začátku této metody výchozí jmenný prostor XML, pokud zdrojová data RSS zahrnují výchozí jmenný
prostor:
if (rssXML.namespace("") != undefined)
{
default xml namespace = rssXML.namespace("");
}
Následující řádky pak vytvoří smyčku z obsahu zdrojových dat XML, přičemž zkoumají každou podřízenou vlastnost
s názvem item.
for each (var item:XML in rssXML..item)
{
var itemTitle:String = item.title.toString();
var itemDescription:String = item.description.toString();
var itemLink:String = item.link.toString();
outXML += buildItemHTML(itemTitle,
itemDescription,
itemLink);
}
První tři řádky jednoduše nastaví proměnné řetězce, aby představovaly vlastnosti titul, popis a odkaz vlastnosti item
dat XML. Následující řádek pak zavolá metodu buildItemHTML(), která vygeneruje data HTML ve formě objektu
XMLList, přičemž tři nové proměnné řetězce budou použity jako parametry.
Sestavování dat objektu XMLList
Data HTML (objekt XMLList) mají následující formu:
<b>itemTitle</b>
<p>
itemDescription
<br />
<a href="link">
<font color="#008000">More...</font>
</a>
</p>
První řádky metody vymažou výchozí jmenný prostor XML (default xml namespace):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 242
Práce s jazykem XML
default xml namespace = new Namespace();
Instrukce default xml namespace má rozsah funkce na úrovni bloku. To znamená, že rozsahem této deklarace je
metoda buildItemHTML().
Řádky, které následují, sestaví objekt XMLList na základě argumentů řetězce předaných do funkce:
var body:XMLList = new XMLList();
body += new XML("<b>" + itemTitle + "</b>");
var p:XML = new XML("<p>" + itemDescription + "</p>");
var link:XML = <a></a>;
link.@href = itemLink; // <link href="itemLinkString"></link>
link.font.@color = "#008000";
// <font color="#008000"></font></a>
// 0x008000 = green
link.font = "More...";
p.appendChild(<br/>);
p.appendChild(link);
body += p;
Tento objekt XMLList představuje data řetězce vhodná pro textové pole HTML jazyka ActionScript.
Metoda xmlLoaded() používá vrácené hodnoty metody buildItemHTML() a převádí je na řetězec:
XML.prettyPrinting = false;
rssOutput = outXML.toXMLString();
Vyjmutí titulu kanálu RSS a odeslání vlastní události
Metoda xmlLoaded() nastaví proměnnou řetězce rssTitle na základě informací ve zdrojových datech RSS XML:
rssTitle = rssXML.channel.title.toString();
Nakonec metoda xmlLoaded() vygeneruje událost, která aplikaci upozorní, že data byla analyzována a jsou k
dispozici:
dataWritten = new Event("dataWritten", true);
243
Kapitola 12: Zpracování událostí
Systém zpracování událostí umožňuje programátorům reagovat na vstupy uživatele a události systému pohodlným
způsobem. Model událostí jazyka ActionScript 3.0 není jenom pohodlný, ale splňuje také standardy, je dobře
integrován do seznamů zobrazení aplikace Adobe® Flash® Player a Adobe® AIR™. Na základě specifikace události DOM
(objektového modelu dokumentu) úrovně 3, což je architektura zpracování událostí průmyslového standardu,
poskytuje programátorům jazyka ActionScript nový model událostí výkonný, ale přesto intuitivní nástroj pro
zpracování událostí.
Tato kapitola je organizována do pěti sekcí. První dvě sekce poskytují vedlejší informace o zpracování události v jazyce
ActionScript. Poslední tři části popisují hlavní koncepty, které stojí za modelem událostí: tok událostí, objekt událostí
a posluchače událostí. Systém zpracování událostí v jazyce ActionScript 3.0 úzce spolupracuje se seznamem zobrazení
a tato kapitola předpokládá, že máte základní znalosti tohoto seznamu zobrazení. Další informace naleznete v části
„Programování zobrazení“ na stránce 265.
Základy zpracování událostí
Úvod do zpracování událostí
Na události můžete nahlížet jako na výskyty čehokoliv v souborech SWF, která vás jako programátora zajímají.
Například většina souborů SWF podporuje nějakou interakci s uživatelem - například jednoduchá forma, jako je
klepnutí myší, nebo složitější forma, například příjem a zpracování dat zadaných do formuláře. Každá taková interakce
uživatele s vaším souborem SWF je považována za událost. Události mohou nastat také bez přímé interakce uživatele,
například když je dokončeno načítání dat ze serveru nebo když se aktivuje připojena kamera.
V jazyce ActionScript 3.0 je každá událost zastoupena objektem události, což je instance třídy Event nebo jedné z jejích
podtříd. Objekt události nejenom, že ukládá informace o specifické události, ale obsahuje také metody, které usnadňují
manipulaci s objektem události. Když například aplikace Flash Player nebo AIR detekuje klepnutí myší, vytvoří objekt
události (instance třídy MouseEvent), který reprezentuje tuto specifickou události klepnutí myši.
Po vytvoření objektu události jej aplikace Flash Player nebo AIR odešle, což znamená, že objekt události je předán
objektu, která je cílem této události. Objekt sloužící jako cíl odeslaného objektu události se nazývá cíl události. Když se
například aktivuje připojená kamera, aplikace Flash Player odešle objekt události přímo do cíle události, což je v tomto
případě objekt představující kameru. V případě, že cíl události je na seznamu zobrazení, objekt události je předán dolů
hierarchií seznamu zobrazení, dokud nedosáhne cíle události. V některých případech pak objekt události "probublává"
zpět v hierarchii seznamu zobrazení, po stejné trase. Tento průchod hierarchií seznamu zobrazení se nazývá tok
událostí.
Ve svém kódu můžete objektům událostí "naslouchat" pomocí posluchačů události. Posluchače událostí jsou funkce
nebo metody, které zapisujete v odezvě na specifické události. Pro zajištění, aby vaše programy na události odpovídaly,
musíte přidat posluchače událostí do cíle události nebo do objektu seznamu zobrazení, který je součástí toku objektu
událostí.
Vždy, když píšete kód posluchače události, je nutné dodržovat tuto základní strukturu (prvky tučným písmem jsou
rezervovaná místa, které vyplníte svým specifickým případem):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 244
Zpracování událostí
function eventResponse(eventObject:EventType):void
{
// Actions performed in response to the event go here.
}
eventTarget.addEventListener(EventType.EVENT_NAME, eventResponse);
Tento kód provádí dvě věci. Nejprve definuje funkci, která je způsobem specifikace činností, které budou provedeny
v odezvě na událost. Dále je zavolána metoda addEventListener() zdrojového objektu, v podstatě “odběr”
specifikované události funkcí tak, že když k události dojde, jsou provedeny činnosti funkce. Když dojde ke specifické
události, cíl události zkontrolujte seznam všech funkcí a metod, které jsou zaregistrovány jako posluchače událostí.
Poté postupně každou zavolá a předá objekt události jako parametr.
Chcete-li vytvořit vlastní posluchač událostí, musíte změnit v tomto kódu čtyři věci. Nejprve musíte změnit název
funkce na název, který chcete používat (musíte jej změnit na dvou místech, kde kód definuje eventResponse). Za
druhé musíte specifikovat vhodný název třídy objektu události, který je odeslán událostí, které chcete naslouchat (v
kódu EventType) a musíte specifikovat příslušnou konstantu pro specifickou událost (v seznamu EVENT_NAME).
Za třetí musíte zavolat metodu addEventListener() pro objekt, která odešle události (v tomto kódu eventTarget).
Volitelně můžete změnit názve proměnné použité jako parametr funkce (v tomto kódu eventObject).
Společné úlohy zpracování událostí
Následující úlohy jsou společné úlohy zpracování událostí, z nichž každá je v této kapitole popsána.
• Zápis kódu reagujícího na události
• Zastavení reakce kódu na události
• Práce s objekty událostí
• Práce s tokem událostí
• Identifikování informací toku událostí
• Zastavení toku událostí
• Zabránění výchozího chování
• Odeslání události z vašich tříd
• Vytváření vlastních typů událostí
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Výchozí chování: některé události zahrnují chování, ke kterému normálně dochází společně s událostí, známou
jako výchozí chování. Například když uživatel zadá text do textového pole, je aktivována události zadávání textu.
Výchozí chování pro tuto událost je v podstatě zobrazení znaku, který byl do textového pole zadán - výchozí
chování však můžete potlačit (pokud z nějakého důvodu nechcete zadaný text zobrazit).
• Odeslání: vyrozumění posluchačů událostí o tom, že došlo k události.
• Událost: něco, co se stane objektu, o čem tento objekt může říci objektům ostatním.
• Tok událostí: když se objektu na seznamu zobrazení stane nějaká událost (objekt zobrazený na obrazovce), všechny
objekty obsahující tento objekt jsou o události vyrozuměny a ty zase vyrozumí své posluchače událostí. Tento
proces začíná na ploše a pokračuje seznamem zobrazení ke stávajícímu objektu, kde k události došlo, pak pokračuje
znovu na plochu. Tento proces je znám jako tok událostí.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 245
Zpracování událostí
• Objekt události: objekt obsahující informace o specifickém výskytu události, které jsou odeslány všem
posluchačům, když je objekt odeslán.
• Cíl události: objekt, který událost ve skutečnosti odeslal. Pokud například uživatel klepne na tlačítko, které se
nachází uvnitř pohyblivého symbolu, který se opět nachází na ploše, všechny tyto objekty odešlou události, ale cíl
události je ten, ke k události ve skutečnosti došlo - v tomto případě se jedná o tlačítko, na které bylo klepnuto.
• Posluchač: objekt nebo funkce, které se zaregistrovaly u objektu a které označují, že by měly být informovány v
případě, že ke specifické události dojde.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Všechny
příklady kódu v této kapitole zahrnují volání funkce trace() pro testování výsledků kódu. Návod na vyzkoušení kódů
uvedených v této kapitole:
1 Pomocí vývojového nástroje Flash vytvořte prázdný dokument.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
Výsledky funkcí trace() uvedených kódů uvidíte v panelu Výstup.
Některé příklady kódu jsou složitější a zapsány jako třída. Postup při testování těchto příkladů:
1 Pomocí vývojového nástroje Flash vytvořte prázdný dokument a uložte jej na svůj počítač.
2 Vytvořte nový soubor ActionScript a uložte ho do stejného adresáře jako dokument vytvořený v 1. kroku. Název
souboru by měl být stejný jako název třídy ve výpisu kódu. Pokud příklad kódu například definuje třídu
pojmenovanou EventTest, použijte k uložení souboru jazyka ActionScript název EventTest.as.
3 Zkopírujte výpis kódu do souboru ActionScript a soubor uložte.
4 V dokumentu klepněte na prázdnou část Plochy nebo pracovní oblasti a aktivujte Inspektor vlastností dokumentu.
5 V Inspektoru vlastností zadejte do pole Třída dokumentu název třídy ActionScript vykopírovaný z textu.
6 Spusťte program pomocí volby Ovládání > Testovat film.
Výsledky příkladu se zobrazí v panelu Výstup.
Tyto techniky testování příkladu kódu jsou vysvětleny podrobněji v kapitole „Testování příkladů kódu v této kapitole“
na stránce 34.
Jak se zpracování událostí v jazyce ActionScript 3.0 liší
od předchozích verzí
Nejvýraznější rozdíl mezi zpracováním události v jazyce ActionScript 3.0 a předchozích verzích tohoto jazyka je to, že
ActionScript 3.0 je jediným systémem pro zpracování událostí, zatímco předchozí verze jazyka ActionScript
umožňovaly existenci několika různých systémů pro zpracování událostí. Tato kapitola začíná přehledem, jak
zpracování událostí pracovalo v předchozích verzích jazyka ActionScript a pak popisuje, jak se jazyce ActionScript 3.0
zpracování událostí změnilo.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 246
Zpracování událostí
Zpracování událostí v předchozích verzích jazyka ActionScript
Verze jazyka ActionScript před verzí ActionScript 3.0 poskytovaly několik různých způsobů zpracování událostí:
• manipulační programy on(), které lze umístit přímo na instance Button a MovieClip
• manipulační programy onClipEvent(), které lze umístit přímo na instance MovieClip
• Vlastnosti funkce zpětného volání, například XML.onload a Camera.onActivity
• Posluchače událostí, které zaregistrujete pomocí metody addListener()
• Třída UIEventDispatcher, která částečně implementuje model událostí DOM.
Každý z těchto mechanismů představuje svou vlastní sadu výhod a omezení. Manipulační programy událostí on() a
onClipEvent() se snadno používají, ale činí následnou údržbu projektu obtížnější, protože kód je vložen přímo na
tlačítka a filmové klipy a lze jej tak obtížně nalézt. Funkce zpětného volání se také jednoduše implementují, ale omezují
vás pouze na jednu funkci zpětného volání na danou událost. Posluchače událostí se implementují obtížně - vyžadují
nejenom vytvoření objektu a funkce posluchače, ale také registrace posluchače u objektu, který událost generuje. Tyto
zvýšené nároky však umožňují vytvořit několik posluchačů událostí a registrovat je všechny pro stejnou událost.
Vývoj součástí jazyka ActionScript 2.0 vedl k vytvoření ještě dalšího modelu události. Tento nový model,
implementovaný ve třídě UIEventDispatcher, byl založen na podřízené sadě specifikace událostí DOM. Vývojáři, kteří
jsou seznámeni se zpracováním událostí součástí, shledají nový model událostí v jazyce ActionScript 3.0 relativně
bezproblémový.
Syntaxe použitá různými modely událostí se různými způsoby překrývá a jinými se odlišuje. Například v jazyce
ActionScript 2.0 mohou být některé vlastnosti, jako například TextField.onChanged, použity jako funkce zpětného
volání nebo posluchač události. Syntax pro registrování objektů posluchače se liší v závislosti na tom, zda používáte
jednu ze šesti tříd, která podporuje posluchače nebo třídy UIEventDispatcher. Pro třídy Key, Mouse,
MovieClipLoader, Selection, Stage a TextField používejte metodu addListener(), avšak pro zpracování událostí
součástí používejte metodu nazvanou addEventListener().
Další složitost zavedená různými modely zpracování událostí spočívá v tom, že rozsah funkce manipulačního
programu událostí se velmi liší v závislosti na použitém mechanismu. Jinými slovy, význam klíčového slova this nebyl
mezi různými systémy zpracování událostí konzistentní.
Zpracování událostí v jazyce ActionScript 3.0
Jazyk ActionScript 3.0 zavádí jednotlivý model zpracování událostí, který nahrazuje mnoho různých mechanismů,
které se vyskytovaly v předchozích verzích jazyka. Nový model událostí je založen na Specifikaci události DOM
(objektového modelu dokumentu) úrovně 3. I když formát souboru SWF nedodržuje specificky standard DOM, mezi
seznamem zobrazení a strukturou DOM existuje dostatečná podobnost, aby implementace modelu událostí DOM
byla možná. Objekt na seznamu zobrazení je analogií uzlu v hierarchické struktuře DOM a termíny objekt seznamu
zobrazení a uzel jsou v této diskusi používány záměnným způsobem.
Implementace modelu událostí DOM v aplikaci Flash Player a AIR zahrnuje koncept pojmenovaný výchozí chování.
Výchozí chování je činností, kterou aplikace Flash Player nebo AIR vykonává jako normální následek některých
událostí.
Výchozí chování
Vývojáři jsou obvykle odpovědní za zápis kódu, který odpovídá na události. V některých případech je chování však
natolik běžně spojeno s událostí, že aplikace Flash Player nebo AIR vykonává dané chování automaticky, pokud
vývojář nepřidá kód, který toto chování zruší. Protože Flash Player nebo AIR automaticky vykazují chování, je toto
chování nazýváno výchozí chování.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 247
Zpracování událostí
Když například uživatel zadá do objektu TextField text, je očekávání, že se text se zobrazí v tomto objektu TextField
natolik běžné, že toto chování je do aplikace Flash Player a AIR přímo integrováno. Pokud nechcete, aby k tomuto
výchozímu chování docházelo, můžete jej zrušit pomocí nového systému zpracování událostí. Když uživatel zadá do
objektu TextField text, aplikace Flash Player nebo AIR vytvoří instanci třídy TextEvent reprezentující tento vstup
uživatele. Chcete-li aplikaci Flash Player nebo AIR zabránit v zobrazení objektu TextField, musíte zpřístupnit tuto
specifickou instanci TextEvent a zavolat metodu preventDefault() této instance.
Nelze však zabránit všemi výchozím chováním. Aplikace Flash Player a AIR například vygenerují objekt MouseEvent
v případě poklepání na slovo v objektu TextField. Výchozí chování, kterému nelze zabránit, je zvýraznění slova pod
kurzorem.
Mnoho typů objektů událostí nemá připojené výchozí chování. Například aplikace Flash Player odešle objekt události
připojení, když je vytvořeno připojení k sítu, ale s není s tím spojeno žádné výchozí chování. Dokumentace rozhraní
API pro třídu Event a její podtřídy uvádí každý typ události a popisuje všechna související výchozí chování a zad lze
tomuto chování zabránit.
je důležité porozumět tomu, že výchozí chování jsou spojena pouze s událostmi odeslanými aplikacemi Flash Player
nebo AIR, a neexistují pro objekty událostí odeslané programově prostřednictvím jazyka ActionScript. Například
můžete použít metody třídy EventDispatcher k odeslání objektu události typu textInput, ale tento objekt události
nebude mít připojené výchozí chování. Jinými slovy aplikace Flash Player a AIR nezobrazí znak v objektu TextField v
důsledku události textInput, kterou jste odeslali programově.
Co je nového s posluchači událostí v jazyce ActionScript 3.0
Pro vývojáře se zkušeností z používání jazyka ActionScript 2.0 a jeho metody addListener() může být vhodné
poukázat na rozdíly mezi modelem posluchače události ActionScript 2.0 a modelem události ActionScript 3.0.
Následující seznam popisuje několik hlavních rozdílů mezi dvěma modely událostí.
• Chcete-li přidat posluchače událostí v jazyce ActionScript 2.0, použijete v některých případech addListener() a
v jiných addEventListener(), zatímco v jazyce ActionScript 3.0 použijete ve všech situacích
addEventListener().
• V jazyce ActionScript 2.0 neexistuje žádný tok události, což znamená, že metoda addListener() může být
zavolána pouze pro objekt, který vysílá události, zatímco v jazyce ActionScript 3.0 může být metoda
addEventListener() zavolána pro kterýkoliv objekt, který je součástí toku událostí.
• V jazyce ActionScript 2.0 mohou být posluchače události buď funkcemi, metodami nebo objekty, zatímco v jazyce
ActionScript 3.0 mohou být pouze funkcemi nebo metodami.
Tok událostí
Aplikace Flash Player nebo AIR odesílá objekty událostí kdykoliv k nějaké události dojde. Pokud cíl události není na
seznamu zobrazení, aplikace Flash Player nebo AIR odešle událost přímo do cíle události. Například aplikace Flash
Player odešle objekt události průběhu přímo do objektu URLStream. V případě, že cílová událost se nachází na
seznamu zobrazení, aplikace Flash Player odešle objekt události do seznamu zobrazení a objekt události se poté
pohybuje seznamem zobrazení do cíle události.
Tok událostí popisuje, jak se objekt události pohybuje seznamem zobrazení. Seznam zobrazení je organizován
hierarchicky, což lze popsat jako strom. Nahoře seznamu zobrazení je plocha, což je speciální kontejner objektů
zobrazení, který slouží jako kořen seznamu zobrazení. Plocha je reprezentována třídou flash.display.Stage a lze ji
zpřístupnit pouze prostřednictvím objektu zobrazení. Každý objekt zobrazení má vlastnost pojmenovanou stage,
která odkazuje na plochu pro danou aplikaci.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 248
Zpracování událostí
Když aplikace Flash Player nebo AIR odešle objekt události pro událost související se seznamem zobrazení, tento
objekt události se pohybuje z plochy do cíle uzlu. Specifikace událostí DOM definuje uzel cíle jako uzel představující
cíl události. Jinými slovy uzel cíle je objektem seznamu zobrazení, kde k události došlo. Pokud například uživatel
klepne na objekt seznamu zobrazení nazvaný child1, aplikace Flash Player nebo AIR odešle objekt události nazvaný
child1 jako cílový uzel.
Tok událostí je koncepčně rozdělen na tři části. První část se nazývá fáze zachycení: tato fáze obsahuje všechny uzly z
plochy až po zdroj uzlu cíle. Druhá část je nazvaná cílová fáze a je tvořena výhradně uzlem cíle. Třetí fáze se nazývá
fází probublávání. Fáze probublávání je tvořena uzly ze zpáteční cesty od zdroj uzlu cíle na plochu.
Názvy fází dávají větší smysl, pokud pojmete seznam zobrazení jako svislou hierarchii s plochou jako horní částí, jak
je znázorněno na následujícím schématu.
Vymezená plocha
Nadřazený uzel
Podřízený uzel2
Podřízený uzel1
Pokud uživatel klepne na Uzel Child1, aplikace Flash Player nebo AIR odešlou objekt události do toku události. Jak
ukazuje následující obrázek, cesta objektu začíná na Stage, dále pokračuje do Parent Node, pak do uzlu Child1 a
nakonec „probublává” zpět na Stage, přičemž prochází znovu Parent Node při své cestě na plochu Stage.
Vymezená plocha
Fáze
zachycení
Bublinová
fáze
Nadřazený uzel
Podřízený uzel1
Podřízený uzel2
Cílová fáze
V tomto příkladu fáze zachycení obsahuje Stage a Parent Node během počáteční cesty směrem dolů. Cílová fáze je
tvořena časem stráveným v uzlu Child1. Fáze probublávání obsahuje Parent Node a Stage při cestě směrem nahoru
zpět do kořenového uzlu.
Tok událostí přispívá k výkonnějšímu systému zpracování událostí, než který byl programátorům ActionScript
dostupný dříve. V předchozích verzích jazyka ActionScript tok událostí neexistoval, což znamená posluchače událostí
mohou být přidány pouze k objektu, který událost generuje. V jazyce ActionScript 3.0 můžete přidat posluchače
událostí nejenom do cílového uzlu, ale také do kteréhokoliv uzlu podél toku událostí.
Schopnost přidat posluchače událostí během toku události je užitečný, když součást uživatelského rozhraní obsahuje
více než jeden objekt. Například objekt tlačítka často obsahuje objekt testu, který slouží jako jmenovka tlačítka. Bez
schopnosti přidat posluchače události do toku události budete muset posluchače přidat k objektu tlačítka i k objektu
textu a zajistit tak, že obdržíte oznámení o událostech klepnutí, ke kterým dojde kdekoliv na tlačítku. Existence toku
událostí však umožňuje umístit jednotlivé posluchače událostí na objekt tlačítka, který zpracovává události klepnutí,
ke kterým dojde buď na objektu textu nebo na objektu tlačítka, které nejsou zablokovány objektem textu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 249
Zpracování událostí
Každý objekt události se však nemusí účastnit všech tří fází toku událostí. Některé typy událostí, například
enterFrame a init, jsou odesílány přímo do uzlu cíle a neúčastní se ani fáze zachycení, ani fáze probublávání. Jiné
události mohou zacílit objekty, které nejsou na seznamu zobrazení, například události odeslané do instance třídy
Socket. Tyto objekty události budou také procházet přímo do objektu cíle, aniž by se účastnily fází zachycení nebo
probublávání.
Chcete-li zjistit, jak se specifický typ události chová, můžete se buď informovat v dokumentaci k rozhraní API nebo
zkontrolovat vlastnosti objektu události. Prověření vlastností objektu události je popsáno v následující kapitole.
Objekty událostí
V novém systému zpracování událostí slouží objekty událostí dvěma hlavním účelům. První, objekty událostí
představuje skutečné události ukládáním informací o specifických událostech do souboru vlastností. Druhý, objekty
událostí obsahují soubor metod, které umožňují manipulovat s objekty událostí a ovlivňovat chování systém
zpracování událostí.
Pro usnadnění přístup k těmto vlastnostem a metodám definuje rozhraní API aplikace Flash Player třídu Event, která
slouží jako základní třída pro všechny objekty událostí. Třída Event definuje základní soubor vlastností a metod, které
jsou společné pro všechny objekty událostí.
Tato kapitola začíná diskusí o vlastnostech třídy Event, pokračuje popisem metod třídy Event a končí vysvětlením,
proč existují podtřídy třídy Event.
Porozumění vlastnostem třídy Event
Třída Event definuje počet vlastností určených pouze ke čtení a konstant, které poskytují důležité informace o objektu
události. Obzvláště důležité jsou následující:
• Objekt události jsou představovány konstantami a ukládání ve vlastnosti Event.type.
• Booleovská hodnota uložená ve vlastnosti Event.cancelable stanoví, zda lze zabránit výchozímu chování
události.
• Informace o toku událost je obsažena ve zbývajících vlastnostech.
Typy objektu události
Každý objekt událost má připojen typ události. Typy události jsou uloženy ve vlastnosti Event.type jako řetězcové
hodnoty. Je vhodné znát typ objektu události, aby váš kód mohl odlišit objekty různých typů navzájem mezi sebou.
Například následující kód specifikuje, že posluchače funkce clickHandler() by měl reagovat na kterýkoliv objekt
klepnutí myší, který je předán do myDisplayObject:
myDisplayObject.addEventListener(MouseEvent.CLICK, clickHandler);
Asi dvanáct typů událostí je spojeno se samotnou třídou Event a zastupováno konstantami třídy Event, některé z nich
jsou zobrazeny v následujícím výňatku z definice třídy Event:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 250
Zpracování událostí
package flash.events
{
public class Event
{
// class constants
public static const ACTIVATE:String = "activate";
public static const ADDED:String= "added";
// remaining constants omitted for brevity
}
}
Tyto konstanty poskytují snadný způsob odkazován na specifické typy událostí. Tyto konstanty byste měli používat
namísto řetězců, které zastupují. Pokud nesprávně uvedete název konstanty v kódu, kompilátor chybu zachytí, ale
pokud namísto toho použijete řetězce, typografická chyba se nemusí v době kompilace projevit a může vést k
neočekávanému chování, které může být obtížné ladit. Například když přidáváte posluchače události, použijte
následující kód:
myDisplayObject.addEventListener(MouseEvent.CLICK, clickHandler);
spíše než:
myDisplayObject.addEventListener("click", clickHandler);
Informace o výchozím chování
Kód může kontrolovat, zda lze zabránit výchozímu chování pro kterýkoliv daný objekt události a to přístupem k
vlastnosti cancelable. Vlastnost cancelable uchovává booleovskou hodnotu, která signalizuje, zda může být
výchozímu chování zabráněno, nebo nikoliv. Můžete zabránit výchozímu chování spojenému s malým počtem
událostí nebo jej zrušit a to pomocí metody preventDefault(). Více informací viz Zrušení výchozího chování
události v části „Porozumění metodám třídy Event“ na stránce 251.
Informace toku události
Zbývající vlastnosti třídy Event obsahují důležité informace o objektu události a jeho vztahu s tokem události, jak je
popsáno v následujícím seznamu:
• Vlastnost bubbles obsahuje informace o částech toku události, na kterých se účastní objekt události.
• Vlastnost eventPhase signalizuje stávající fázi v toku události.
• Vlastnost target ukládá odkaz na cíl události.
• Vlastnost currentTarget ukládá odkaz na objekt seznamu zobrazení, který právě zpracovává objekt události.
Vlastnost bubbles
O události říkáme, že probublává v případě, že objekt události se účastní fáze probublávání toku události, což znamená,
že objekt události je předán z uzlu cíle přes jeho následníky, až dosáhne plochy. Vlastnost Event.bubbles ukládá
booleovskou hodnotu signalizující, zda se objekt události účastní fáze probublávání. Protože všechny události, které
probublávají se také účastní fází zachycení a cílové fáze, kterákoliv událost, která probublává, se účastní všech tří fází
toku události. Pokud je hodnota true, objekt události se účastní všech tří fází. Pokud je hodnota false, objekt události
se neúčastní fáze probublávání.
Vlastnost eventPhase
Můžete stanovit fázi události pro kterýkoliv objekt události a to vyšetřením jeho vlastnosti eventPhase. Vlastnost
eventPhase obsahuje celočíselnou hodnotu bez znaménka, která zastupuje jednu ze tří fází toku události. Rozhraní
API aplikace Flash Player definuje samostatnou třídu EventPhase, která obsahuje tři konstanty odpovídající třem
celočíselným hodnotám bez znaménka, jak je znázorněno v následujícím výňatku kódu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 251
Zpracování událostí
package flash.events
{
public final class EventPhase
{
public static const CAPTURING_PHASE:uint = 1;
public static const AT_TARGET:uint = 2;
public static const BUBBLING_PHASE:uint= 3;
}
}
Tyto konstanty odpovídají třem platným hodnotám vlastnosti eventPhase. Tyto konstanty můžete použít ke
zpřehlednění kódu a zvýšení jeho čitelnosti. Pokud chcete například zajistit, aby funkce pojmenovaná myFunc() byla
volána pouze v případě, že cíl události je v cílové fázi, můžete k otestování tohoto stavu použít následující kód:
if (event.eventPhase == EventPhase.AT_TARGET)
{
myFunc();
}
Vlastnost target
Vlastnost target uchovává odkaz na objekt, který je cílem události. V některých případech je toto přímočaré,
například když se aktivuje mikrofon, je cílem objektu události objekt Microphone. Pokud je cíl na seznamu zobrazení,
musíte vzít v úvahu hierarchii seznamu zobrazení. Pokud například uživatel klepne myší na důležité místi, které
obsahuje překrývající se objekty seznamu zobrazení, aplikace Flash Player a AIR jako cíl události vždy zvolí objekt,
který je nejdále od plochy.
V případě složitých souborů SWF, obzvláště těch, jejichž tlačítka jsou běžně zdobena malými podřízenými objekty,
nemusí být vlastnost target použita často, protože může obvykle ukazovat na podřízený objekt tlačítka, namísto na
samotné tlačítko. V této situaci je běžným postupem přidání posluchačů událostí k tlačítku a použití vlastnosti
currentTarget, protože ukazuje na tlačítko, zatímco vlastnost target může ukazovat na podřízený objekt tlačítka.
Vlastnost currentTarget
Vlastnost currentTarget obsahuje odkaz na objekt, který právě zpracovává objekt události. I když se může zdát
neobvyklé nevědět, který uzel právě zpracovává objekt události, který prověřujete, mějte na paměti, že můžete přidat
funkci objektu události ke kterémukoliv objektu zobrazení, v daném toku události tohoto objektu a funkci posluchače
lze umístit do libovolného umístění. Kromě toho lze přidat stejnou funkci posluchače k jiným objektům zobrazení. Se
zvětšování velikosti projektu a jeho složitosti se vlastnost currentTarget stává stále více užitečnější.
Porozumění metodám třídy Event
Existují tři kategorie metod třídy event.
• Metody pomocné, které mohou vytvářet kopie objektu nebo jej převádět na řetězec
• Metody toku události, které odebírají objekty události z toku události
• Výchozí chování metod, které brání výchozímu chování nebo kontrolují, zda mu bylo zabráněno
Pomocné metody třídy Event
Ve třídě Event existují dvě pomocné metody. Metoda clone() umožňuje vytvářet kopie objektu události. Metoda
toString() umožňuje generovat znázornění řetězce vlastnosti pro objekt události, společně s jejich hodnotami. Obě
tyto metody jsou požívány vnitřně systémem modelu události, ale jsou zpřístupněny vývojářům pro obecné použití.
Pokročilí vývojáři, kteří vytvářejí podtřídy třídy Event, musí potlačit a implementovat verze obou pomocných metod
a zajistit tak, že podtřída události bude řádně funkční.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 252
Zpracování událostí
Zastavení toku událostí
Můžete zavolat metodu Event.stopPropagation() nebo Event.stopImmediatePropagation() a zabránit tak
objektu události v pokračování pohybu skrze tok událostí. Dvě metody jsou téměř identické a liší se pouze v tom, zda
mohou být vykonány ostatní posluchače události stávajícího uzlu:
• Metoda Event.stopPropagation() zabraňuje objektu události v pohybu k následujícímu uzlu, ale pouze poté, co
je povoleno vykonání všech ostatních posluchačů události ve stávajícím uzlu.
• Metoda Event.stopImmediatePropagation() také zabraňuje objektu události v pohybu k následujícímu uzlu,
ale neumožňuje vykonání všech ostatních posluchačů události ve stávajícím uzlu.
Zavolání některé z těchto metod nemá žádný účinek na to, zda dojde k výchozímu chování souvisejícímu s danou
událostí. Metody výchozího chování třídy Event použijte k tomu, abyste zabránili výchozímu chování.
Zrušení výchozího chování události
Dvě metody, které se týkají zrušení výchozího chování, jsou preventDefault() a isDefaultPrevented(). Zavolejte
metodu preventDefault() a zrušte výchozí chování související s událostí. Chcete-li zkontrolovat, zda metoda
preventDefault() byla již zavolána pro objekt události, zavolejte metodu isDefaultPrevented(), která vrátí
hodnotu true, pokud již byla metoda zavolána, jinak vrátí hodnotu false.
Metoda preventDefault() bude funkční pouze v případě, že je zrušeno výchozí chování události. V dokumentaci
rozhraní API můžete zkontrolovat, zda se jedná o tento případ, případně můžete použít jazyk ActionScript k prověření
vlastnosti cancelable objektu události.
Zrušení výchozího chování nemá žádný účinek na průběh pohybu objektu události skrze tok události. Metody toku
události pro třídu Event použijte pro odstranění objektu události z toku události.
Podtřídy třídy Event
Pro mnoho událostí postačuje běžná sada vlastností, která je definována v třídě Event. Ostatní události však mají
unikátní charakteristiku, kterou nelze zachytit vlastnostmi dostupnými ve třídě Event. Pro tyto události definuje jazyk
ActionScript 3.0 několik podtříd třídy Event.
Každá podtřída poskytuje dodatečné vlastnosti a typy události, které jsou unikátní pro danou kategorii událostí.
Například, události související se vstupem myši mají několik unikátních vlastností, které nelze zachytit vlastnostmi
definovanými ve třídě Event. Třída MouseEvent rozšiřuje třídu Event přidáním deseti vlastností, které obsahují
informace, jako je například umístění události mouse a zda jsou stisknuty během události mouse specifická tlačítka.
Podtřída Event rovněž obsahuje konstanty, které zastupují typy událostí související s podtřídami. Například třída
MouseEvent definuje konstanty pro několik typů události mouse, včetně typů události click, doubleClick,
mouseDown a mouseUp.
Jak je popsáno v kapitole Pomocné metody třídy Event v tématu „Objekty událostí“ na stránce 249, při vytváření
podtřídy Event musíte potlačit metody clone() a toString() a poskytnout tak funkčnost specifickou pro podtřídu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 253
Zpracování událostí
Posluchače událostí
Posluchače událostí, které se také nazývají manipulační programy událostí, jsou funkce, které aplikace Flash Player a
AIR vykonávají v odezvě na specifické události. Přidání posluchače události je dvoukrokový proces. Nejprve vytvoříte
funkci nebo metodu třídy pro aplikaci Flash Player nebo AIR, která se vykoná v odezvě na událost. Toto se někdy
nazývá funkce posluchače nebo funkce manipulačního programu událostí. Za druhé použijete metodu
addEventListener() k zaregistrování funkce posluchače v cíli události nebo v kterémkoliv objektu seznamu
zobrazení, který leží v příslušném toku události.
Vytváření funkce posluchače
Vytvoření funkce posluchače je jednou z oblastí, kde se model události jazyka ActionScript 3.0 odchyluje od modelu
události DOM. V modelu události DOM je zřetelné rozlišení mezi posluchačem události a funkcí posluchače:
posluchač události je instancí třídy, která implementuje rozhraní EventListener, zatímco funkce posluchače je
metodou této třídy, pojmenovanou handleEvent(). V modelu události DOM registrujete instanci třídy, která
obsahuje funkci posluchače, spíše než skutečnou funkci posluchače.
V modelu události jazyka ActionScript 3.0 neexistuje žádné odlišené mezi posluchačem události a funkcí posluchače.
Jazyk ActionScript 3.0 nemá žádné rozhraní EventListener a funkce posluchače, které mohou být definované mimo
třídu nebo jako součást třídy. Kromě toho funkce posluchače nemusí být pojmenovány handleEvent() - mohou být
pojmenovány libovolným platným identifikátorem. V jazyce ActionScript 3.0 registrujete název skutečné funkce
posluchače.
Funkce posluchače definovaná mimo třídu
Následující kód vytváří jednoduchý soubor SWF, který zobrazuje červený čtvercový obrazec. Funkce posluchače
pojmenovaná clickHandler(), která není součástí třídy, naslouchá událostem klepnutí myši na červený čtverec.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 254
Zpracování událostí
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
}
function clickHandler(event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
Když uživatel pracuje s výsledným souborem SWF klepnutím na čtverec, aplikace Flash Player nebo AIR generují
následující výstup:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Povšimněte si, že objekt události je předán jako argument do clickHandler(). To umožní funkci posluchače prověřit
objekt události. V tomto příkladu použijte vlastnost objektu události type a ujistěte se, že událost je událostí klepnutí.
Příklad také kontroluje hodnotu klíčového slova this. V tomto případě this zastupuje globální objekt, což dává
smysl, protože funkce je definována mimo kteroukoliv uživatelskou třídu nebo objekt.
Funkce posluchače definované jako metoda třídy
Následující příklad je shodný s předchozím, který definoval třídu ClickExample kromě toho, že funkce
clickHandler() je definována jako metoda třídy ChildSprite:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 255
Zpracování událostí
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
private function clickHandler(event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
}
Když uživatel pracuje s výsledným souborem SWF klepnutím na červený čtverec, aplikace Flash Player nebo AIR
generují následující výstup:
clickHandler detected an event of type: click
the this keyword refers to: [object ChildSprite]
Povšimněte si, že klíčové slovo this odkazuje na instanci ChildSprite pojmenovanou child. To je změna chování od
verze ActionScript 2.0. Pokud jste používali součásti v jazyce ActionScript 2.0, můžete si zapamatovat, že když byly
třídy metody předány do UIEventDispatcher.addEventListener(), rozsah metod byl vázán na součást, která
vysílal událost, namísto třídy, ve které byla metoda posluchače definována. Jinými slovy, pokud jste používali tuto
techniku v jazyce ActionScript 2.0, klíčové slovo this by odkazovalo na součást vysílající událost, namísto instance
ChildSprite.
To byl významný problém pro některé programátory, protože to znamenalo, že nemohou přistupovat k jiným
metodám a vlastnostem třídy, obsahující metodu posluchače. Jako opravný prostředek mohli programátoři jazyka
ActionScript 2.0 používat třídu mx.util.Delegate ke změně rozsahu metody posluchače. To již není nutné, protože
jazyk ActionScript 3.0 vytváří vázanou metodu, když je zavolána metoda addEventListener(). V důsledku toho
klíčové slovo this odkazuje na instanci ChildSprite pojmenovanou child a programátor má přístup k jiným
metodám a vlastnostem třídy ChildSprite.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 256
Zpracování událostí
Posluchač události, který by neměl být používán
Existuje třetí technika, kterou vytváříte generický objekt s vlastností, která ukazuje na dynamicky přiřazené funkce
posluchače, ale její použití se nedoporučuje. Je zde popisována pouze proto, že byla běžně používána v jazyce
ActionScript 2.0, ale ve verzi ActionScript 3.0 by používána být neměla. Tato technika se nedoporučuje proto, že
klíčové slovo this bude odkazovat na globální objekt, namísto objektu posluchače.
Následující příklad je shodný s předchozím příkladem třídy ClickExample, kromě toho, že funkce posluchače je
definována jako součást druhového objektu nazvaného myListenerObj:
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, myListenerObj.clickHandler);
}
}
var myListenerObj:Object = new Object();
myListenerObj.clickHandler = function (event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
Výsledky sledování budou vypadat takto:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Bylo by možné očekávat, že klíčové slovo this bude odkazovat na myListenerObj a že výstup sledování bude
[object Object], ale namísto toho odkazuje na globální objekt. Když předáte název dynamické vlastnosti jako
argument metodě addEventListener(), aplikace Flash Player nebo AIR nedokáží vytvořit vázanou metodu. Tak
tomu je proto, že to, co předáváte jako parametr listener není ničím jiným, než paměťovou adresou funkce
posluchače, a aplikace Flash Player a AIR nemá žádný způsob, jak spojit tuto paměťovou adresu s instancí
myListenerObj.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 257
Zpracování událostí
Správa posluchačů událostí
Pomocí metod rozhraní IEventDispatcher můžete spravovat funkce posluchače. Rozhraní IEventDispatcher je verzí
jazyka ActionScript 3.0 rozhraní EventTarget modelu události DOM. Ačkoliv může IEventDispatcher implikovat, že
hlavním účelem je odesílat (nebo předávat) objekty události, metody této třídy jsou ve skutečnosti používány mnohem
častěji k registrování posluchačů událostí, jejich kontrole a odebrání. Rozhraní IEventDispatcher definuje pět metod,
jako je zobrazeno v následujícím kódu:
package flash.events
{
public interface IEventDispatcher
{
function addEventListener(eventName:String,
listener:Object,
useCapture:Boolean=false,
priority:Integer=0,
useWeakReference:Boolean=false):Boolean;
function removeEventListener(eventName:String,
listener:Object,
useCapture:Boolean=false):Boolean;
function dispatchEvent(eventObject:Event):Boolean;
function hasEventListener(eventName:String):Boolean;
function willTrigger(eventName:String):Boolean;
}
}
Aplikace Flash Player API implementuje rozhraní IEventDispatcher s třídou EventDispatcher, která slouží jako
základní třída pro všechny třídy, které mohou být cíli událostí nebo částí toku události. Například třída DisplayObject
dědí z třídy EventDispatcher. To znamená, že kterýkoliv objekt na seznamu zobrazení má přístup k metodám rozhraní
IEventDispatcher.
Přidávání posluchačů událostí
Metoda addEventListener() je hlavní tažnou silou rozhraní IEventDispatcher. Použijte ji k registrování funkcí
posluchače. Dva vyžadované parametry jsou type a listener. Parametr type použijte pro specifikování typu
události. Parametr listener použijte pro specifikování funkce posluchače, která se spustí, když dojde k události.
Parametr listener může být referenci na kteroukoliv funkci nebo metodu třídy.
Poznámka: Při specifikování parametru listener nepoužívejte závorky. Například funkce clickHandler() je
specifikována bez závorek v následujícím volání metody addEventListener():
Poznámka: addEventListener(MouseEvent.CLICK, clickHandler).
Parametr useCapture metody addEventListener() umožňuje ovládat toku události od fáze, ve které bude váš
posluchač aktivní. Pokud useCapture nastavíte na hodnotu true, posluchač bude aktivní během fáze toku události.
Pokud useCapture nastavíte na hodnotu false, posluchač bude aktivní během cílové fáze a fáze probublávání toku
události. Chcete-li naslouchat události během všech fází toku události, musíte zavolat dvakrát addEventListener(),
jednou s parametrem useCapture nastaveným na hodnotu true a pak znovu s parametrem useCapture nastaveným
na hodnotu false.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 258
Zpracování událostí
Parametr priority metody addEventListener() není oficiální součástí modelu objektu události DOM úrovně 3. Je
součástí jazyka ActionScript 3.0 proto, aby vám umožnil vyšší flexibilitu organizování posluchačů událostí. Když
zavoláte addEventListener(), můžete nastavit prioritu pro daný posluchač události předáním celočíselné hodnoty
jako parametru priority. Výchozí hodnota je 0, ale můžete ji nastavit na zápornou nebo kladnou celočíselnou
hodnotu. Čím vyšší je číslo, tím dříve bude posluchač události vykonán. Posluchače událostí se stejnou prioritou jsou
vykonány v pořadí, ve kterém jsou přidány, takže čím dříve je posluchač přidán, tím dříve je vykonán.
Parametr useWeakReference umožňuje specifikovat, zda je odkaz na funkci posluchače slabý nebo normální.
Nastavením tohoto parametru na hodnotu true umožňuje se vyhnout situacím, ve kterých funkce posluchače setrvává
v paměti, i když již není potřebná. Aplikace Flash Player a AIR používají techniku nazvanou čištění uvolněné paměti k
odstranění objektů z paměti, které již nejsou používány. Objekt je považován za dále nepoužitý, pokud k němu nejsou
žádné odkazy. Funkce čištění uvolněné paměti se neohlíží na slabé odkazy, což znamená, že funkce posluchače mající
pouze slabé odkazy ukazující ni, je vhodná pro čištění paměti.
Odstranění posluchačů události
Metodu removeEventListener() můžete použít pro odstranění posluchače události, který již dále nepotřebujete. Je
vhodné odstranit všechny posluchače, které již nebudou používány. Vyžadované parametry zahrnují parametry
eventName a listener, které jsou shodné, jako požadované parametry metody addEventListener().
Nezapomeňte, že můžete naslouchat událostem během všech fází dvojím zavoláním addEventListener(), jednou s
parametrem useCapture nastaveným na hodnotu true a pak znovu se stejným parametrem nastaveným na hodnotu
false. Chcete-li odstranit oba posluchače událostí, měli byste zavolat dvakrát removeEventListener(), jednou s
parametrem useCapture nastaveným na hodnotu true a pak znovu se stejným parametrem nastaveným na hodnotu
false.
odesílání události
Metoda dispatchEvent() může být použita pokročilými programátory k odeslání objektu uživatelské události do
toku události. Jediným parametrem přijatým touto metodou je odkaz na objekt události, což musí být instance třídy
Event nebo podtřídy třídy Event. Po odeslání je vlastnost target objektu události nastavena na objekt, pro který byla
zavolána událost dispatchEvent().
Kontrola stávajících posluchačů událostí
Závěrečné dvě metody rozhraní IEventDispatcher poskytují užitečné informace o existenci posluchačů události.
Metoda hasEventListener() vrací hodnotu true v případě, že je nalezen posluchač události pro specifický typ
události na specifickém objektu seznamu zobrazení. Metoda willTrigger() rovněž vrací hodnotu true v případě,
že je nalezen posluchač události pro specifický objekt seznamu zobrazení, ale willTrigger() kontroluje posluchače
nejenom na daném objektu zobrazení, ale také na všech předchůdcích objektu seznamu zobrazení pro všechny fáze
toku události.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 259
Zpracování událostí
Události chyb bez posluchačů
Výjimky, spíše než události, jsou primárním mechanismem pro zpracování chyb v jazyce ActionScript 3.0, ale
zpracování výjimek není funkční pro asynchronní provoz, například pro načítání souborů. Pokud chyba nastane
během takového asynchronního provozu, aplikace Flash Player a AIR odešle objekt události chyby. Pokud nevytvoříte
posluchače pro událost chyby, verze ladicího programu aplikace Flash Player a AIR vyvolá dialogové okno s
informacemi o chybě. Například verze ladiče přehrávače Flash Player vyvolá následující dialogové okno popisující
chybu vygenerovanou, když se aplikace pokusí načíst soubor z neplatné adresy URL:
Většina událostí chyby je založena na třídě ErrorEvent a jako takové budou mít vlastnost pojmenovanou text, která
je uložena v chybovém hlášení zobrazeném aplikací Flash Player nebo AIR. Dvě výjimky jsou třídy StatusEvent a
NetStatusEvent. Obě tyto třídy mají vlastnost level (StatusEvent.level a NetStatusEvent.info.level). Když
je vlastnost level nastavena na hodnou "error", tyto typy událostí jsou považovány za události chyby.
Událost chyby nezpůsobí zastavení chodu souboru SWF. Projeví se pouze jako dialogové okno ve verzích ladicího
programu zásuvných modulů prohlížeče a samostatných přehrávačů, jako hlášení na výstupním panelu v přehrávači
a jako záznam v souboru protokolu pro vývojové prostředí Adobe Flex Builder 3. Neprojeví se ve všech vydaných
verzích aplikace Flash Player nebo AIR.
Příklad: budík
Příklad budíku je tvořen budíkem, který umožňuje uživateli specifikovat čas, ve kterém se budík vypne, stejně jako
hlášení, které se v daný čas zobrazí. Příklad budíku je postaven na aplikaci SimpleClock z kapitoly „Práce s daty a časy“
na stránce 129 Budík ukazuje několik aspektů práce s událostmi v jazyce ActionScript 3.0, včetně:
• Poslech a odpovídání na události
• Vyrozumění posluchačů o události
• Vytváření vlastních typů událostí
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace Budík naleznete ve složce Samples/AlarmClock. Aplikace zahrnuje následující soubory:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 260
Zpracování událostí
Soubor
Popis
AlarmClockApp.mxml
Hlavní soubor aplikace v programu Flash (FLA) nebo Flex (MXML).
nebo
AlarmClockApp.fla
com/example/programmingas3/clock/AlarmClock.as
Třída, která rozšiřuje třídu SimpleClock přidáním funkce budíku.
com/example/programmingas3/clock/AlarmEvent.as
Třída uživatelské události (podtřída flash.events.Event), která slouží
jako objekt události pro událost alarm třídy AlarmClock.
com/example/programmingas3/clock/AnalogClockFace.as
Vykreslí kruhové hodiny s hodinovou, minutovou a sekundovou
ručičkou na základě času (popsáno v příkladu SimpleClock).
com/example/programmingas3/clock/SimpleClock.as
Rozhraní součásti hodin s jednoduchou funkcí stopek (popsáno v
příkladu SimpleClock).
Přehled Budíku
Hlavní funkce budíku v tomto příkladu, včetně sledování času a zobrazení hodin, opětovně používá kód aplikace
SimpleClock, který je popsán v kapitole „Příklad: Jednoduché analogové hodiny“ na stránce 134. Třída AlarmClock
rozšiřuje třídu SimpleClock z příkladu přidáním funkce pro budík, včetně nastavení času buzení a informování o tom,
kdy bude budík vypnutý.
Poskytnutí informace o tom, kdy dojde k nějaké události, je úlohou pro kterou jsou události stvořeny. Třída
AlarmClock zpřístupňuje událost Alarm, které mohou jiné objekty naslouchat s cílem provedení různých činností.
Kromě toho třída AlarmClock používá instanci třídy Timer ke stanovení, kdy má spustit alarm. Podobně jako třída
AlarmClock, také třída Timer poskytuje událost a informuje ostatní objekty (v tomto případě instance AlarmClock),
když uplynul jistý čas. Podobně jako u většiny aplikací v jazyce ActionScript, události tvoří důležitou část funkce
vzorové aplikace Budík.
Spuštění budíku
Jak bylo uvedeno dříve, jedinou funkcí, kterou třída AlarmClock ve skutečnosti poskytuje, je nastavení a spuštění
budíku. Vestavěná třída Timer (flash.utils.Timer) poskytuje způsob, jak může vývojář definovat kód, který bude
spuštěn po specifikované době. Třída AlarmClock využívá instanci Timer pro stanovení, kdy má budík vypnout.
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* The Timer that will be used for the alarm.
*/
public var alarmTimer:Timer;
...
/**
* Instantiates a new AlarmClock of a given size.
*/
public override function initClock(faceSize:Number = 200):void
{
super.initClock(faceSize);
alarmTimer = new Timer(0, 1);
alarmTimer.addEventListener(TimerEvent.TIMER, onAlarm);
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 261
Zpracování událostí
Instance Timer definovaná v třídě AlarmClock je pojmenovaná alarmTimer. Metoda initClock(), která provádí
potřebná nastavení pro instanci AlarmClock, provádí s proměnnou alarmTimer dvě věci. Nejprve je proměnná
konkretizována s parametry, které poskytují instrukce instanci Timer, aby vyčkala 0 milisekund a spustí událost
budíku pouze jednou. Po konkretizaci alarmTimer kód zavolá metodu proměnné addEventListener() a signalizuje
tak, že chce naslouchat události timer této proměnné. Instance Timer pracuje odesláním události timer po uplynutí
stanovené doby. Třída AlarmClock bude muset znát, kdy je událost timer odeslána a nastaví tak vlastní budík.
Zavoláním addEventListener() se kód AlarmClock sám zaregistruje jako posluchač s alarmTimer. Dva parametry
signalizují, že třída AlarmClock chce poslouchat události timer (indikovaná konstantou TimerEvent.TIMER) a když
k události dojde, metoda onAlarm() třídy AlarmClock by měla být zavolána v odezvě na danou událost.
Chcete-li nastavit alarm, třída AlarmClock setAlarm() je zavolána následujícím způsobem:
/**
* Sets the time at which the alarm should go off.
* @param hour The hour portion of the alarm time.
* @param minutes The minutes portion of the alarm time.
* @param message The message to display when the alarm goes off.
* @return The time at which the alarm will go off.
*/
public function setAlarm(hour:Number = 0, minutes:Number = 0, message:String = "Alarm!"):Date
{
this.alarmMessage = message;
var now:Date = new Date();
// Create this time on today's date.
alarmTime = new Date(now.fullYear, now.month, now.date, hour, minutes);
// Determine if the specified time has already passed today.
if (alarmTime <= now)
{
alarmTime.setTime(alarmTime.time + MILLISECONDS_PER_DAY);
}
// Stop the alarm timer if it's currently set.
alarmTimer.reset();
// Calculate how many milliseconds should pass before the alarm should
// go off (the difference between the alarm time and now) and set that
// value as the delay for the alarm timer.
alarmTimer.delay = Math.max(1000, alarmTime.time - now.time);
alarmTimer.start();
return alarmTime;
}
Tato metoda provádí několik věcí, včetně uložení zprávy budíku a vytvoření objektu Date (alarmTime), který
zastupuje skutečný časový okamžik, kdy byl budík vypnutý. S největším významem pro stávající diskusi, v několika
posledních řádcích metody, je časovač proměnné alarmTimer nastaven a aktivován. Nejprve je zavolána jeho metoda
reset(), časovač se zastaví a resetuje se v případě, že je již spuštěn. Dále, stávající čas (zastoupen proměnou now) je
odečten od hodnoty proměnné alarmTime s cílem stanovit, kolik milisekund musí uplynout, než se budík vypne.
Třída Timer neaktivuje událost timer v absolutním čase, takže je to tento rozdíl relativního času, který je přiřazen
vlastnosti delay pro alarmTimer. Nakonec je zavolána metoda start() a časovač se ve skutečnosti spustí.
Jakmile uplynul specifický čas, alarmTimer odešle událost timer. protože třída AlarmClock registruje svou metodu
onAlarm() jako posluchače pro tuto událost, když dojde k události timer, je zavolána metoda onAlarm().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 262
Zpracování událostí
/**
* Called when the timer event is dispatched.
*/
public function onAlarm(event:TimerEvent):void
{
trace("Alarm!");
var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage);
this.dispatchEvent(alarm);
}
Metoda, která je registrována jako posluchač události musí být definovaná vhodným podpisem (tj. soubor parametrů
a zpětný typ metody). Má-li být metoda posluchačem pro událost timer třídy Timer, musí metoda definovat jeden
parametr, jehož datový typ je TimerEvent (flash.events.TimerEvent), podtřída třídy Event. Když instance Timer zavolá
své posluchače událost, předá instanci TimerEvent jako objekt události.
Informování ostatních o budíku
Podobně jako třída Timer, také třída AlarmClock poskytuje událost, která umožňuje ostatnímu kódu přijímat
oznámení, když je budík vypnut. Má-li třída používat rámec zpracování událostí vestavěných do jazyka ActionScript,
musí tato třída implementovat rozhraní flash.events.IEventDispatcher. To je nejběžnější provedeno rozšířením třídy
flash.events.EventDispatcher, která poskytuje standardní implementaci IEventDispatcher (nebo rozšířením jedné z
podtříd EventDispatcher). Jak bylo popsáno výše, třída AlarmClock rozšiřuje třídu SimpleClock, která zase rozšiřuje
třídu Sprite, která (prostřednictvím řetězce dědičnosti) rozšiřuje třídu EventDispatcher. To vše znamená, že třída
AlarmClock má již vestavěnou funkci poskytování vlastních událostí.
Jiný kód může registrovat oznámení události alarm třídy AlarmClock zavoláním metody addEventListener(),
kterou AlarmClock dědí z EventDispatcher. Když je instance AlarmClock připraven k oznámení jiné části kódu, že její
událost alarm byla aktivována, učiní tak zavoláním metody dispatchEvent(), která je také zděděna z
EventDispatcher.
var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage);
this.dispatchEvent(alarm);
Tyto řádky kódu jsou převzaty z metody onAlarm() třídy AlarmClock (dříve zobrazena celá). Je zavolána metoda
dispatchEvent() instance AlarmClock, která vyrozumí všechny registrované posluchače, že byla spuštěna událost
alarm instance AlarmClock. Parametr předaný do dispatchEvent() je objektem události, který bude předán
společně s metodami posluchače. V tomto případě se jedná o instanci třídy AlarmEvent, podtřídu Event, vytvořenou
specificky pro tento příklad.
Poskytnutí uživatelské události budíku
Všechny posluchače událostí získají parametr objektu události s informací o aktivaci specifické události. V mnoha
případech je objekt události instancí třídy Event. Nicméně v některých případech je užitečné posluchačům události
poskytnout další informace. Jak bylo popsáno výše v této kapitole, běžným způsobem jak toto uskutečnit je definování
nové třídy, podtřídy třídy Event, a použití instance této třídy jako objektu události. Na tomto příkladu je instance
AlarmEvent použita jako objekt události, když je odeslána událost alarm třídy AlarmClock. Třída AlarmEvent zde
zobrazená poskytuje další informace o události alarm, specificky hlášení budíku:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 263
Zpracování událostí
import flash.events.Event;
/**
* This custom Event class adds a message property to a basic Event.
*/
public class AlarmEvent extends Event
{
/**
* The name of the new AlarmEvent type.
*/
public static const ALARM:String = "alarm";
/**
* A text message that can be passed to an event handler
* with this event object.
*/
public var message:String;
/**
*Constructor.
*@param message The text to display when the alarm goes off.
*/
public function AlarmEvent(message:String = "ALARM!")
{
super(ALARM);
this.message = message;
}
...
}
Nejlepší způsob, jak vytvořit vlastní objekt události, je definovat třídu, která rozšiřuje třídu Event, jak je znázorněno v
předchozím příkladu. Chcete-li doplnit zděděnou funkčnost, musí třída AlarmEvent definovat vlastnost message
obsahující text hlášení budíku souvisejícího s událostí; hodnota message je předána jako parametr do konstruktoru
AlarmEvent. Třída AlarmEvent také definuje konstantu ALARM, kterou lze použít k odkazování na specifickou událost
(alarm) při zavolání metody addEventListener() třídy AlarmClock.
Kromě přidání vlastní funkčnosti musí každá podtřída Event potlačit zděděnou metodu clone() jako součást rámce
zpracování události jazyka ActionScript. Podtřídy Event mohou také volitelně potlačit zděděnou metodu toString()
a zahrnout vlastnosti vlastní události do hodnoty vrácené, když je zavolaná metoda toString().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 264
Zpracování událostí
/**
* Creates and returns a copy of the current instance.
* @return A copy of the current instance.
*/
public override function clone():Event
{
return new AlarmEvent(message);
}
/**
* Returns a String containing all the properties of the current
* instance.
* @return A string representation of the current instance.
*/
public override function toString():String
{
return formatToString("AlarmEvent", "type", "bubbles", "cancelable", "eventPhase",
"message");
}
Potlačená metoda clone() musí vrátit novou instanci podtřídy Event, se všemi uživatelskými vlastnostmi
nastavenými tak, aby odpovídaly stávající instanci. V potlačené metodě toString() se použije pomocná metoda
formatToString() (zděděná od Event) pro poskytnutí řetězce s názvem vlastního typu, stejně jako názvů a hodnoty
všech svých vlastností.
265
Kapitola 13: Programování zobrazení
Programování zobrazení v Adobe® ActionScript® 3.0 vám umožňuje pracovat s prvky, které se objeví na ploše
přehrávače Adobe® Flash® Player nebo Adobe® AIR™. Tato kapitola popisuje základní koncepty pro práci s prvky na
obrazovce. Zjistíte podrobnosti o programatickém uspořádání vizuálních prvků. Naučíte se také vytvářet své vlastní
třídy pro objekty zobrazení.
Základy programování zobrazení
Úvod do programování zobrazení
Každá aplikace vytvořená pomocí jazyka ActionScript 3.0 má hierarchii objektů zobrazení, která se nazývá seznam
zobrazení. Viz níže. Seznam zobrazení obsahuje všechny viditelné prvky v aplikaci.
Vymezená
Stageplocha
Instance hlavní
třídy souboru
SWF
Objekt zobrazení
Kontejner objektu
zobrazení
Kontejner objektu
zobrazení
Objekt zobrazení
Kontejner objektu
zobrazení
Objekt zobrazení
Kontejner objektu
zobrazení
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 266
Programování zobrazení
Jak ukazuje obrázek, elementy zobrazení lze rozdělit do jedné nebo více následujících skupin:
• Vymezená plocha
Plocha je základní kontejner pro objekty zobrazení. Každá aplikace má jeden objekt plochy, který obsahuje všechny
objekty zobrazení na obrazovce. Plocha je kontejner nejvyšší úrovně a je na prvním místě hierarchie seznamu
zobrazení:
Každý soubor SWF má přirazenou třídu jazyka ActionScript, která se nazývá hlavní třída souboru SWF. Když se v
aplikaci Flash Player nebo prostředí Adobe AIR otevře soubor SWF, vyvolá pro danou třídu funkci konstruktora a
vytvořená instance (jedná se vždy o typ objektu zobrazení) je přidána jako podřízený objekt plochy. Hlavní třída
souboru SWF vždy rozšiřuje třídu Sprite (pro více informací viz „Výhody přístupu seznamu zobrazení“ na
stránce 270).
Na plochu se dostanete pomocí vlastnosti stage jakékoliv instance třídy DisplayObject. Více informací naleznete
v části „Nastavení vlastností plochy“ na stránce 278.
• Objekty zobrazení
V jazyce ActionScript 3.0 jsou všechny prvky, které se zobrazí na obrazovce v aplikaci typy objektů zobrazení. Balík
flash.display zahrnuje třídu DisplayObject, která je základní třídou rozšířenou o několik dalších tříd. Tyto různé
třídy představují různé typy objektů zobrazení, jako jsou například vektorové tvary, filmové klipy a textová pole.
Přehled těchto tříd naleznete v části „Výhody přístupu seznamu zobrazení“ na stránce 270.
• Kontejnery objektů zobrazení
Kontejnery objektů zobrazení jsou zvláštní typy objektů zobrazení, které mají svou vlastní vizuální reprezentaci, a
mohou také obsahovat podřízené objekty, které jsou také objekty zobrazení.
Třída DisplayObjectContainer je podtřídou třídy DisplayObject. Objekt DisplayObjectContainer může obsahovat
více objektů zobrazení ve svém podřízenémseznamu. Například následující ilustrace ukazuje typ objektu
DisplayObjectContainer, známý jako Sprite, který obsahuje různé objekty zobrazení:
A
B
C
D
A. Objekt SimpleButton. Tento typ objektu zobrazení má různé stavy „nahoru”, „dolů” a „přes”. B. Objekt Bitmap. V tomto případě byl
objekt Bitmap načten z externího formátu JPEG pomocí objektu Loader. C. Objekt Shape. „Rámeček snímku” obsahuje zaoblený obdélník,
který je nakreslen v jazyce ActionScript. Na tento objekt Shape je použit filtr vrženého stínu. D. Objekt TextField.
V tomto kontextu objektů zobrazení jsou objekty DisplayObjectContainer známé také jako kontejnery objektů
zobrazení nebo jednodušekontejnery. Jak již bylo uvedeno dříve, plocha je kontejner objektů zobrazení.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 267
Programování zobrazení
Ačkoliv všechny viditelné objekty zobrazení dědí ze třídy DisplayObject, typ každého z nich je určitou podtřídou
třídy DisplayObject. Například funkce konstruktora existuje pro třídu Shape nebo Video, ale pro třídu
DisplayObject neexistuje žádná funkce konstruktora.
Běžné úlohy programování zobrazení
Protože mnoho programování v jazyce ActionScript zahrnuje vytvoření a manipulaci vizuálními prvky, existuje
několik úloh, které souvisí s programováním zobrazení. Tato kapitola popisuje běžné úlohy, které se vztahují na
všechny objekty zobrazení, včetně:
• Práce se seznamem zobrazení a kontejnery objektů zobrazení
• Přidávání objektů zobrazení do seznamu zobrazení
• Odstranění objektů ze seznamu zobrazení
• Přesouvání objektů mezi kontejnery zobrazení
• Přesouvání objektů před nebo za jiné objekty
• Práce s plochou
• Nastavení kmitočtu snímků
• Ovládání měřítka plochy
• Práce v režimu celé obrazovky
• Zpracování událostí objektů zobrazení
• Umístění objektů zobrazení, včetně vytvoření interakce přetažení
• Změna velikosti nebo měřítka a otáčení s objekty zobrazení
• Použití režimů prolnutí, transformací barev a průhlednosti na objekty zobrazení
• Maskování objektů zobrazení
• Animace objektů zobrazení
• Nahrání externího obsahu zobrazení (obrazů nebo souborů SWF)
Kapitoly dále v této příručce popisují další úlohy pro práci s objekty zobrazení. Mezi tyto úlohy patří ty, které se
vztahují na jakýkoliv objekt zobrazení, a úlohy přiřazené k určitým typům objektů zobrazení:
• Kreslení vektorové grafiky pomocí jazyka ActionScript na objektech zobrazení, viz část „Používání kreslicího
rozhraní API“ na stránce 314
• Použití geometrických transformací na objekty zobrazení, popsáno v části „Práce s geometrií“ na stránce 334
• Použítí efektů grafických filtrů, jako rozostření, záře, vržený stín a další, pro objekty zobrazení, viz části „Filtrování
objektů zobrazení“ na stránce 346
• Práce s vlastnostmi specifickými pro MovieClip, popsaná v části „Práce s filmovými klipy“ na stránce 398
• Práce s objekty TextField, popsaná v části „Práce s textem“ na stránce 423
• Práce s grafikou bitmapy, popsaná v části „Práce s bitmapami“ na stránce 473
• Práce s video prvky, popsaná v části „Práce s videem“ na stránce 515
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 268
Programování zobrazení
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Alfa: Hodnota barvy představující množství průhlednosti (nebo přesněji, množství neprůhlednosti) v barvě.
Například barva s hodnotou kanálu alfa 60 % ukazuje 60 % z plné intenzity a ze 40 % je průhledná.
• Bitmapová Grafika: Grafika, která je v počítači definována jako mřížka (řádky a sloupce) barevných obrazových
bodů. Běžné bitmapové grafiky zahrnují digitální fotografie a podobné obrazy.
• Režim prolnutí: Určuje, jak by měly obsahy dvou překrývajících se obrazů vzájemně reagovat. Neprůhledný obraz
nacházející se nad jiným obrazem obvykle blokuje spodní obraz, který tak není vůbec viditelný. Různé režimy
prolnutí však způsobí, že se barvy snímků navzájem prolnou různými způsoby, takže výsledný obsah je určitou
kombinací daných dvou obrazů
• Seznam zobrazení: Hierarchie objektů zobrazení, které budou vykreslovány jako viditelný obsah obrazovky
přehrávačem Flash Player a aplikací AIR. Plocha je kořen seznamu zobrazení a všechny objekty zobrazení, které
jsou připojeny k ploše nebo k některé z podřízených ploch, vytvářejí seznam zobrazení (i v případě, že objekt není
ve skutečnosti vykreslován, například pokud je mimo hranice plochy).
• Objekt zobrazení: Objekt, který představuje nějaký typ vizuálního obsahu v přehrávači Flash Player nebo aplikaci
AIR. Do seznamu zobrazení lze zahrnout pouze objekty zobrazení a všechny třídy objektů zobrazení jsou
podtřídami třídy DisplayObject.
• Kontejner objektu zobrazení: Zvláštní typ objektu zobrazení, který může obsahovat podřízené objekty zobrazení.
Kromě toho má obvykle vlastní vizuální znázornění.
• Hlavní třída souboru SWF: Třída, která definuje chování nejkrajnějšího objektu zobrazení v souboru SWF, který je
koncepčně třídou pro vlastní soubor SWF. Například soubor SWF vytvořený ve vývojovém prostředí Flash má
„hlavní časovou osu“, která obsahuje všechny ostatní časové osy; hlavní třída souboru SWF je třída, pro kterou je
časová osa instancí.
• Maskování: Technika, kdy jsou určité části obrazu skryty z pohledu (nebo opačně, kdy jsou určité části obrazu
zobrazeny). Části obrazu maskování budou průhledné, takže lze vidět obsah pod nimi. Tento termín souvisí s krycí
páskou, která při malování zabraňuje použití nátěru na určité oblasti.
• Plocha: Vizuální kontejner, který je základem nebo pozadím všech vizuálních obsahů v SWF.
• Transformace: Úprava vizuálních vlastností grafiky, jako je otočení objektu, změna velikosti, zkosení nebo
deformace tvaru či změna barvy.
• Grafika vektoru: Grafika, která je definována v počítači jako čáry a tvary nakreslené se zvláštními vlastnostmi
(například tloušťka, délka, velikost, úhel a poloha).
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Protože
se tato kapitola týká vytváření a manipulace s vizuálním obsahem, všechny kódy v této kapitole vytvářejí vizuální
objekty a zobrazení na obrazovce; testování vzorku zahrnuje zobrazení výsledku v přehrávači Flash Player nebo v
aplikaci AIR, nikoli zobrazení hodnot proměnných jako v předchozích kapitolách. Návod na vyzkoušení kódů
uvedených v této kapitole:
1 Pomocí vývojového nástroje Flash vytvořte prázdný dokument
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 269
Programování zobrazení
Zobrazíte výsledky kódu zobrazeného na obrazovce a na panelu Výstup se zobrazí všechna volání funkce trace().
Techniky pro zkoušení uvedených příkladů kódů jsou podrobněji vysvětleny v části „Testování příkladů kódu v této
kapitole“ na stránce 34.
Základní třídy zobrazení
Balíček flash.display v jazyce ActionScript 3.0 obsahuje třídy pro vizuální objekty, které lze zobrazit v přehrávači Flash
Player nebo v aplikaci AIR. Následující ilustrace ukazuje vztahy podtříd těchto tříd objektů základních zobrazení.
DisplayObject
AVM1Movie
Bitmap
InteractiveObject
DisplayObjectContainer SimpleButton
Loader
Sprite
MorphShape
Shape
StaticText
Video
TextField
Stage
MovieClip
Ilustrace zobrazuje dědění tříd objektů zobrazení. Všimněte si, že některé z těchto tříd, zvláště StaticText, TextField a
Video, nejsou součástí balíčku flash.display, ale budou zděděny z třídy DisplayObject.
Všechny třídy, které rozšiřují třídu DisplayObject, dědí její metody a vlastnosti. Více informací naleznete v části
„Vlastnosti a metody třídy DisplayObject“ na stránce 273.
Můžete konkretizovat objekty následujících tříd zobrazených v balíčku flash.display:
• Bitmap - Tato třída slouží k definici bitmapových objektů, buď načtených z externích souborů nebo vykreslených
pomocí jazyka ActionScript. Bitmapu můžete načíst z externích souborů pomocí třídy Loader. Načíst můžete
soubory ve formátech GIF, JPG nebo PNG. Můžete také vytvořit objekt BitmapData s vlastními daty a poté vytvořit
objekt Bitmap, který daná data používá. Můžete použít metody třídy BitmapData pro upravení bitmap, ať jsou
načteny nebo vytvořeny v jazyce ActionScript. Více informací naleznete v části „Načtení objektů zobrazení“ na
stránce 305 a „Práce s bitmapami“ na stránce 473.
• Loader - Třídu Loader používáte pro načtení externích datových zdrojů (buď souborů SWF nebo grafiky). Více
informací naleznete v části „Dynamické načtení obsahu zobrazení“ na stránce 305.
• Shape - Tato třída slouží k vytvoření vektorových grafik, například obdélníků, čar, kruhů, atd. Více informací
naleznete v části „Používání kreslicího rozhraní API“ na stránce 314.
• SimpleButton - Objekt SimpleButton je reprezentací jazyka ActionScript symbolu tlačítka vytvořeného ve
vývojovém nástroji Flash. Instance SimpleButton má čtyři stavy tlačítka: nahoru, dolů, nad a zahájit test (oblast,
která reaguje na události myši a klávesnice).
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 270
Programování zobrazení
• Sprite - objekt Sprite může obsahovat vlastní grafiku a také podřízené objekty zobrazení. (Třída Sprite rozšiřuje
třídu DisplayObjectContainer.) Více informací naleznete v části „Práce s kontejnery objektů zobrazení“ na
stránce 273 a „Používání kreslicího rozhraní API“ na stránce 314.
• MovieClip - Objekt MovieClip je forma jazyku ActionScript pro symbol filmového klipu vytvořeného ve
vývojovém nástroji Flash. V praxi se MovieClip podobá objektu Sprite, s výjimkou toho, že má časovou osu. Více
informací naleznete v části „Práce s filmovými klipy“ na stránce 398.
Následující třídy, které nejsou v balíčku flash.display, jsou podtřídami třídy DisplayObject:
• Třída TextField, která je součástí balíčku flash.text, je objekt zobrazení pro zobrazení textu a vstup. Více informací
naleznete v části „Práce s textem“ na stránce 423.
• Třída Video, která je součástí balíčku flash.media, je objektem zobrazení používaným pro zobrazování souborů
videa. Další informace naleznete v části „Práce s videem“ na stránce 515.
Následující třídy v balíčku flash.display rozšiřují třídu DisplayObject, ale nelze vytvořit jejich instance. Místo toho
slouží jako nadřazené třídy pro jiné objekty zobrazení a kombinují běžné funkce do jediné třídy.
• AVM1Movie - Třída AVM1Movie se používá pro znázornění načtených souborů SWF, které jsou vytvářeny v
jazyce ActionScript 1.0 a 2.0.
• DisplayObjectContainer - Třídy Loader, Stage, Sprite a MovieClip každá rozšiřují třídu DisplayObjectContainer.
Více informací naleznete v části „Práce s kontejnery objektů zobrazení“ na stránce 273.
• InteractiveObject - InteractiveObject je základní třída pro všechny objekty používané pro interakci s myší a
klávesnicí. Objekty SimpleButton, TextField, Loader, Sprite, Stage, a MovieClip jsou podtřídami třídy
InteractiveObject. Více informací ohledně vytváření interakcí myši a klávesnice naleznete v části „Zachycování
uživatelských vstupů“ na stránce 585.
• MorphShape - Tyto objekty jsou vytvářeny při vytváření doplnění tvaru v nástroji vytváření Flash. Objekty
nemůžete konkretizovat pomocí jazyka ActionScript, ale jsou přístupné ze seznamu zobrazení.
• Stage - Třída plochy rozšiřuje třídu DisplayObjectContainer. Pro aplikaci existuje jedna instance plochy a je
umístěna na prvním místě v hierarchii seznamu zobrazení. Na plochu se dostanete pomocí vlastnosti stage
jakékoliv instance DisplayObject. Více informací naleznete v části „Nastavení vlastností plochy“ na stránce 278.
Třída StaticText v balíčku flash.text rozšiřuje třídu DisplayObject, ale nelze vytvořit její instanci v kódu. Pole statického
textu jsou vytvářena pouze v aplikaci Flash.
Výhody přístupu seznamu zobrazení
V jazyce ActionScript 3.0 existují samostatné třídy pro různé typy objektů zobrazení. V jazyce ActionScript 1.0 a 2.0
je mnoho stejných typů objektů zahrnuto do jedné třídy: třída MovieClip.
Tato individualizace tříd a hierarchická struktura seznamů zobrazení má následující výhody:
• Efektivnější vykreslování a menší využití paměti
• Vylepšené řešení hloubky
• Plné křížení seznamu zobrazení
• Objekty zobrazení mimo seznam
• Snadnější vytváření podtříd objektů zobrazení
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 271
Programování zobrazení
Účinnější vykreslování a menší velikosti souborů
V jazyce ActionScript 1.0 a 2.0 můžete kreslit tvary pouze v objektu MovieClip. V jazyce ActionScript 3.0 existují
jednodušší třídy objektů zobrazení, ve kterých můžete kreslit tvary. Protože tyto třídy objektů zobrazení jazyka
ActionScript 3.0 neobsahují celou sadu metod a vlastností, které objekt MovieClip zahrnuje, využívají méně paměti
nebo procesoru.
Například každý objekt MovieClip obsahuje vlastnosti pro časovou osu filmového klipu, zatímco objekt Shape nikoliv.
Vlastnosti pro řízení časové osy mohou používat mnoho zdrojů paměti a procesoru. V jazyce ActionScript 3.0 vede
používání objektů Shape k lepším výsledkům. Objekt Shape má méně doplňků než složitější objekt MovieClip.
Aplikace Flash Player a AIR nepotřebuje spravovat nepoužívané vlastnosti MovieClip, které vylepšují rychlost a snižují
paměť používanou objekty.
Vylepšené řešení hloubky
V jazyce ActionScript 1.0 a 2.0 byla hloubka řešena prostřednictvím lineárního schématu řešení hloubky a metod,
například getNextHighestDepth().
Jazyk ActionScript 3.0 obsahuje třídu DisplayObjectContainer, která má výhodnější metody a vlastnosti pro řešení
hloubky objektů zobrazení.
Jestliže v jazyce ActionScript 3.0 přesouváte objekt zobrazení do nového umístění v podřízeném seznamu instance
DisplayObjectContainer, změní se automaticky poloha i jiných podřízených prvků v kontejneru objektu zobrazení a
jsou jim zde přiřazeny příslušné podřízené indexové pozice.
V jazyce ActionScript 3.0 je také vždy možné objevit všechny podřízené objekty jakéhokoliv kontejneru objektů
zobrazení. Každá instance DisplayObjectContainer má vlastnost numChildren, která uvádí počet podřízených prvků
v kontejneru objektů zobrazení. Vzhledem k tomu, že je podřízený seznam kontejneru objektů zobrazení vždy
indexovaným seznamem, můžete zkoumat všechny objekty v seznamu z indexované polohy 0 pomocí poslední
indexované polohy (numChildren - 1). Toto nebylo možné s metodami a vlastnostmi objektu MovieClip v jazyce
ActionScript 1.0 a 2.0.
V jazyce ActionScript 3.0 můžete snadno sekvenčně křížit seznam zobrazení; v podřízeném seznamu kontejneru
objektů zobrazení nejsou žádné mezery v číslech indexu. Křížení seznamu zobrazení a ovládání hloubky objektů je
snadnější, než v jazycích ActionScript 1.0 a 2.0. V jazycích ActionScript 1.0 a 2.0 mohl filmový klip obsahovat objekty
se střídavými mezerami v pořadí hloubky, což mělo za následek složitější křížení seznamu objektů. V jazyce
ActionScript 3.0 je každý podřízený seznam kontejnerů objektů zobrazení interně uložen do vyrovnávací paměti jako
pole, což umožňuje velice rychlé vyhledávání (dle indexu). Opakování všemi podřízenými prvky kontejneru objektů
zobrazení je také velice rychlé.
V jazyce ActionScript 3.0 máte také přístup k podřízeným prvkům v kontejneru objektů zobrazení použitím metody
getChildByName() třídy DisplayObjectContainer.
Plné křížení seznamu zobrazení
V jazycích ActionScript 1.0 a 2.0 jste neměli přístup k některým objektům, například k vektorovým tvarům, které byly
nakresleny v nástroji Flash. V jazyce ActionScript 3.0 máte přístup ke všem objektům na seznamu zobrazení - k těm
vytvořeným pomocí jazyka ActionScript a všem objektům zobrazení vytvořených v nástroji Flash. Podrobnosti
naleznete v části „Procházení seznamu zobrazení“ na stránce 277.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 272
Programování zobrazení
Objekty zobrazení mimo seznam
V jazyce ActionScript 3.0 můžete vytvářet objekty zobrazení, které nejsou na seznamu viditelného zobrazení. Tyto
objekty jsou nazývány objekty zobrazení mimo seznam. Objekt zobrazení je přidán k seznamu viditelného zobrazení
pouze vyvoláte-li metodu addChild() nebo addChildAt() instance DisplayObjectContainer, která již byla do
seznamu zobrazení přidána.
Objekty zobrazení mimo seznam můžete používat pro sestavování složitých objektů zobrazení, jako jsou ty, které mají
více kontejnerů objektů zobrazení obsahující násobné objekty zobrazení. Uchováváním objektů zobrazení mimo
seznam můžete sestavovat komplikované objekty bez použití času zpracování k vykreslování těchto objektů zobrazení.
Poté můžete objekt zobrazení mimo seznam kdykoliv přidat do seznamu zobrazení. Můžete také přesunout podřízený
prvek kontejneru objektů zobrazení do a mimo seznam a do jakékoliv požadované polohy v seznamu zobrazení.
Snadnější vytváření podtříd objektů zobrazení
V jazyce ActionScript 1.0 a 2.0 byste často pro vytvoření základních tvarů nebo pro zobrazení bitmap museli přidat
nový objekt MovieClip do souboru SWF. V jazyce ActionScript 3.0 zahrnuje třída DisplayObject mnoho
zabudovaných podtříd, včetně tvaru a bitmapy. Protože třídy v jazyce ActionScript 3.0 jsou více zaměřeny na specifické
typy objektů, je snazší vytvořit základní podtřídy těchto zabudovaných podtříd.
Například pro nakreslení kruhu v jazyce ActionScript 2.0 jste mohli vytvořit třídu CustomCircle, která rozšiřuje třídu
MovieClip, jestliže je objekt vlastní třídy konkretizován. Nicméně tato třída by také obsahovala několik vlastností a
metod z třídy MovieClip (například totalFrames), které se na tuto třídu nevztahují. V jazyce ActionScript 3.0 můžete
nicméně vytvořit třídu CustomCircle, která rozšiřuje objekt Shape a nezahrnuje nesouvisející vlastnosti a metody,
které jsou obsaženy ve třídě MovieClip. Následující kód ukazuje příklad třídy CustomCircle:
import flash.display.*;
public class CustomCircle extends Shape
{
var xPos:Number;
var yPos:Number;
var radius:Number;
var color:uint;
public function CustomCircle(xInput:Number,
yInput:Number,
rInput:Number,
colorInput:uint)
{
xPos = xInput;
yPos = yInput;
radius = rInput;
color = colorInput;
this.graphics.beginFill(color);
this.graphics.drawCircle(xPos, yPos, radius);
}
}
Práce s objekty zobrazení
Nyní, když chápete základní koncepty plochy, kontejnerů objektů zobrazení a seznamu zobrazení, vám tato část nabízí
podrobnější informace o práci s objekty zobrazení v jazyce ActionScript 3.0.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 273
Programování zobrazení
Vlastnosti a metody třídy DisplayObject
Všechny objekty zobrazení jsou podtřídy třídy DisplayObject a jako takové dědí vlastnosti a metody třídy
DisplayObject. Zděděné vlastnosti jsou základními vlastnostmi, které se vztahují na všechny objekty zobrazení.
Například každý objekt zobrazení má vlastnostxa vlastnost y, která určuje polohu objektu v jeho kontejneru objektů
zobrazení.
Nemůžete vytvořit instanci DisplayObject pomocí konstruktoru třídy DisplayObject. Musíte vytvořit jiný typ objektu
(objekt, který je podtřídou třídy DisplayObject), například Sprite, pro konkretizaci objektu s operátorem new. Také
pokud si přejete vytvořit vlastní třídu objektu zobrazení, musíte vytvořit podtřídu jedné z podtříd objektů zobrazení,
které mají použitelnou funkci konstruktoru (například třída Shape nebo třída Sprite). Pro více informací viz popis
třídy DisplayObject v Referenční příručce jazyka ActionScript 3.0 a jeho komponent.
Přidávání objektů zobrazení do seznamu zobrazení
Jestliže konkretizujete objekt zobrazení, nezobrazí se na obrazovce (na ploše) dokud instanci objektu zobrazení
nepřidáte do kontejneru objektů zobrazení, který je uveden na seznamu zobrazení. Například v následujícím kódu
objekt TextField myText by nebyl viditelný, pokud byste vypustili poslední řádek kódu. Na posledním řádku kódu se
musí klíčové slovo this vztahovat ke kontejneru objektů zobrazení, který je již přidán do seznamu zobrazení.
import flash.display.*;
import flash.text.TextField;
var myText:TextField = new TextField();
myText.text = "Buenos dias.";
this.addChild(myText);
Jestliže přidáte jakýkoliv vizuální prvek k ploše, stane se daný prvek podřízeným prvkem objektu Stage. První soubor
SWF načtený v aplikaci (například soubor, který vložíte na stránku HTML) je automaticky přidán jako podřízený
soubor plochy. Může to být objekt jakéhokoliv typu, který rozšiřuje třídu Sprite.
Jakékoliv objekty zobrazení, které vytvořítebez použití jazyka ActionScript—například přidáním tagu MXML do
Adobe Flex Builder 3 nebo umístěním položky na plochu v přehrávači Flash jsou přidány do seznamu zobrazení.
Ačkoliv tyto objekty zobrazení nepřidáváte prostřednictvím jazyka ActionScript, máte k nim prostřednictvím jazyka
ActionScript umožněn přístup. Například následující kód přizpůsobuje šířku objektu pojmenovaného button1, který
byl přidán v nástroji pro vytváření (nikoliv prostřednictvím jazyka ActionScript):
button1.width = 200;
Práce s kontejnery objektů zobrazení
Jestliže je objekt DisplayObjectContainer vymazán ze seznamu zobrazení nebo jestliže je přesunut nebo jiným
způsobem změněn, každý objekt zobrazený v DisplayObjectContainer je také odstraněn, přesunut nebo změněn.
Samotný kontejner objektu zobrazení je typem objektu zobrazení - lze jej přidat k jinému kontejneru objektu
zobrazení. Například následující snímek ukazuje kontejner objektu zobrazení pictureScreen, který obsahuje jeden
tvar obrysu a čtyři jiné kontejnery objektu zobrazení (typu PictureFrame):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 274
Programování zobrazení
A
B
A. Tvar definující hranici kontejneru zobrazení pictureScreen B. Čtyři kontejnery objektů zobrazení, které jsou podřízené objektu
pictureScreen
Chcete-li v seznamu zobrazení uvést objekt zobrazení, musíte jej přidat ke kontejneru objektů zobrazení, který je na
seznamu zobrazení. Přidání provedete pomocí metody addChild() nebo metodou addChildAt() objektu
kontejneru. Například bez závěrečného řádku následujícího kódu by se objekt myTextField nezobrazil:
var myTextField:TextField = new TextField();
myTextField.text = "hello";
this.root.addChild(myTextField);
V této ukázce kódu ukazuje this.root kontejner objektu zobrazení MovieClip, který daný kód obsahuje. Ve
skutečném kódu můžete určit odlišný kontejner.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 275
Programování zobrazení
Použijte metodu addChildAt() pro přidání podřízeného prvku k určité pozici v podřízeném seznamu kontejneru
objektu zobrazení. Tyto indexové polohy v podřízeném seznamu se základem v nule se vztahují k rozvržení (pořadí
odpředu dozadu) objektů zobrazení. Zvažte například následující tři objekty zobrazení. Každý objekt byl vytvořen z
vlastní třídy nazvané Ball.
Rozvržení těchto objektů zobrazení v jejich kontejnerech lze upravit pomocí metody addChildAt(). Posuďte
například následující kód:
ball_A = new Ball(0xFFCC00, "a");
ball_A.name = "ball_A";
ball_A.x = 20;
ball_A.y = 20;
container.addChild(ball_A);
ball_B = new Ball(0xFFCC00, "b");
ball_B.name = "ball_B";
ball_B.x = 70;
ball_B.y = 20;
container.addChild(ball_B);
ball_C = new Ball(0xFFCC00, "c");
ball_C.name = "ball_C";
ball_C.x = 40;
ball_C.y = 60;
container.addChildAt(ball_C, 1);
Po provedení tohoto kódu jsou objekty zobrazení umístěny do container objektu DisplayObjectContainer
následovně. Všimněte si rozvržení objektů.
Pro změnu polohy objektu na první místo seznamu zobrazení jej jednoduše znovu přidejte do seznamu. Například po
předcházejícím kódu přesuňte ball_A na první místo skupiny, použijte tento řádek kódu:
container.addChild(ball_A);
Tento kód účinně odstraní ball_A z jeho umístění v seznamu zobrazení container a znovu jej přidá na první místo
v seznamu - konečným výsledkem je jeho přesunutí navrch hromádky.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 276
Programování zobrazení
Můžete použít metodu getChildAt() pro ověření pořadí vrstev objektů zobrazení. Metoda getChildAt() vrátí
podřízené objekty kontejneru založené na číslu indexu, které jim přiřadíte. Následující kód například odhaluje jména
objektů zobrazení na různých pozicích v podřízeném seznamu container objektu DisplayObjectContainer:
trace(container.getChildAt(0).name); // ball_A
trace(container.getChildAt(1).name); // ball_C
trace(container.getChildAt(2).name); // ball_B
Jestliže odstraníte objekt zobrazení z podřízeného seznamu nadřazeného kontejneru, vyšší prvky seznamu se posunou
o pozici dolů v podřízeném indexu. V návaznosti na předcházející kód například následující kód ukazuje, jak se objekt
zobrazení, který byl na pozici 2 v container DisplayObjectContainer přesune do pozice 1, jestliže je objekt zobrazení
níže v podřízeném seznamu odstraněn:
container.removeChild(ball_C);
trace(container.getChildAt(0).name); // ball_A
trace(container.getChildAt(1).name); // ball_B
Metody removeChild() a removeChildAt() neodstraní úplně instance objektů zobrazení. Tyto metody je jednoduše
odstraní z podřízeného seznamu kontejneru. K instanci lze stále odkazovat pomocí jiné proměnné. (Pomocí operátoru
delete úplně odstraníte objekt.)
Vzhledem k tomu, že objekt zobrazení má pouze jeden nadřazený kontejner, můžete přidat instanci objektu zobrazení
pouze do jednoho kontejneru objektu zobrazení. Například následující kód ukazuje, že objekt zobrazení tf1 může
existovat pouze v jednom kontejneru (v tomto případě je to Sprite, který rozšiřuje třídu DisplayObjectContainer):
tf1:TextField = new TextField();
tf2:TextField = new TextField();
tf1.name = "text 1";
tf2.name = "text 2";
container1:Sprite = new Sprite();
container2:Sprite = new Sprite();
container1.addChild(tf1);
container1.addChild(tf2);
container2.addChild(tf1);
trace(container1.numChildren); // 1
trace(container1.getChildAt(0).name); // text 2
trace(container2.numChildren); // 1
trace(container2.getChildAt(0).name); // text 1
Jestliže přidáte objekt zobrazení, který je obsažen v jednom kontejneru objektů zobrazení do jiného kontejneru objektů
zobrazení, je odstraněn z prvního podřízeného seznamu kontejneru objektů zobrazení.
Vedle výše popsaných metod třída DisplayObjectContainer definuje několik metod pro práci s podřízenými objekty
zobrazení, včetně následujících:
• Metoda contains(): Určuje, zda je objekt zobrazení podřízeným objektem DisplayObjectContainer.
• Metoda getChildByName(): Dosadí objekt zobrazení podle názvu.
• Metoda getChildIndex(): Vrátí indexovou polohu objektu zobrazení.
• Metoda setChildIndex(): Změní polohu podřízeného objektu zobrazení.
• Metoda swapChildren(): Přepíná pořadí vpředu-vzadu dvou zobrazených objektů.
• Metoda swapChildrenAt(): Přepíná pořadí vpředu-vzadu dvou objektů zobrazení, určené jejich indexovými
hodnotami.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 277
Programování zobrazení
Pro více informací viz relevantní záznamy v Referenční příručce jazyka ActionScript 3.0 a jeho komponent.
Vzpomeňte si, že objekt zobrazení, který leží mimo seznam zobrazení - ten, který není obsažen v kontejneru objektů
zobrazení, který je podřízeným prvkem plochy - je znám jako objekt zobrazení mimo seznam.
Procházení seznamu zobrazení
Jak jste si již všimli, seznam zobrazení má stromovou strukturu. Na vrcholu stromu je plocha, která může obsahovat
více objektů zobrazení. Tyto objekty zobrazení, které jsou sami kontejnery objektů zobrazení, mohou obsahovat jiné
objekty zobrazení nebo kontejnery zobrazení.
Vymezená
Stageplocha
Instance hlavní
třídy souboru
SWF
Objekt zobrazení
Kontejner objektu
zobrazení
Kontejner objektu
zobrazení
Objekt zobrazení
Kontejner objektu
zobrazení
Objekt zobrazení
Kontejner objektu
zobrazení
Třída DisplayObjectContainer zahrnuje vlastnosti a metody pro křížení seznamu zobrazení, prostřednictvím
podřízených seznamů kontejnerů objektu zobrazení. Vezměme například následující kód, který přidá dva objekty
zobrazení, title a pict k objektu container (který je Sprite a třída Sprite rozšiřuje třídu DisplayObjectContainer):
var container:Sprite = new Sprite();
var title:TextField = new TextField();
title.text = "Hello";
var pict:Loader = new Loader();
var url:URLRequest = new URLRequest("banana.jpg");
pict.load(url);
pict.name = "banana loader";
container.addChild(title);
container.addChild(pict);
Metoda getChildAt() vrátí podřízený prvek seznamu zobrazení v určité poloze indexu:
trace(container.getChildAt(0) is TextField); // true
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 278
Programování zobrazení
podřízené objekty jsou také přístupné podle jména. Každý objekt zobrazení má vlastnost jména a jestliže ji nepřiřadíte,
přiřadí přehrávač Flash Player nebo aplikace AIR výchozí hodnotu, například "instance1". Například následující
kód ukazuje, jak použít metodu getChildByName() pro přístup k podřezanému objektu zobrazení s názvem "banana
loader":
trace(container.getChildByName("banana loader") is Loader); // true
Použití metody getChildByName() může mít za následek pomalejší výkon než v případě použití metody
getChildAt().
Protože kontejner objektů zobrazení může ve svém seznamu zobrazení obsahovat jiné kontejnery objektu zobrazení
jako podřízené objekty, můžete zkřížit plný seznam zobrazení aplikace jako strom. Například ve výpisu kódu
uvedeném dříve je po dokončení operace načítání pro objekt pict Loader načten pro objekt pict jeden podřízený
objekt zobrazení, což je bitmapa. Pro přístup k tomuto objektu zobrazení bitmapy můžete zadat
pict.getChildAt(0). Můžete také zadat container.getChildAt(0).getChildAt(0) (protože
container.getChildAt(0) == pict).
Následující funkce poskytuje výstup zamýšleného trace() seznamu zobrazení z kontejneru objektů zobrazení:
function traceDisplayList(container:DisplayObjectContainer,indentString:String = ""):void
{
var child:DisplayObject;
for (var i:uint=0; i < container.numChildren; i++)
{
child = container.getChildAt(i);
trace(indentString, child, child.name);
if (container.getChildAt(i) is DisplayObjectContainer)
{
traceDisplayList(DisplayObjectContainer(child), indentString + "")
}
}
}
Nastavení vlastností plochy
Třída Stage potlačí většinu vlastností a metod třídy DisplayObject. Jestliže vyvoláte jednu z těchto potlačených
vlastností nebo metod, zobrazí přehrávač Flash Player nebo AIR výjimku. Například objekt Stage nemá vlastnosti x
nebo y, protože je jeho pozice fixována jako hlavní kontejner pro aplikaci. Vlastnosti xa y se vztahují k pozici objektu
zobrazení relativní k jeho kontejneru, a protože plocha není obsažena v žádném jiném kontejneru objektu zobrazení,
tyto vlastnosti se nepoužijí.
Poznámka: Některé vlastnosti a metody třídy Stage jsou dostupné pouze pro objekty zobrazení, které jsou ve stejné
bezpečnostní schránce jako první načtený soubor SWF. Podrobnosti naleznete v části „Zabezpečení plochy“ na
stránce 705
Ovládání rychlosti zpětného přehrávání obrazů
Vlastnost framerate třídy Stage se používá pro nastavení kmitočtu obrazů pro všechny soubory SWF načtené do
aplikace. Pro více informací viz Referenční příručka jazyka ActionScript 3.0 a jeho komponent.
Ovládání měřítka plochy
Při změně velikosti části obrazovky představující přehrávač Flash Player nebo AIR, Flash Player nebo AIR automaticky
upraví obsah plochy tak, aby odpovídal. Vlastnost třídy plochy scaleMode určuje, jak se obsah plochy upraví. Tuto
vlastnost lze nastavit na čtyři různé hodnoty, definované jako obsah ve třídě flash.display.StageScaleMode.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 279
Programování zobrazení
Pro tři z hodnot scaleMode (StageScaleMode.EXACT_FIT, StageScaleMode.SHOW_ALL, a
StageScaleMode.NO_BORDER), změní přehrávač Flash Player a AIR měřítko obsahu plochy tak, aby byl uvnitř jejích
hranic. Tyto tři možnosti se liší v určení, jak je změny stupnice dosaženo:
•
StageScaleMode.EXACT_FIT určuje poměrnost SWF.
•
StageScaleMode.SHOW_ALL určuje, zda se zobrazí ohraničení, například černé lišty, které se objeví při zobrazení
širokoúhlého filmu na standardní televizi.
•
StageScaleMode.NO_BORDER určuje, zdamůže být obsah částečně odříznut nebo ne.
Jestliže je scaleMode nastaveno na StageScaleMode.NO_SCALE, obsah plochy si při změně velikosti okna přehrávače
Flash Player nebo aplikace AIR uchová svou definovanou velikost. Pouze v tomto režimu měřítka lze vlastnosti
plochyWidth a Height třídy Stage použít k určení skutečných rozměrů obrazového bodu okna se změněnou velikostí.
(V jiných režimech měřítka vlastnosti stageWidth a stageHeight vždy odrážejí původní šířku a výšku SWF.) Jestliže
je vlastnost scaleMode nastavena na StageScaleMode.NO_SCALE a u souboru SWF je změněna velikost, událost
resize třídy Stage je odeslána a umožní provedení úprav.
Je-li následně vlastnost scaleMode nastavena na StageScaleMode.NO_SCALE, umožní vám větší kontrolu nad tím,
jak se obsah obrazovky mění se změnou velikosti okna. Například v souboru SWF obsahujícím video a ovládací lištu
si můžete přát, aby ovládací lišta měla v případě změny velikosti plochy stejnou velikost a změnit pouze velikost okna
videa tak, aby se přizpůsobilo změně velikosti plochy. To je ukázáno na následujícím příkladě:
// videoScreen is a display object (e.g. a Video instance) containing a
// video; it is positioned at the top-left corner of the Stage, and
// it should resize when the SWF resizes.
//
//
//
//
controlBar is a display object (e.g. a Sprite) containing several
buttons; it should stay positioned at the bottom-left corner of the
Stage (below videoScreen) and it should not resize when the SWF
resizes.
import
import
import
import
flash.display.Stage;
flash.display.StageAlign;
flash.display.StageScaleMode;
flash.events.Event;
var swfStage:Stage = videoScreen.stage;
swfStage.scaleMode = StageScaleMode.NO_SCALE;
swfStage.align = StageAlign.TOP_LEFT;
function resizeDisplay(event:Event):void
{
var swfWidth:int = swfStage.stageWidth;
var swfHeight:int = swfStage.stageHeight;
// Resize the video window.
var newVideoHeight:Number = swfHeight - controlBar.height;
videoScreen.height = newVideoHeight;
videoScreen.scaleX = videoScreen.scaleY;
// Reposition the control bar.
controlBar.y = newVideoHeight;
}
swfStage.addEventListener(Event.RESIZE, resizeDisplay);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 280
Programování zobrazení
Práce v režimu celé obrazovky
Režim celé obrazovky vám umožňuje nastavit plochu filmu tak, aby zaplnila celý monitoru bez jakýchkoliv hranic
nebo nabídek kontejnerů. Vlastnost třídy Stage displayState se používá k zapínání a vypínání režimu plné
obrazovky v souboru SWF. Vlastnost displayState může být nastavena na jednu z hodnot definovanou konstantami
ve třídě flash.display.StageDisplayState. Jestliže chcete zapnout režim celé obrazovky, nastavte vlastnost
displayState na StageDisplayState.FULL_SCREEN:
stage.displayState = StageDisplayState.FULL_SCREEN;
V aplikaci Flash Player může být režim celé obrazovky iniciován pouze pomocí jazyka ActionScript v reakci na
klepnutí myší (včetně klepnutím pravým tlačítkem) nebo stisknutím klávesy. Obsah aplikace AIR běžící v
bezpečnostní schránce aplikace nevyžaduje, aby byl režim celé obrazovky aktivován reakcí na gesto uživatele.
Jestliže chcete režim celé obrazovky ukončit, nastavte vlastnost displayState na StageDisplayState.NORMAL.
stage.displayState = StageDisplayState.NORMAL;
Navíc může uživatel odejít z režimu celé obrazovky přepnutím výběru do jiného okna nebo použitím jedné z několika
kombinací kláves: Esc (všechny platformy), Ctrl-W (Windows), Apple-W (Mac) nebo Alt-F4 (Windows).
Povolení režimu celé obrazovky v přehrávači Flash Player
Chcete-li povolit režim celé obrazovky pro soubor SWF vložený do stránky HTML, musí kód HTML, který bude
obsahovat přehrávač Flash Player, zahrnovat tag param, atribut embed s názvem allowFullScreen a hodnotou true,
a to následovně:
<object>
...
<param name="allowFullScreen" value="true" />
<embed ... allowfullscreen="true" />
</object>
Vyberte ve vývojovém nástroji Flash položky Soubor -> Nastavení publikování a v dialogovém okně Nastavení
publikování na kartě HTML zvolte položku Pouze Flash - Povolit šablonu celé obrazovky.
V programu Flex se ujistěte, zda šablona HTML obsahuje tagy <object> a <embed>, které podporují režim celé
obrazovky.
Jestliže pro generování SWF-vkládajících tagů používáte JavaScript na webové stránce, musíte upravit JavaScript pro
přidání tagu allowFullScreen param a atributu. Například jestli vaše stránka HTML používá
funkciAC_FL_RunContent() (která je používána HTML stránkami vytvářenými v aplikacích Flex Builder i Flash),
měli byste přidat parametr allowFullScreen pro volání dané funkce následovně:
AC_FL_RunContent(
...
'allowFullScreen','true',
...
); //end AC code
Toto se nevztahuje na soubory SWF spuštěné v samostatném přehrávači Flash Player.
Poznámka: Jestliže nastavíte režim okna (wmode v jazyku HTML) na možnost Neprůhledné bez okna (neprůhledné)
nebo Průhledné bez okna (průhledné), bude okno celé obrazovky vždy neprůhledné.
Používání režimu celé obrazovky s přehrávačem Flash Player v prohlížeči má také omezení související se
zabezpečením. Tato omezení jsou popsána v „Zabezpečení přehrávače Flash Player“ na stránce 688.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 281
Programování zobrazení
Velikost a změna velikosti vymezené plochy v režimu celé obrazovky
Vlastnosti Stage.fullScreenHeight a Stage.fullScreenWidth vrátí výšku a šířku monitoru, který je použit při
přechodu na celou obrazovku, jestliže je daný stav ihned aktivován. Tyto hodnoty nemusí být správné, pokud má
uživatel po načtení těchto hodnot, ale před přechodem na celou obrazovku, možnost přesunout prohlížeč z jednoho
monitoru na druhý. Pokud tyto hodnoty získáte ve stejném manipulačním programu události, ve kterém jste nastavili
vlastnost Stage.displayState na hodnotu StageDisplayState.FULL_SCREEN, jsou tyto hodnoty správné.
U uživatelů s více monitory se obsah SWF rozšíří tak, aby vyplnil pouze jeden monitor. Aplikace Flash Player i AIR
používají metrický systém za účelem určení, který monitor obsahuje největší podíl SWF, a tento monitor použijí pro
režim celé obrazovky. Vlastnosti fullScreenHeight a fullScreenWidth odráží pouze velikost monitoru, který slouží pro
režim celé obrazovky . Další informace naleznete v částech Stage.fullScreenHeight a Stage.fullScreenWidth
dokumentu Referenční příručka jazyka ActionScript 3.0 a jeho komponent.
Chování změny měřítka pro režim celé obrazovky je stejné jako za běžnému režimu; změna měřítka je ovládání
vlastností třídy Stage scaleMode. Jestliže je vlastnost scaleMode nastavena na StageScaleMode.NO_SCALE, vlastnosti
plochy stageWidth a stageHeight se změní tak, aby odrážely velikost prostoru obrazovky, který zabírá soubor SWF
(v tomto případě je to celá obrazovka); jestliže je parametr HTML zobrazen v prohlížeči, ovládá nastavení.
Událost třídy Stage fullScreen můžete použít tak, aby detekovala a reagovala při zapnutí nebo vypnutí režimu celé
obrazovky. Při zapínání nebo vypínání režimu celé obrazovky můžete chtít například změnit polohu, přidat nebo
odstranit položky z obrazovky, jako v tomto případě:
import flash.events.FullScreenEvent;
function fullScreenRedraw(event:FullScreenEvent):void
{
if (event.fullScreen)
{
// Remove input text fields.
// Add a button that closes full-screen mode.
}
else
{
// Re-add input text fields.
// Remove the button that closes full-screen mode.
}
}
mySprite.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenRedraw);
Jak ukazuje tento kód, je objekt události pro událost fullScreen instancí třídy flash.events.FullScreenEvent, která
zahrnuje vlastnost fullScreen určující, zda je režim celé obrazovky aktivován (true (pravda)) nebo nikoliv (false
(nepravda)).
Podpora klávesnice v režimu celé obrazovky
Je-li přehrávač Flash Player spuštěný v prohlížeči, jsou v režimu celé obrazovky zakázány všechny skripty jazyka
ActionScript související s klávesnicí, jako jsou události klávesnice a zadávání textu do instancí TextField. Výjimkami
jsou tyto povolené klávesy:
• Klávesy nesouvisející s tiskem – konkrétně šipky, mezerník a klávesa Tab.
• Klávesové zkratky pro ukončení režimu celé obrazovky: Esc (v systému Windows i počítačích Macintosh), Ctrl-W
(Windows), Apple-W (Macintosh) a Alt-F4.
Pro obsah SWF, který je spuštěný v samostatné aplikaci Flash Player nebo AIR, tato omezení neexistují. Aplikace AIR
podporuje interaktivní režim na celou obrazovku, který umožňuje vstupy klávesnice.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 282
Programování zobrazení
Hardwarová změna měřítka v režimu celé obrazovky
Můžete použít vlastnost třídy Stage fullScreenSourceRect pro nastavení přehrávače Flash Player nebo aplikace AIR
na změnu měřítka určité oblasti plochy na režim celé obrazovky. Je-li tato možnost k dispozici, provádí aplikace Flash
Player i AIR změnu měřítka hardwarově; tím se využije grafická a video karta v počítači a obsah se obecně zobrazí
rychleji než při programové změně měřítka.
Chcete-li využít výhod hardwarové změny velikosti, nastavte celou nebo část vymezené plochy na režim celé
obrazovky. Následující kód jazyka ActionScript 3.0 nastaví celou vymezenou plochu na režim celé obrazovky:
import flash.geom.*;
{
stage.fullScreenSourceRect = new Rectangle(0,0,320,240);
stage.displayState = StageDisplayState.FULL_SCREEN;
}
Jestliže je tato vlastnost nastavena pro platný obdélník a vlastnost displayState je nastavena na režim celé obrazovky,
přehrávač Flash Player změní velikost určené oblasti. Aktuální velikost vymezené plochy v obr. bodech v rámci jazyka
ActionScript se nemění. Přehrávač Flash Player a AIR uplatní minimální omezení velikosti obdélníku, aby se
přizpůsobil standardní zprávě „Press Esc to exit full-screen mode“. Tento limit je obvykle okolo 260 na 30 obr. bodů,
ale může se lišit v závislosti na platformě a verzi přehrávače Flash Player.
Vlastnost fullScreenSourceRect může být nastavena pouze když přehrávač Flash Player nebo AIR není v režimu
celé obrazovky. Chcete-li tuto vlastnost použít správně, nejdříve nastavte tuto vlastnost a potom nastavte vlastnost
displayState na režim celé obrazovky.
Chcete-li povolit změnu měřítka, nastavte vlastnost fullScreenSourceRect na objekt obdélníku.
stage.fullScreenSourceRect = new Rectangle(0,0,320,240);
Chcete-li zakázat změnu měřítka, nastavte vlastnost fullScreenSourceRect na hodnotu null.
stage.fullScreenSourceRect = null;
Chcete-li využívat výhod funkcí hardwarové akcelerace u přehrávače Flash Player, zapněte tuto volbu pomocí
dialogového okna nastavení přehrávače Flash Player. Chcete-li toto dialogové okno načíst, klepněte ve svém prohlížeči
na obsah přehrávače Flash Player pravým tlačítkem (Windows) nebo s klávesou Ctrl (Macintosh). Vyberte kartu
Zobrazení, která je kartou první, a zaškrtněte políčko: Povolit hardwarovou akceleraci.
Přímé režimy okna a režimy skládání GPU
Přehrávač Flash Player 10 uvádí dva režimy okna – přímé okno a okno skládání GPU, které můžete povolit nastavením
publikování ve vývojovém nástroji Flash. Tyto režimy nejsou v aplikaci AIR podporovány. Jestliže chcete využít výhod
těchto režimů, musíte pro přehrávač Flash Player povolit hardwarovou akceleraci.
Přímý režim používá rychlejší, nejpřímější cestu k posunutí grafiky na obrazovku, což je výhodné pro přehrávání
videa.
Skládání GPU používá k akceleraci skládání jednotku pro zpracování grafiky na video kartě. Skládání videa je proces
vrstvení více obrazů k vytvoření jediného obrazu videa. Při akceleraci skládání s GPU může dojít k vylepšení výkonu
konverze YUV, opravy barev, rotace, změny měřítka nebo prolnutí. YUV konverze odkazuje na konverzi barev
složených analogových signálů použitých pro přenosy na barevný model RGB (červená, zelená, modrá), který
používají video kamery a displeje. Používání GPU pro urychlení skládání snižuje požadavky na paměť a skládání, které
jsou jinak kladeny na CPU. Výsledkem je také hladší přehrávání pro standardně definované video.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 283
Programování zobrazení
Při implementaci těchto režimů oken buďte opatrní. Používání skládání GPU může být náročné pro paměť a zdroje a
CPU. Jestliže nelze některé operace (například režimy prolnutí, filtrování, ořezání nebo maskování) provést v GPU,
budou provedeny softwarem. Společnost Adobe doporučuje omezit se při používání těchto režimů na jeden soubor
SWF na každou stránku HTML. Tyto režimy by neměly být povoleny pro bannery. Zařízení Flash Test Movie
nepoužívá hardwarovou akceleraci, ale můžete jí použít pomocí volby Publikovat náhled.
Nastavení kmitočtu snímků v souboru SWF na hodnotu vyšší než 60 (maximální kmitočet aktualizace obrazovky) je
zbytečné. Nastavení kmitočtu snímků na hodnotu mezi 50 a 55 umožňuje vynechání snímků, ke kterému může občas
dojít.
V systému Windows vyžaduje používání přímého režimu rozhraní Microsoft DirectX 9 s 128 MB paměti VRAM a u
počítačů Apple Macintosh rozhraní OpenGL (v systému Mac OS X verze 10.2 nebo vyšší). Skládání GPU vyžaduje
v systému Windows podporu rozhraní Microsoft DirectX 9 a Pixel Shader 2.0 s 128 MB paměti VRAM. V systémech
Mac OS X a Linux vyžaduje skládání GPU rozhraní OpenGL 1.5 a několik rozšíření OpenGL (objekt framebuffer,
násobnou texturu, objekty clony, jazyk clonění, clonu fragmentu).
Režimy akcelerace direct a gpu můžete pro každý soubor SWF aktivovat jednotlivě pomocí dialogového okna
Nastavení publikování programu Flash (pomocí nabídky Hardwarová akcelerace na kartě Flash). Jestliže zvolíte možnost
Žádná, vrátí se režim okna na default, transparent nebo opaque, dle nastavení Režim okna na kartě HTML.
Zpracování událostí pro objekty zobrazení
Třída DisplayObject dědí z třídy EventDispatcher. To znamená, že každý objekt zobrazení se může plně účastnit v
modelu události (popsáno v části „Zpracování událostí“ na stránce 243). Každý objekt zobrazení může použít svou
metodu addEventListener() - získanou z třídy EventDispatcher - pro naslouchání určité události, ale pouze jestliže
je naslouchající objekt součástí toku událostí pro danou událost.
Když aplikace Flash Player nebo AIR odešle objekt události, daný objekt události dorazí k ploše a objektu zobrazení,
kde k události došlo, a zpět. Jestliže uživatel například klepne na objekt zobrazení pojmenovaný child1, přehrávač
Flash Player odešle objekt události z plochy hierarchií seznamu zobrazení směrem dolů až k objektu zobrazení child1.
Tok událostí je koncepčně rozdělen do tří fází, dle ukázky v tomto diagramu:
Vymezená plocha
Fáze
zachycení
Bublinová
fáze
Nadřazený uzel
Podřízený uzel1
Podřízený uzel2
Cílová fáze
Další informace viz „Zpracování událostí“ na stránce 243.
Jedním důležitým bodem, na který je třeba při práci s událostmi objektů zobrazení pamatovat, je vliv, který přijímače
události mohou být na to, zda jsou objekty zobrazení při odstranění ze seznamu zobrazení automaticky odstraněny z
paměti (do koše). Jestliže má objekt zobrazení objekty přihlášené ke svým událostem jako přijímače, daný objekt
zobrazení nebude odstraněn z paměti, i když je odstraněn se seznamu zobrazení, protože bude mít i nadále odkazy na
tyto objekty přijímače. Více informací naleznete v části „Správa posluchačů událostí“ na stránce 257.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 284
Programování zobrazení
Výběr podtřídy DisplayObject
S nabídkou několika možností, ze kterých si můžete vybrat, je jedním z nejdůležitějších rozhodnutí při práci s objekty
zobrazení to, který objekt zobrazení má být za kterým účelem použit. Zde je návod, který vám při rozhodování
pomůže. Stejné návrhy platí v případě, jestliže potřebujete instanci třídy, nebo vybíráte základní třídu pro třídu, kterou
vytváříte:
• Jestliže nepotřebujete objekt, který může být kontejnerem pro jiné objekty zobrazení (tzn. potřebujete pouze jeden,
který slouží jako samostatný prvek obrazovky), vyberte jednu z těchto podtříd DisplayObject nebo
InteractiveObject, v závislosti pro co bude daný objekt použit:
• Bitmapa pro zobrazení obrazu bitmapy.
• TextField pro přidání textu.
• Video pro zobrazení videa.
• Tvar pro plátno pro kreslení obsahu na obrazovce. Zvláště jestliže si přejete vytvořit instanci pro kreslení tvarů
na obrazovce a nebude se jednat o kontejner pro jiné objekty zobrazení, získáte použitím Shape místo Sprite
nebo MovieClip výrazný výkon.
• MorphShape, StaticText nebo SimpleButton pro položky vytvořené vývojovým nástrojem Flash. (Instance
těchto tříd nemůžete vytvořit programaticky, ale můžete vytvořit proměnné s těmito typy dat, které se vztahují
k položkám vytvořeným pomocí vývojového nástroje Flash.)
• Jestliže potřebujete proměnnou, která bude odkazovat na hlavní plochu, použijte třídu Stage a její typ dat.
• Jestliže potřebujete kontejner pro načtení externího souboru SWF nebo obrázkového souboru, použijte instanci
Loader. Načtený obsah bude přidán k seznamu zobrazení jako podřízený obsah instance Loader. Jeho typ dat bude
záviset na povaze načteného obsahu, a to následovně:
• Načtený snímek bude instancí bitmapy.
• Načtený soubor SWF zapsaný do jazyka ActionScript 3.0 bude instancí Sprite nebo MovieClip (nebo instancí
podtřídy těchto tříd, dle určení tvůrcem obsahu).
• Načtený soubor SWF zapsaný v jazyce ActionScript 1.0 nebo jazyce ActionScript 2.0 bude instancí
AVM1Movie.
• Jestliže potřebujete objekt, který bude sloužit jako kontejner pro jiné objekty zobrazení (zda budete také kreslit na
objekt zobrazení pomocí jazyka ActionScript či nikoliv), zvolte jednu z podtříd DisplayObjectContainer:
• Sprite jestliže objekt bude vytvořen pouze pomocí jazyka ActionScript, nebo jako základní třída pro vlastní
objekt zobrazení, který bude vytvořen a spravován pouze v jazyce ActionScript.
• MovieClip jestliže vytváříte proměnnou, která odkazuje na filmový klip vytvořený v nástroji pro vytváření Flash.
• Jestliže vytváříte třídu, které bude spojena se symbolem filmového klipu v knihovně Flash, zvolte jako základní
třídu vaší třídy jednu z těchto podtříd DisplayObjectContainer:
• MovieClip jestliže připojený symbol filmového klipu má obsah na více než jednom obrazu
• Sprite jestliže má připojený symbol pohyblivého klipu obsah pouze na prvním obrazu
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 285
Programování zobrazení
Manipulace s objekty zobrazení
Bez ohledu na to, který objekt zobrazení si zvolíte pro použití, existuje několik způsobů manipulace, které všechny
objekty zobrazení mají společné jako prvky zobrazené na obrazovce. Například mohou být všechny umístěny na
obrazovce, přesunuty dopředu nebo dozadu v pořadí umístění objektů zobrazení, může být změněno měřítko,
provedeno otočení, atd. Protože všechny objekty zobrazení dědí tuto funkci ze své společné základní třídy
(DisplayObject), tato funkce se chová stejně, ať už manipulujete s instancí TextField, instancí Video a instancí Shape,
nebo s jiným objektem zobrazení. Následující část podrobně popisuje některé z běžných manipulací objekty zobrazení.
Změna polohy
Základní manipulace s jakýmkoliv objektem zobrazení je jeho umístění na obrazovce. Pro nastavení polohy objektů
zobrazení změňte vlastnosti objektu x a y.
myShape.x = 17;
myShape.y = 212;
Systém pro polohování objektu zobrazení zachází s plochou jako s kartézským systémem souřadnic (běžný mřížkový
systém s horizontální osou x a vertikální osou y). Počátek systému souřadnic (souřadnice 0,0, kde se potkávají osy x a
y) je umístěn v horním levém rohu plochy. Z tohoto místa směřují kladné hodnoty x doprava a záporné hodnoty
doleva (v porovnání s typickým grafovým systémem), zatímco kladné hodnoty y směřují dolů a záporné nahoru.
Například předcházející řádky kódu přesouvají objekt myShape na x-souřadnici 17 (17 obrazových bodů doprava od
počátku) a na y-souřadnici 212 (212 obrazových bodů pod počátkem).
Dle výchozího nastavení, jestliže je objekt zobrazení vytvořen pomocí jazyka ActionScript, vlastnosti x a y jsou obě
nastaveny na hodnotu 0 a umísťují objekt do horního levého rohu svého nadřazeného obsahu.
Změna polohy relativní k ploše
Je důležité si zapamatovat, že vlastnosti x a y se vždy vztahují k poloze objektu zobrazení relativní k souřadnici 0,0
svého nadřazeného objektu zobrazení. Takže pro instanci Shape (například kruh) obsaženou uvnitř instance Sprite,
umístí nastavení vlastností xa y objektů Shape na 0 kruh v horním levém rohu Sprite, což nemusí nezbytně být horní
levý roh plochy. Pro umístění objektu relativně k celkovým souřadnicím plochy můžete použít metodu
globalToLocal() jakéhokoliv objektu zobrazení a převrátit souřadnice z globálních souřadnic (plocha) na místní
souřadnice (kontejnery objektů zobrazení), jako:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 286
Programování zobrazení
// Position the shape at the top-left corner of the Stage,
// regardless of where its parent is located.
// Create a Sprite, positioned at x:200 and y:200.
var mySprite:Sprite = new Sprite();
mySprite.x = 200;
mySprite.y = 200;
this.addChild(mySprite);
// Draw a dot at the Sprite's 0,0 coordinate, for reference.
mySprite.graphics.lineStyle(1, 0x000000);
mySprite.graphics.beginFill(0x000000);
mySprite.graphics.moveTo(0, 0);
mySprite.graphics.lineTo(1, 0);
mySprite.graphics.lineTo(1, 1);
mySprite.graphics.lineTo(0, 1);
mySprite.graphics.endFill();
// Create the circle Shape instance.
var circle:Shape = new Shape();
mySprite.addChild(circle);
// Draw a circle with radius 50 and center point at x:50, y:50 in the Shape.
circle.graphics.lineStyle(1, 0x000000);
circle.graphics.beginFill(0xff0000);
circle.graphics.drawCircle(50, 50, 50);
circle.graphics.endFill();
// Move the Shape so its top-left corner is at the Stage's 0, 0 coordinate.
var stagePoint:Point = new Point(0, 0);
var targetPoint:Point = mySprite.globalToLocal(stagePoint);
circle.x = targetPoint.x;
circle.y = targetPoint.y;
Můžete také použít metodu třídy DisplayObject localToGlobal() pro převedení místních souřadnic na souřadnice
plochy.
Vytváření interakce přetažení
Jedním běžným důvodem pro přesunutí objektu zobrazení je vytvoření interakce přetažení. Jestliže uživatel klepne na
objekt, objekt se bude přesouvat společně s pohybem myši, dokud neuvolníte tlačítko myši. Interakci přetažení lze
vytvořit v jazyce ActionScript dvěma způsoby. V obou případech se používají dvě události myši: při stisknutí tlačítka
myši bude objekt sledovat kurzor myši a při uvolnění tlačítka objekt přestane kurzor myši sledovat.
První způsob použití metody startDrag() je jednodušší, ale omezenější. Jestliže stisknete tlačítko myši, bude
vyvolána metoda startDrag() objektu zobrazení, který má být přetažen. Při uvolnění tlačítka myši je vyvolána
metoda stopDrag().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 287
Programování zobrazení
// This code creates a drag-and-drop interaction using the startDrag()
// technique.
// square is a DisplayObject (e.g. a MovieClip or Sprite instance).
import flash.events.MouseEvent;
// This function is called when the mouse button is pressed.
function startDragging(event:MouseEvent):void
{
square.startDrag();
}
// This function is called when the mouse button is released.
function stopDragging(event:MouseEvent):void
{
square.stopDrag();
}
square.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
square.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
Tato technika podléhá jednomu významného omezení: pomocí metody startDrag() lze přetáhnout pokaždé pouze
jednu položku. Jestliže je jeden objekt zobrazení přetažen a metoda startDrag() je vyvolána na jiném objektu
zobrazení, první objekt zobrazení okamžitě přestane sledovat myš. Například jestliže je funkce startDragging()
takto změněna, pouze objekt circle bude přetažen, a to i přes volání metody square.startDrag():
function startDragging(event:MouseEvent):void
{
square.startDrag();
circle.startDrag();
}
Následkem toho, že lze pomocí metody startDrag() pokaždé přetáhnout pouze jeden objekt, metoda stopDrag()
může být vyvolána na jakémkoliv objektu zobrazení a zastaví jakýkoliv objekt, který je aktuálně tažen.
Jestliže potřebujete přetáhnout více než jeden objekt zobrazení nebo zamezit možnosti konfliktů v případě, že jeden
nebo více objektů potenciálně používá metodu startDrag(), je nejlepší pro vytvoření efektu přetažení použít
techniku sledování myši. V případě této techniky je při stisknutí tlačítka myši události plochy mouseMove připsána
funkce jakou poslouchač. Tato funkce, které je poté vyvolána pokaždé s pohybem myši způsobuje, že tažený objekt
přeskočí na souřadnice x, y myši. Při uvolnění tlačítka myši je funkce odhlášena jako poslouchač a znamená to, že při
pohybu myši již není vyvolána a objekt přestane sledovat kurzor myši. Zde je kód, který demonstruje tuto techniku:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 288
Programování zobrazení
// This code creates a drag-and-drop interaction using the mouse-following
// technique.
// circle is a DisplayObject (e.g. a MovieClip or Sprite instance).
import flash.events.MouseEvent;
var offsetX:Number;
var offsetY:Number;
// This function is called when the mouse button is pressed.
function startDragging(event:MouseEvent):void
{
// Record the difference (offset) between where
// the cursor was when the mouse button was pressed and the x, y
// coordinate of the circle when the mouse button was pressed.
offsetX = event.stageX - circle.x;
offsetY = event.stageY - circle.y;
// tell Flash Player to start listening for the mouseMove event
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCircle);
}
// This function is called when the mouse button is released.
function stopDragging(event:MouseEvent):void
{
// Tell Flash Player to stop listening for the mouseMove event.
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragCircle);
}
// This function is called every time the mouse moves,
// as long as the mouse button is pressed down.
function dragCircle(event:MouseEvent):void
{
// Move the circle to the location of the cursor, maintaining
// the offset between the cursor's location and the
// location of the dragged object.
circle.x = event.stageX - offsetX;
circle.y = event.stageY - offsetY;
// Instruct Flash Player to refresh the screen after this event.
event.updateAfterEvent();
}
circle.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
circle.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
Vedle toho, kdy objekt zobrazení sleduje kurzor myši, zahrnuje běžná část interakce přetažení přesunutí taženého
objektu dopředu displeje, takže se bude jevit jako plovoucí nad všemi ostatními objekty. Předpokládejme například, že
máte dva objekty, kruh a čtverec, které mají interakci přetažení. Jestliže je kruh na seznamu zobrazení níže než čtverec,
na kruh klepnete a táhnete tak, že je kurzor nad čtvercem, bude kruh zdánlivě klouzat za čtvercem a iluze přetažení
bude porušena. Můžete také zvolit postup, kdy po klepnutí na kruh dojde k jeho přesunutí na první místo seznamu
zobrazení, a proto se vždy zobrazí navrch jakéhokoliv obsahu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 289
Programování zobrazení
Následující kód (přejatý z předchozího příkladu) vytvoří interakci přetažení pro dva objekty zobrazení, kruh a čtverec.
Kdykoliv stisknete tlačítko myši nad jedním z nich, daná položka je přesunuta na první místo v seznamu zobrazení
plochy, takže se přetažená položka vždy objeví nahoře. Kód, který je nový nebo se od předchozího uvedení změní, se
zobrazí tučně.
//
//
//
//
This code creates a drag-and-drop interaction using the mouse-following
technique.
circle and square are DisplayObjects (e.g. MovieClip or Sprite
instances).
import flash.display.DisplayObject;
import flash.events.MouseEvent;
var offsetX:Number;
var offsetY:Number;
var draggedObject:DisplayObject;
// This function is called when the mouse button is pressed.
function startDragging(event:MouseEvent):void
{
// remember which object is being dragged
draggedObject = DisplayObject(event.target);
// Record the difference (offset) between where the cursor was when
// the mouse button was pressed and the x, y coordinate of the
// dragged object when the mouse button was pressed.
offsetX = event.stageX - draggedObject.x;
offsetY = event.stageY - draggedObject.y;
// move the selected object to the top of the display list
stage.addChild(draggedObject);
// Tell Flash Player to start listening for the mouseMove event.
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragObject);
}
// This function is called when the mouse button is released.
function stopDragging(event:MouseEvent):void
{
// Tell Flash Player to stop listening for the mouseMove event.
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragObject);
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 290
Programování zobrazení
// This function is called every time the mouse moves,
// as long as the mouse button is pressed down.
function dragObject(event:MouseEvent):void
{
// Move the dragged object to the location of the cursor, maintaining
// the offset between the cursor's location and the location
// of the dragged object.
draggedObject.x = event.stageX - offsetX;
draggedObject.y = event.stageY - offsetY;
// Instruct Flash Player to refresh the screen after this event.
event.updateAfterEvent();
}
circle.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
circle.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
square.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
square.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
Chcete-li dále rozšířit tento efekt, například pro hru, kde jsou tokeny nebo karty přesouvány mezi hromádkami,
můžete přetažený objekt do seznamu zobrazení plochy přidat při jeho „vyzvednutí“ a poté jej přidat do jiného seznamu
zobrazení - například „hromádka“, kde je objekt umístěn - při uvolnění tlačítka myši.
Nakonec pro vylepšení efektu můžete klepnutím na objekt zobrazení použít filtr vrženého stínu (když jej začnete
přetahovat) a vržený stín odstranit při uvolnění objektu. Podrobnosti ohledně používání filtrů vrženého stínu a jiných
filtrů pro objekty zobrazení v jazyce ActionScript naleznete v části „Filtrování objektů zobrazení“ na stránce 346.
Stranový posun a posouvání objekty zobrazení
Máte-li objekt zobrazení, který je příliš veliký pro prostor, ve kterém jej chcete zobrazit, můžete použít vlastnost
scrollRect pro určení zobrazitelného prostoru objektu zobrazení. Dále změnou vlastnosti scrollRect v reakci na
vstup uživatele můžete způsobit vychýlení objektu vlevo a vpravo, nebo procházení nahoru či dolů.
Vlastnost scrollRect je instancí třídy Rectangle, která je třídou kombinující hodnoty potřebné k definování
obdélníkového prostoru jako jediného objektu. Pro první definování zobrazitelného prostoru objektu zobrazení
vytvořte novou instanci obdélníku a přiřaďte ji k vlastnosti objektu zobrazení scrollRect. Později pro procházení
nebo posouvání načtete vlastnost scrollRect do samostatné proměnné Rectangle a změníte požadovanou vlastnost
(například změníte vlastnost instance x pro posouvání nebo vlastnost y pro procházení). Poté znovu přiřadíte instanci
obdélníku vlastnosti scrollRect a uvědomíte tak objekt zobrazení o změněné hodnotě.
Následující kód například definuje zobrazitelnou oblast pro objekt TextField pojmenovaný bigText, který je příliš
vysoký, aby se vešel do ohraničení souboru SWF. Jestliže klepnete na dvě tlačítka pojmenovaná up a down, vyvolají
funkce, které způsobí, že se obsah objektu TextField posune nahoru nebo dolů upravením vlastnosti yinstance
scrollRect Rectangle.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 291
Programování zobrazení
import flash.events.MouseEvent;
import flash.geom.Rectangle;
// Define the initial viewable area of the TextField instance:
// left: 0, top: 0, width: TextField's width, height: 350 pixels.
bigText.scrollRect = new Rectangle(0, 0, bigText.width, 350);
// Cache the TextField as a bitmap to improve performance.
bigText.cacheAsBitmap = true;
// called when the "up" button is clicked
function scrollUp(event:MouseEvent):void
{
// Get access to the current scroll rectangle.
var rect:Rectangle = bigText.scrollRect;
// Decrease the y value of the rectangle by 20, effectively
// shifting the rectangle down by 20 pixels.
rect.y -= 20;
// Reassign the rectangle to the TextField to "apply" the change.
bigText.scrollRect = rect;
}
// called when the "down" button is clicked
function scrollDown(event:MouseEvent):void
{
// Get access to the current scroll rectangle.
var rect:Rectangle = bigText.scrollRect;
// Increase the y value of the rectangle by 20, effectively
// shifting the rectangle up by 20 pixels.
rect.y += 20;
// Reassign the rectangle to the TextField to "apply" the change.
bigText.scrollRect = rect;
}
up.addEventListener(MouseEvent.CLICK, scrollUp);
down.addEventListener(MouseEvent.CLICK, scrollDown);
Jak ukazuje tento příklad, při práci s vlastností objektu zobrazení scrollRect je nejlepší určit, že by aplikace Flash
Player nebo AIR měly uložit obsah objektu zobrazení do vyrovnávací paměti jako bitmapu, pomocí vlastnosti
cacheAsBitmap. Jestli to určíte, přehrávač Flash Player a AIR nemusí znovu nakreslit celý obsah objektu zobrazení
pokaždé při jeho procházení a mohou místo toho pro vykreslování nezbytné části přímo na obrazovku použít do
vyrovnávací paměti uloženou bitmapu. Podrobnosti naleznete v části „Ukládání objektů zobrazení do vyrovnávací
paměti“ na stránce 294.
Manipulace s velikostí a změna měřítka objektů
Provádět měření a manipulovat velikostí objektu zobrazení můžete dvěma způsoby, pomocí vlastností rozměrů
(width a height) nebo vlastností měřítka scaleX a scaleY).
Každý objekt zobrazení má vlastnost width a vlastnost height, které jsou zpočátku nastaveny na velikost objektů v
obrazových bodech. Hodnoty těchto vlastností můžete načíst a změřit tak velikost objektu zobrazení. Můžete také určit
nové hodnoty a změnit tak velikost objektu, a to následovně:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 292
Programování zobrazení
// Resize a display object.
square.width = 420;
square.height = 420;
// Determine the radius of a circle display object.
var radius:Number = circle.width / 2;
Změna height nebo width objektu zobrazení způsobí změnu měřítka objektu. Jeho obsah se smrští nebo roztáhne
tak, aby odpovídal nové oblasti. Jestliže objekt zobrazení obsahuje pouze vektorové tvary, tyto tvary budou překresleny
v novém měřítku, bez ztráty kvality. Pro jakékoliv grafické prvky bitmapy v objektu zobrazení bude změněno měřítko,
místo toho, aby byly překresleny. Například digitální fotografie, jejíž šířka a výška je zvětšena za aktuální rozměry
obrazového bodu v obrazu budou pixelovány a snímek bude vypadat zubatý.
Jestliže změníte vlastnosti width nebo height objektu zobrazení, aktualizují aplikace Flash Player a AIR také
vlastnostiscaleX a scaleY objektu.
Poznámka: Objekty TextField jsou výjimkou tohoto chování změny měřítka. Velikost textových polí je třeba změnit a
přizpůsobit tak zabalení textu a velikosti písma, aby po změně velikosti obnovila textové pole své hodnoty scaleX nebo
scaleY na 1. Nicméně pokud nastavíte hodnoty scaleX nebo scaleY objektu TextField, hodnoty šířky a výšky se změní tak,
aby se přizpůsobily zadaným hodnotám měřítka.
Tyto vlastnosti představují relativní velikost objektu zobrazení v porovnání s jeho původní velikostí. Vlastnosti scaleX
a scaleY používají zlomky (desetinné hodnoty) pro znázornění procenta. Jestliže byla například vlastnost width
objektu zobrazení změněna tak, že je ve vztahu ke své původní velikosti poloviční, velikost objektu scaleX bude mít
hodnotu .5, tzn. 50 procent. Jestliže byla výška zdvojnásobena, jeho vlastnost scaleY bude mít hodnotu 2, tzn. 200
procent.
// circle is a display object whose width and height are 150 pixels.
// At original size, scaleX and scaleY are 1 (100%).
trace(circle.scaleX); // output: 1
trace(circle.scaleY); // output: 1
// When you change the width and height properties,
// Flash Player changes the scaleX and scaleY properties accordingly.
circle.width = 100;
circle.height = 75;
trace(circle.scaleX); // output: 0.6622516556291391
trace(circle.scaleY); // output: 0.4966887417218543
Změny velikosti nejsou poměrné. Jinými slovy, jestliže změníte vlastnost čtverce height, ale nikoliv width, jeho
proporce již nebudou stejné a vnikne z něho obdélník místo čtverce. Jestliže si přejete provádět relativní změny
velikosti objektu zobrazení, můžete nastavit hodnoty vlastností scaleX a scaleY a změnit tak velikost objektu, jako
alternativu k nastavení vlastností width nebo height. Například tento kód změní vlastnost width objektu zobrazení
nazvaného square a poté změní vertikální měřítko scaleY) tak, aby odpovídalo horizontálnímu měřítku, a aby
velikost čtverce zůstala proporční.
// Change the width directly.
square.width = 150;
// Change the vertical scale to match the horizontal scale,
// to keep the size proportional.
square.scaleY = square.scaleX;
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 293
Programování zobrazení
Ovládání deformace během změny měřítka
Běžně je při změně měřítka objektu zobrazení (například horizontální protažení) následná deformace rovnoměrně
rozmístěna přes objekt, takže každá část je protažena o stejné množství. Tento postup je ideální pro grafické a
designové prvky. Nicméně někdy je lepší ovládat to, která část objektu zobrazení se protáhne, a která část zůstane
nezměněna. Běžným příkladem je tlačítko, které je obdélníkem se zaoblenými rohy. S běžnou změnou měřítka se rohy
tlačítka protáhnou a poloměr rohu se při změně velikosti tlačítka také změní.
Nicméně v tomto případě by bylo lepší ovládat změnu měřítka - mít možnost určit jisté oblasti, pro které by mělo být
změněno měřítko (rovné strany a střed) a oblasti, kde měřítko změněno být nemá (rohy) - takže bude změna měřítka
provedena bez viditelné deformace.
Můžete použít změnu měřítka s 9 řezy pro vytvoření objektů zobrazení tam, kde ovládáte změnu měřítka objektů. Se
změnou měřítka s 9 řezy je objekt zobrazení rozdělen do devíti samostatných obdélníků (do mřížky 3x3). Obdélníky
nemají nezbytně stejnou velikost - kterou určujete při umístění linií mřížky. Jakýkoliv obsah, který leží v obdélnících
se čtyřmi rohy (např. zaoblené rohy tlačítka) nebude při změně měřítka objektu zobrazení protažen nebo stlačen.
Obdélníky horního a dolního středu změní měřítko horizontálně, ale nikoliv vertikálně, zatímco obdélníky v levém a
pravém středu změní měřítko vertikálně, ale nikoliv horizontálně. Středový obdélník změní měřítko jak horizontálně,
tak vertikálně.
Pokud si při vytváření objektu zobrazení přejete, aby určitý objekt nikdy měřítko nezměnil, musíte se ujistit, zda jsou
dělicí čáry mřížky měřítka s 9 řezy umístěny tak, že obsah bude nakonec umístěn v jednom z rohových obdélníků.
V jazyce ActionScript se nastavení hodnoty pro vlastnost objektu zobrazení scale9Grid zapne pro daný objekt změnu
měřítka s 9 řezy a určí velikost obdélníků v mřížce změny měřítka objektu. Instanci třídy Rectangle použijete jako
hodnotu pro vlastnost scale9Grid následovně:
myButton.scale9Grid = new Rectangle(32, 27, 71, 64);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 294
Programování zobrazení
Čtyři parametry konstruktoru obdélníku jsou souřadnice x, y, šířka a výška. V tomto případě je horní levý roh
obdélníku na objektu zobrazení pojmenovaném myButton umístěn v bodě x: 32, y: 27. Obdélník je 71 obr. bodů široký
a 64 obr. bodů vysoký (takže je jeho pravá hrana na souřadnici x 103 na objektu zobrazení a jeho spodní hrana je na
souřadnici y 92 na objektu zobrazení).
Vlastní oblast obsažená v oblasti definované instancí Rectangle představuje středový obdélník mřížky. Ostatní obdélníky
jsou vypočítány přehrávačem Flash Player a AIR prodloužením velikostí instance Rectangle, jak je uvedeno zde:
V tomto případě se při zvětšení nebo zmenšení měřítka zaoblené rohy nenatáhnou nebo nestlačí, ale jiné oblasti budou
upraveny tak, aby se přizpůsobily změně měřítka.
A
B
C
A. myButton.width = 131;myButton.height = 106; B. myButton.width = 73;myButton.height = 69; C. myButton.width = 54;myButton.height
= 141;
Ukládání objektů zobrazení do vyrovnávací paměti
Když se velikost vašich návrhů v přehrávači Flash zvětšuje, ať už vytváříte aplikaci nebo složitou skriptovanou animaci,
musíte zohlednit výkon a optimalizaci. Jestliže máte obsah, který zůstává statický (například instance obdélníkového
tvaru), přehrávač Flash Player nebo aplikace AIR neoptimalizuje obsah. Proto při změně polohy obdélníku přehrávač
Flash Player nebo aplikace AIR překreslí celou instanci tvaru.
Do vyrovnávací paměti můžete uložit určité objekty zobrazení a vylepšit tak výkon vašeho souboru SWF. Objekt
zobrazení je povrch, v podstatě verze bitmapy vektorových dat instance, což jsou údaje, které nechcete ve svém souboru
SWF významně změnit. Proto instance se zapnutým ukládáním do vyrovnávací paměti nejsou při přehrávání souboru
SWF kontinuálně překresleny a umožňují tak rychlé vykreslování souboru SWF.
Poznámka: Můžete aktualizovat data vektoru, kdy dojde k opětovnému vytvoření povrchu. Proto vektorová data
uložená do vyrovnávací paměti na povrchu nemusí zůstat pro celý soubor SWF beze změn.
Nastavení vlastnosti cacheAsBitmap objektu zobrazení na hodnotu true (pravda) vyvolá uložení reprezentace
bitmapy objektu zobrazení do vyrovnávací paměti. Aplikace Flash Player nebo aplikace AIR vytvoří pro danou instanci
objekt povrchu, kterým je bitmapa uložená do mezipaměti, nikoliv vektorová data. Jestliže změníte ohraničení objektu
zobrazení, povrch bude znovu vytvořen a nebude pouze změněna jeho velikost. Povrchy se mohou vnořit do jiných
povrchů. podřízený povrch zkopíruje své bitmapy na svůj nadřazený povrch. Více informací naleznete v části
„Aktivace ukládání bitmapy do vyrovnávací paměti“ na stránce 296.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 295
Programování zobrazení
Vlastnost třídy DisplayObject opaqueBackground a vlastnost scrollRect se vztahují k uložení bitmapy do
vyrovnávací paměti pomocí vlastnosti cacheAsBitmap. Ačkoliv jsou tyto tři vlastnosti navzájem nezávislé, vlastnosti
opaqueBackground a scrollRect nejlépe fungují, když je objekt uložen do vyrovnávací paměti jako bitmapa výhody ve výkonu pro vlastnosti opaqueBackground a scrollRect uvidíte pouze tehdy, jestliže nastavíte
cacheAsBitmap na hodnotu true (pravda). Více informací o procházení obsahu objektu zobrazení naleznete v části
„Stranový posun a posouvání objekty zobrazení“ na stránce 290. Více informací o nastavení neprůhledného pozadí
naleznete v části „Nastavení neprůhledné barvy pozadí“ na stránce 296.
Informace ohledně maskování alfa kanálu, která vyžaduje nastavení vlastnosti cacheAsBitmap na hodnotu true
(pravda) naleznete v části „Maskování objektů zobrazení“ na stránce 301.
Kdy povolit ukládání do vyrovnávací paměti
Zapnutím ukládání do vyrovnávací paměti u objektu zobrazení se vytvoří povrch, který má několik výhod, například
pomáhá rychle vykreslovat složité vektorové animace. Existuje několik scénářů, ve kterých je třeba aktivovat ukládání
do vyrovnávací paměti. Může se zdát, že si ukládání do vyrovnávací paměti vždy budete přát aktivovat pro zlepšení
výkonu svých SWF souborů; nicméně existují situace, kdy aktivace ukládání do vyrovnávací paměti výkon nezlepší,
nebo jej dokonce zhorší. Tato část popisuje scénáře, ve který by mělo být ukládání do vyrovnávací paměti použito a ty,
kdy je třeba použít běžné objekty zobrazení.
Celkový výkon dat uložených do vyrovnávací paměti závisí na tom, jak složitá jsou vektorová data vašich instancí,
kolik dat měníte a zda jste nastavili vlastnost opaqueBackground. Pokud měníte malé oblasti, rozdíl mezi použitím
povrchu a použitím vektorových dat může být zanedbatelný. Před otevřením aplikace si můžete přát otestovat oba
scénáře při práci.
Kdy použít ukládání bitmap do vyrovnávací paměti
Následující příklady jsou typické scénáře, v nichž můžete vidět významné výhody zapnutí ukládání bitmap do
vyrovnávací paměti.
• Složitý obraz pozadí: Aplikace, která obsahuje detailní a složitý obraz pozadí s vektorovými daty (například obraz,
kde jste použili příkaz sledování bitmapy nebo kresba, kterou jste vytvořili v aplikaci Adobe Illustrator®). Můžete
animovat znaky přes pozadí, což animaci zpomalí, protože pozadí potřebuje neustále obnovovat vektorová data.
Pro vylepšení výkonu můžete nastavit vlastnost opaqueBackground pozadí objektu zobrazení na true (pravda).
Pozadí se rendruje jako bitmapa a je možné je rychle překreslit, takže se vaše animace přehrává rychleji.
• Rolovací textové pole: Aplikace, která zobrazuje velké množství textu v rolovacím textovém poli. Textové pole
můžete vložit do objektu zobrazení, který pomocí vazeb procházení nastavíte k procházení (vlastnost scrollRect).
To umožňuje rychlé procházení obrazovými body určené instance. Když uživatel roluje instanci objektu zobrazení,
přehrávač Flash Player nebo aplikace AIR přesune rolované obrazové body nahoru a generují nově odkrytou oblast
místo nového generování celého textového pole.
• Systém oken: Aplikace se složitým systémem překrývajících se oken. Každé okno může být otevřené nebo zavřené
(například okna webového prohlížeče). Pokud označíte každé okno jako povrch (nastavíte vlastnost
cacheAsBitmap na hodnotu true (pravda), každé okno je izolované a ukládá se do vyrovnávací paměti.
Uživatelé mohou přetahovat okna tak, aby se vzájemně překrývala a každé okno nemusí znovu generovat vektorový
obsah.
• Maskování alfa kanálu: Při používání maskování alfa kanálu musíte nastavit vlastnost cacheAsBitmap na hodnotu
true (pravda). Pro více informací viz „Maskování objektů zobrazení“ na stránce 301.
Aktivace ukládání bitmapy do vyrovnávací paměti ve všech těchto scénářích vylepšuje reakce a interakce aplikace
optimalizací vektorové grafiky.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 296
Programování zobrazení
Dále kdykoliv použijete filtr na objekt zobrazení, cacheAsBitmap je automaticky nastavena na možnost true
(pravda), i když ji výslovně nastavíte na false (nepravda). Jestliže z objektu zobrazení vymažete všechny filtry,
vlastnost cacheAsBitmap se vrátí na hodnotu, na kterou byla naposledy nastavena.
Kdy se vyvarovat ukládání bitmap do vyrovnávací paměti
Špatné použití této funkce by mohlo negativně ovlivnit váš soubor SWF. Jestliže používáte ukládání bitmapy do
vyrovnávací paměti, zapamatujte si následující návod:
• Nepoužívejte povrchy nadměrně (objekty zobrazení se zapnutým ukládáním do vyrovnávací paměti). Každý
povrch používá více paměti než běžný objekt zobrazení, což znamená, že povrchy byste měli aktivovat pouze tehdy,
když potřebujete vylepšit výkon vykreslování.
Bitmapa uložená do vyrovnávací paměti může zabírat podstatně více paměti než normální objekt zobrazení.
Například instance Sprite na ploše má velikost 250 obr. bodů x 250 obr. bodů, při ukládání do vyrovnávací paměti
může použít 250 KB místo 1 KB v případě běžné instance Sprite (neuloženou do vyrovnávací paměti).
• Vyvarujte se zvětšování do povrchů uložených do vyrovnávací paměti. Pokud se nadměrně používá ukládání
bitmap do vyrovnávací paměti, zabírá to velké množství paměti (viz předchozí bod), zejména pokud zvětšujete
obsah.
• Pro instance objektu zobrazení používejte povrchy, které jsou převážně statické (bez animace). Instanci můžete
přetahovat nebo přesouvat, ale obsah instance by se neměl příliš animovat nebo měnit. (Animace nebo změna
obsahu je pravděpodobnější s instancí MovieClip obsahující animaci nebo instanci Videa.) Pokud například
instanci otáčíte nebo transformujete, instance se mění mezi povrchem a vektorovými daty, což se obtížně
zpracovává a negativně to ovlivňuje soubor SWF.
• Pokud mísíte povrchy s vektorovými daty, zvyšuje se objem zpracování, které Flash Player a AIR (a někdy počítač)
musí provádět. Seskupujte povrchy co nejvíce je to možné - například při vytváření aplikací dělení obrazovky.
Aktivace ukládání bitmapy do vyrovnávací paměti
Pro zapnutí ukládání bitmap do vyrovnávací paměti nastavte její vlastnost cacheAsBitmap na hodnotu true
(pravda):
mySprite.cacheAsBitmap = true;
Po nastavení vlastnosti cacheAsBitmap na hodnotu true (pravda) si můžete všimnout, že se objekt zobrazení
automaticky roztáhne přes všechny souřadnice. Při testování souboru SWF byste měli zaznamenat, že se jakákoliv
animace na složitém vektorovém obrazu rendruje rychleji.
Povrch (bitmapa uložená do vyrovnávací paměti) není vytvořen, i když je cacheAsBitmap nastavena na hodnotu
true (pravda), dojde-li k následujícímu:
• Bitmapa je větší než 2880 obrazových bodů na výšku nebo na šířku.
• Nezdařilo se přiřazení bitových map (vznik chyby „nedostatek paměti“).
Nastavení neprůhledné barvy pozadí
Pro objekt zobrazení můžete nastavit neprůhledné pozadí. Například jestliže má váš soubor SWF pozadí, které
obsahuje složité vektory, můžete nastavit vlastnost opaqueBackground na určitou barvu (obvykle je to stejná barva
jako má plocha). Barva je určena jako číslo (běžně šestnáctková hodnota barvy). Pozadí je poté považováno za
bitmapu, což pomáhá optimalizovat výkon.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 297
Programování zobrazení
Nastavíte-li vlastnost cacheAsBitmap na hodnotu true (pravda), a vlastnost opaqueBackground na určitou barvu,
vlastnost opaqueBackground umožní neprůhlednost a rychlejší vykreslování interní bitmapy. Jestliže vlastnost
cacheAsBitmap nenastavíte na hodnotu true (pravda), vlastnost opaqueBackground přidá neprůhledný tvar s
čtvercovým vektorem k pozadí objektu zobrazení. Bitmapa nebude vytvořena automaticky.
Následující příklad ukazuje způsob nastavení pozadí objektu zobrazení na optimální výkon:
myShape.cacheAsBitmap = true;
myShape.opaqueBackground = 0xFF0000;
V tomto případě je barva pozadí tvaru pojmenovaná myShape nastavena na červenou (0xFF0000). Za předpokladu, že
instance Shape obsahuje kresbu zeleného trojúhelníku na ploše s bílým pozadím, zobrazí se jako zelený trojúhelník s
červenou barvou v prázdném prostoru ohraničujícího pole instance Shape (obdélník, který úplně obklopuje tvar).
Tento symbol by samozřejmě dával více smysl, pokud by byl použit na ploše s plným červeným pozadím. Na pozadí s
jinou barvou bude místo toho vybrána tato barva. Například v souboru SWF s bílým pozadím by byla vlastnost
opaqueBackground nejpravděpodobněji nastavena na 0xFFFFFF, nebo na čistě bílou.
Použití režimů prolnutí
Režimy prolnutí zahrnují kombinaci barev jednoho obrazu (základního obrazu) s barvami jiného obrazu (obraz
prolínání) pro vytvoření třetího obrazu - výsledný obraz je ten, který je skutečně zobrazen na obrazovce. Každá
hodnota obr. bodu v obrazu je zpracována s odpovídající hodnotou obr. bodu druhého obrazu pro vytvoření hodnoty
obr. bodu pro stejnou pozici ve výsledku.
Každý objekt zobrazení má vlastnost blendMode, kterou lze nastavit na jeden z následujících režimů prolnutí. Tyto
jsou konstanty určené ve třídě BlendMode. Můžete také použít hodnoty String (v kulatých závorkách), které jsou
skutečnými hodnotami těchto konstant.
•
BlendMode.ADD ("add"): Běžně se používá pro vytvoření efektu prolínání animovaného osvětlení mezi dvěma
obrazy.
•
BlendMode.ALPHA ("alpha"): Běžně se používá pro použití průhlednosti popředí na pozadí.
•
BlendMode.DARKEN ("darken"): Běžně se používá pro typ překrývání.
•
BlendMode.DIFFERENCE ("difference"): Běžně se používá pro vytvoření více kmitajících barev.
•
BlendMode.ERASE ("erase"): Běžně se používá pro vystřižení (vymazání) části pozadí pomocí popředí alfa.
•
BlendMode.HARDLIGHT ("hardlight"): Běžně se používá pro vytvoření efektu tónování.
•
BlendMode.INVERT ("invert"): Používá se pro obrácení pozadí.
•
BlendMode.LAYER ("layer"): Používá se k vytvoření přechodného uložení do vyrovnávací paměti pro
předsestavení určitého objektu zobrazení.
•
BlendMode.LIGHTEN ("lighten"): Používá se pro překrytý typ.
•
BlendMode.MULTIPLY ("multiply"): Běžně se používá pro vytvoření stínů a efektů hloubky.
•
BlendMode.NORMAL ("normal"): Používá se pro určení, že hodnoty obr. bodů obrazu prolínání potlačí hodnoty
výchozího obrazu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 298
Programování zobrazení
•
BlendMode.OVERLAY ("overlay"): Běžně se používá pro vytvoření efektu tónování.
•
BlendMode.SCREEN ("screen"): Běžně se používá pro vytvoření zvýraznění a přesvětlení čoček.
•
BlendMode.SHADER ("shader"): Používá se pro určení, zda je clona Pixel Bender používána pro vytvoření
vlastního efektu prolýnání. Více informací o používání clon naleznete v části „Práce s shadery Pixel Bender“ na
stránce 376.
•
BlendMode.SUBTRACT ("subtract"): Běžně se používá pro vytvoření animovaného efektu ztmavení mezi dvěma
obrazy.
Úprava barev DisplayObject
Pro nastavení barvy nebo zobrazení objektu můžete použít metody třídy ColorTransform
(flash.geom.ColorTransform). Každý objekt zobrazení má vlastnost transform, která je instancí třídy Transform a
obsahuje informace o různých transformacích, které se aplikují na objekty zobrazení (například otočení, změny
měřítka nebo polohy, atd.). Vedle této informace o geometrických transformacích zahrnuje třída transformace také
vlastnost colorTransform, která je instancí třídy ColorTransform a poskytuje přístup k provádění úprav barev
objektů zobrazení. Pro přístup k informaci o transformaci barvy objektu zobrazení můžete použít kód, například:
var colorInfo:ColorTransform = myDisplayObject.transform.colorTransform;
Po vytvoření instance ColorTransform můžete načíst hodnoty její vlastnosti a zjistíte tak, které transformace barev
byly již použity, nebo můžete tyto hodnoty nastavit tak, aby provedly změny barvy objektu zobrazení. Pro aktualizaci
objektu zobrazení po změnách musíte znovu přiřadit instanci ColorTransform zpět k vlastnosti
transform.colorTransform.
var colorInfo:ColorTransform = my DisplayObject.transform.colorTransform;
// Make some color transformations here.
// Commit the change.
myDisplayObject.transform.colorTransform = colorInfo;
Nastavení hodnot barvy pomocí kódu
Vlastnost color třídy ColorTransform lze použít pro přiřazení specifické hodnoty červené, zelené, modré (RGB)
barvy k objektu zobrazení. Následující příklady používají vlastnosti color pro změnu barvy objektu zobrazení
pojmenovaného jako square na modrou, jestliže uživatel klepne na tlačítko s názvem blueBtn:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 299
Programování zobrazení
// square is a display object on the Stage.
// blueBtn, redBtn, greenBtn, and blackBtn are buttons on the Stage.
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
// Get access to the ColorTransform instance associated with square.
var colorInfo:ColorTransform = square.transform.colorTransform;
// This function is called when blueBtn is clicked.
function makeBlue(event:MouseEvent):void
{
// Set the color of the ColorTransform object.
colorInfo.color = 0x003399;
// apply the change to the display object
square.transform.colorTransform = colorInfo;
}
blueBtn.addEventListener(MouseEvent.CLICK, makeBlue);
Upozorňujeme, že jestliže změníte barvu objektu zobrazení pomocí vlastnosti color, úplně změní barvu celého
objektu, bez ohledu na to, zda měl objekt dříve více barev. Jestliže například existuje objekt zobrazení obsahující zelený
kruh s černým textem navrchu, nastavením vlastnosti color k danému objektu asociované instance ColorTransform
na odstín červené změníte celý objekt, kruh a text na červenou barvu (takže text již nebude odlišitelný od zbytku
objektu).
Úprava efektů barvy a jasnosti pomocí kódu
Předpokládejme, že máte objekt zobrazení s více barvami (například digitální fotografie) a nechcete úplně změnit
barvu objektu; přejete si pouze upravit barvu objektu zobrazení na základě stávajících barev. V tomto scénáři zahrnuje
třída ColorTransform sérii násobitele a vlastnosti odsazení, které můžete použít k provedení tohoto typu úpravy.
Vlastnosti násobitele pojmenované redMultiplier, greenMultiplier, blueMultipliera alphaMultiplier
působí jako barevné fotografické filtry (nebo barevné sluneční brýle), které zvětšují nebo zmenšují určité barvy v
objektu zobrazení. Vlastnosti odsazení (redOffset, greenOffset, blueOffset a alphaOffset) lze použít pro
přidání dalšího množství určité barvy k objektu nebo pro učení minimální hodnoty, kterou určitá barva může mít.
Tyto vlastnosti násobitelů a odsazení jsou totožné s dalšími nastaveními barvy, které jsou k dispozici pro symboly
filmového klipu v nástroji vytváření přehrávače Flash, zvolíte-li z vyskakovací nabídky Barva v části Inspektor
vlastnosti položku Pokročilé.
Následující kód načte snímek ve formátu JPEG a použije na něj transformaci barvy, která přizpůsobí červené a zelené
kanály při pohybu ukazovátka myši podél os x a y. Vzhledem k tomu, že v tomto případě nejsou určeny žádné hodnoty
odsazení, bude hodnota barvy každého barevného kanálu zobrazeného na obrazovce procentem hodnoty původní
barvy v obrazu - znamená to, že většina červené nebo zelené barvy zobrazené v daném obrazovém bodu bude
původním množstvím červené nebo zelené barvy v daném obrazovém bodu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 300
Programování zobrazení
import
import
import
import
import
flash.display.Loader;
flash.events.MouseEvent;
flash.geom.Transform;
flash.geom.ColorTransform;
flash.net.URLRequest;
// Load an image onto the Stage.
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image1.jpg");
loader.load(url);
this.addChild(loader);
// This function is called when the mouse moves over the loaded image.
function adjustColor(event:MouseEvent):void
{
// Access the ColorTransform object for the Loader (containing the image)
var colorTransformer:ColorTransform = loader.transform.colorTransform;
// Set the red and green multipliers according to the mouse position.
// The red value ranges from 0% (no red) when the cursor is at the left
// to 100% red (normal image appearance) when the cursor is at the right.
// The same applies to the green channel, except it's controlled by the
// position of the mouse in the y axis.
colorTransformer.redMultiplier = (loader.mouseX / loader.width) * 1;
colorTransformer.greenMultiplier = (loader.mouseY / loader.height) * 1;
// Apply the changes to the display object.
loader.transform.colorTransform = colorTransformer;
}
loader.addEventListener(MouseEvent.MOUSE_MOVE, adjustColor);
Otáčení objektů
Objekty zobrazení lze otáčet pomocí vlastnosti rotation. Tuto hodnotu můžete načíst a zjistit tak, zda bylo objektem
otáčeno nebo pro otočení objektem můžete tuto vlastnost nastavit na číslo (ve stupních) představující otočení, které
bude na objekt použito. Například tento řádek kódu otočí objektem pojmenovaným square o 45 stupňů (o jednu
osminu celé otáčky):
square.rotation = 45;
Objektem zobrazení můžete také otáčet pomocí matrice transformace, popsané v části „Práce s geometrií“ na
stránce 334.
Vyblednutí objektů
Průhlednost objektu zobrazení můžete ovládat a změnit ji na částečnou (nebo úplnou průhlednost), nebo změnit
průhlednost a objekt se pak bude jevit jako postupně ztmavený nebo zesvětlený. Vlastnost třídy DisplayObject alpha
definuje průhlednost (nebo přesněji neprůhlednost) objektu zobrazení. Vlastnost alpha lze nastavit na jakoukoliv
hodnotu mezi 0 a 1, kde 0 znamená úplně průhledné a 1 je úplně neprůhledné. Například tyto řádky kódu změní objekt
pojmenovaný myBall na částečně (50 procent) průhledný, jestliže na něj klepnete myší:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 301
Programování zobrazení
function fadeBall(event:MouseEvent):void
{
myBall.alpha = .5;
}
myBall.addEventListener(MouseEvent.CLICK, fadeBall);
Průhlednost objektu zobrazení můžete také změnit pomocí úprav barvy dostupných skrze třídu ColorTransform. Více
informací naleznete v části „Úprava barev DisplayObject“ na stránce 298.
Maskování objektů zobrazení
Objekt zobrazení můžete použít jako masku a vytvořit tak otvor, skrze který je viditelný obsah jiného objektu
zobrazení.
Definování masky
Pro označení, že objekt zobrazení bude maskou pro jiný objekt zobrazení, nastavte objekt masky jako vlastnost mask
objektu zobrazení, který má být maskován:
// Make the object maskSprite be a mask for the object mySprite.
mySprite.mask = maskSprite;
Maskovaný objekt zobrazení je odhalen pod všemi neprůhlednými prostory objektu zobrazení, který se chová jako
maska. Například následující kód vytvoří instanci Shape obsahující červený čtverec o velikosti 100 x 100 obrazových
bodů a instanci Sprite obsahující modrý kruh s poloměrem 25 obrazových bodů. Jestliže klepnete na kruh, nastaví se
jako maska pro čtverec, takže jediná část čtverce, která je zobrazena, je část pokrytá plnou částí kruhu. Jinak řečeno,
viditelný bude pouze červený kruh.
// This code assumes it's being run within a display object container
// such as a MovieClip or Sprite instance.
import flash.display.Shape;
// Draw a square and add it to the display list.
var square:Shape = new Shape();
square.graphics.lineStyle(1, 0x000000);
square.graphics.beginFill(0xff0000);
square.graphics.drawRect(0, 0, 100, 100);
square.graphics.endFill();
this.addChild(square);
// Draw a circle and add it to the display list.
var circle:Sprite = new Sprite();
circle.graphics.lineStyle(1, 0x000000);
circle.graphics.beginFill(0x0000ff);
circle.graphics.drawCircle(25, 25, 25);
circle.graphics.endFill();
this.addChild(circle);
function maskSquare(event:MouseEvent):void
{
square.mask = circle;
circle.removeEventListener(MouseEvent.CLICK, maskSquare);
}
circle.addEventListener(MouseEvent.CLICK, maskSquare);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 302
Programování zobrazení
Objekt zobrazení, který se chová jako maska, lze přetáhnout, animovat, dynamicky změnit jeho velikost a lze používat
samostatné tvary v rámci jediné masky. Maskovací objekt zobrazení není třeba přidat na seznam zobrazení. Nicméně
pokud si přejete, aby se měřítko objektu masky změnilo se změnou měřítka plochy, nebo pokud si přejete umožnit
interakci uživatele s maskou (například uživatelem ovládané tažení a změna velikosti), musíte objekt masky přidat do
seznamu zobrazení. Skutečný z-index (pořadí zepředu dozadu) objektu zobrazení není podstatný, jestliže je objekt
zobrazení přidán do seznamu zobrazení. (Objekt masky se na obrazovce nezobrazí, s výjimkou funkce masky.) Jestliže
je objekt masky instancí s několika obrazy, přehraje všechny obrazy ve své časové ose, stejně jako kdyby nebyl nastaven
jako maska. Masku můžete odstranit nastavením vlastnosti mask na null:
// remove the mask from mySprite
mySprite.mask = null;
Nemůžete použít masku pro maskování jiné masky. Nemůžete nastavit vlastnost alpha maskovacího objektu
zobrazení. V objektu zobrazení, který je použit jako maska, jsou použity pouze výplně; tahy jsou ignorovány.
O maskování písma zařízení
Objekt zobrazení můžete použít pro maskování textu, který je nastaven v písmu zařízení. Jestliže používáte objekt
zobrazení pro maskování textu nastaveného v písmu zařízení, obdélníkový ohraničující rámeček masky se použije jako
maskovací tvar. To znamená, že pokud vytvoříte pro text s písmem zařízení masku objektu zobrazení jiného než
obdélníkového tvaru, pak maska, která se objeví v souboru SWF, převezme tvar obdélníkového ohraničovacího
rámečku masky, ne tvar samotné masky.
Maskování alfa kanálu
Maskování alfa kanálu je podporováno, jestliže maska i maskované objekty zobrazení používají ukládání bitmapy do
vyrovnávací paměti, jak je ukázáno níže:
// maskShape is a Shape instance which includes a gradient fill.
mySprite.cacheAsBitmap = true;
maskShape.cacheAsBitmap = true;
mySprite.mask = maskShape;
Například jednou aplikací maskování alfa kanálu je použít filtr na objekt masky nezávisle na filtru, který je použit na
maskovaný objekt zobrazení.
V následujícím příkladu je externí soubor obrazu načten do plochy. Daný obraz (nebo přesněji, instance Loader, do
které je načten) bude objektem zobrazení, který je maskován. Elipsa přechodu (plný černý střed měnící se na okrajích
v průhledný) je nakreslena přes snímek; toto bude maska alfa. Oba objekty zobrazení mají zapnuté ukládání bitmapy
do vyrovnávací paměti. Elipsa je nastavena jako maska pro snímek a poté ji lze přetáhnout.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 303
Programování zobrazení
// This code assumes it's being run within a display object container
// such as a MovieClip or Sprite instance.
import
import
import
import
import
flash.display.GradientType;
flash.display.Loader;
flash.display.Sprite;
flash.geom.Matrix;
flash.net.URLRequest;
// Load an image and add it to the display list.
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image1.jpg");
loader.load(url);
this.addChild(loader);
// Create a Sprite.
var oval:Sprite = new Sprite();
// Draw a gradient oval.
var colors:Array = [0x000000, 0x000000];
var alphas:Array = [1, 0];
var ratios:Array = [0, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(200, 100, 0, -100, -50);
oval.graphics.beginGradientFill(GradientType.RADIAL,
colors,
alphas,
ratios,
matrix);
oval.graphics.drawEllipse(-100, -50, 200, 100);
oval.graphics.endFill();
// add the Sprite to the display list
this.addChild(oval);
// Set cacheAsBitmap = true for both display objects.
loader.cacheAsBitmap = true;
oval.cacheAsBitmap = true;
// Set the oval as the mask for the loader (and its child, the loaded image)
loader.mask = oval;
// Make the oval draggable.
oval.startDrag(true);
Animace objektů
Animace je proces hýbaní nebo také vyvolávání změny. Skriptovaná animace je základní částí videoher a je často
používána pro přidání lesku a užitečných bodů interakce jiným aplikacím.
Základní myšlenkou skriptované animace je nutnost změny a to, že změna musí být rozdělena do postupných
přírůstků. V jazyce ActionScript snadno nastavíte opakování, a to prostřednictvím běžného příkazu smyčky. Nicméně
opakování proběhne všemi svými interakcemi před tím, než dojde k aktualizaci zobrazení. Pro vytvoření skriptované
animace potřebujete napsat ActionScript, který provede určitou akci opakovaně a také aktualizuje obrazovku při
každém jejím spuštění.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 304
Programování zobrazení
Představte si například, že si přejete vytvořit jednoduchou animaci, například cestu míče přes obrazovku. Jazyk
ActionScript zahrnuje jednoduchý mechanismus, který vám umožňuje vysledovat tok času a příslušně aktualizovat
obrazovku - to znamená, že můžete zadat kód, který pohybuje míčem pokaždé o malý kus, dokud nedosáhne cílového
místa. Po každém pohybu se aktualizuje obrazovka a pohyb přes plochu bude viditelný.
Z praktického hlediska je rozumné synchronizovat skriptovanou animaci s kmitočtem obrazů souboru SWF (jinými
slovy – nastavit změnu animace tak, aby proběhla pokaždé při zobrazení nového obrazu), protože definuje, jak často
aplikace Flash Player nebo AIR aktualizují obrazovku. Každý objekt zobrazení má událost enterFrame, která je
odeslána v souladu s kmitočtem obrazů souboru SWF - jedna událost na snímek. Většina vývojářů, kteří vytvářejí
skriptovanou animaci používají událost enterFrame jako způsob vytvoření akcí, které se opakují. Můžete napsat kód,
který naslouchá události enterFrame, pohybuje animovaným míčem o určitý kus s každým obrazem a při aktualizaci
obrazovky (každého obrazu) je míč znovu nakreslen v nové pozici a vytváří tak pohyb.
Poznámka: Dalším způsobem provedení opakované akce je použití třídy Timer. Instance Timer spustí oznámení o
události pokaždé, když uplyne určitá doba. Můžete napsat kód, který provede animaci manipulací s časovou událostí
třídy Timer a nastavením krátkého časového intervalu (zlomek vteřiny). Více informací o používání třídy Timer
naleznete v části „Kontrola časových intervalů“ na stránce 132.
V následujícím případě je na ploše vytvořena instance Sprite, pojmenovaná circle. Při klepnutí na kruh je zahájena
sekvence skriptované animace a circle vybledne (jeho vlastnost alpha se zmenší), dokud není zcela průhledný:
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
// draw a circle and add it to the display list
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x990000);
circle.graphics.drawCircle(50, 50, 50);
circle.graphics.endFill();
addChild(circle);
// When this animation starts, this function is called every frame.
// The change made by this function (updated to the screen every
// frame) is what causes the animation to occur.
function fadeCircle(event:Event):void
{
circle.alpha -= .05;
if (circle.alpha <= 0)
{
circle.removeEventListener(Event.ENTER_FRAME, fadeCircle);
}
}
function startAnimation(event:MouseEvent):void
{
circle.addEventListener(Event.ENTER_FRAME, fadeCircle);
}
circle.addEventListener(MouseEvent.CLICK, startAnimation);
Klepne-li uživatel na kruh, funkce fadeCircle() je připsána jako poslouchač události enterFrame, což znamená, že
bude vyvolána jednou na snímek. Tato funkce zesvětlí circle změnou jeho vlastnosti alpha, takže jednou za snímek
se hodnota kruhu alpha sníží o 0,05 (5 procent) a obrazovka se aktualizuje. Jestliže je hodnota alpha 0 (circle je
zcela průhledný), funkce fadeCircle() je odstraněna jako poslouchač události a ukončí tak animaci.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 305
Programování zobrazení
Stejný kód lze například použít pro vytvoření animovaného pohybu místo vyblednutí. Nahrazením jiné vlastnosti za
vlastnost alpha ve funkci, která je poslouchačem události enterFrame dojde k animaci dané vlastnosti. Například
změna tohoto řádku
circle.alpha -= .05;
na tento kód
circle.x += 5;
provede animaci vlastnosti xa kruh se tím přesune napravo od plochy. Podmínka, která ukončí animaci může být
změněna pro ukončení animace (tj. odepsání poslouchače enterFrame) v případě, že bylo dosaženo požadované
souřadnice x.
Dynamické načtení obsahu zobrazení
Jakýkoliv z následujících externích datových zdrojů zobrazení můžete načíst do jazyka ActionScript 3.0:
• Soubor SWF vytvořený v jazyce ActionScript 3.0 - Tento soubor může být třídou Sprite, MovieClip nebo jakoukoliv
třídou, která rozšiřuje třídu Sprite.
• Soubor s obrazem - zahrnuje soubory JPG, PNG a GIF.
• Soubor AVM1 SWF - jedná se o soubor SWF zapsaný v jazyce ActionScript 1.0 nebo 2.0.
Tyto datové zdroje můžete načíst pomocí třídy Loader.
Načtení objektů zobrazení
Objekty Loader jsou používány pro načtení souborů SWF a souborů grafiky do aplikace. Třída Loader je podtřídou
třídy DisplayObjectContainer. Objekt Loader může ve svém seznamu zobrazení obsahovat pouze jeden podřízený
objekt - objekt zobrazení reprezentující SWF nebo grafický soubor, který načítá. Přidáte-li objekt Loader k seznamu
zobrazení, jako v následujícím kódu, přidáváte také načtený podřízený objekt zobrazení k seznamu zobrazení, jakmile
se nahraje:
var pictLdr:Loader = new Loader();
var pictURL:String = "banana.jpg"
var pictURLReq:URLRequest = new URLRequest(pictURL);
pictLdr.load(pictURLReq);
this.addChild(pictLdr);
Jakmile je soubor SWF nebo snímek načten, můžete přesunout načtený objekt do jiné schránky objektu zobrazení,
jako je container objektu DisplayObjectContainer v tomto příkladě:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 306
Programování zobrazení
import flash.display.*;
import flash.net.URLRequest;
import flash.events.Event;
var container:Sprite = new Sprite();
addChild(container);
var pictLdr:Loader = new Loader();
var pictURL:String = "banana.jpg"
var pictURLReq:URLRequest = new URLRequest(pictURL);
pictLdr.load(pictURLReq);
pictLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);
function imgLoaded(event:Event):void
{
container.addChild(pictLdr.content);
}
Monitorování průběhu načítání
Jakmile začne nahrávání souboru, vytvoří se objekt LoaderInfo. Objekt LoaderInfo poskytuje informace jako postup
načítání, adresu URL načítajícího objektu a načítaného obsahu, celkový počet bytů média a jmenovitou výšku a šířku
média. Objekt LoaderInfo také odesílá události pro monitorování průběhu načítání.
Následující diagram ukazuje rozdílné použití objektu LoaderInfo - pro instanci hlavní třídy souboru SWF, pro objekt
Loader a pro objekt načtený objektem Loader:
Vymezená plocha
Objekt LoaderInfo
Vlastnost loaderInfo
Instance hlavní
třídy souboru
SWF
Objekt LoaderInfo
Vlastnost contentLoaderInfo
Objekt LoaderInfo
obsah
Vlastnost loaderInfo
Objekt LoaderInfo je dostupný jako vlastnost objektu Loader i vlastnost načteného objektu zobrazení. Jakmile začne
načítání, je objekt LoaderInfo dostupný prostřednictvím vlastnosti contentLoaderInfo objektu Loader. Jakmile
objekt zobrazení dokončil načítání, objekt LoaderInfo je dostupný jako vlastnost načteného objektu zobrazení
prostřednictvím vlastnosti objektu zobrazení loaderInfo. Vlastnost loaderInfo načteného objektu zobrazení se
vztahuje ke stejnému objektu LoaderInfo jako vlastnost contentLoaderInfo objektu Loader. Jinými slovy objekt
LoaderInfo je sdílen mezi souborem načteného objektu a objektem Loader, který jej načetl.
Pro přístup k vlastnostem načteného obsahu přidejte poslouchač události do objektu LoaderInfo, jako v následujícím
kódu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 307
Programování zobrazení
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
var ldr:Loader = new Loader();
var urlReq:URLRequest = new URLRequest("Circle.swf");
ldr.load(urlReq);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
addChild(ldr);
function loaded(event:Event):void
{
var content:Sprite = event.target.content;
content.scaleX = 2;
}
Další informace viz „Zpracování událostí“ na stránce 243.
Určení kontextu načítání
Při načítání externího souboru do přehrávače Flash Player nebo aplikace AIR pomocí metody load() nebo
loadBytes() třídy Loader, můžete také určit parametr context. Tento parametr je objektem LoaderContext.
Třída LoaderContext zahrnuje tři vlastnosti, které vám umožňují definovat kontext způsobu použití načteného
obsahu.
•
checkPolicyFile: Tuto vlastnost použijte pouze při načítání souboru obrazu (nikoliv souboru SWF). Jestliže tuto
vlastnost nastavíte na true, Loader vyhledá v původním serveru soubor zásad (viz „Ovládací prvky webového
místa (soubory zásad)“ na stránce 694). Toto je nezbytné pouze pro obsah pocházející z domén jiných než domén
souboru SWF, který obsahuje objekt Loader. Jestliže server udělí doméně Loader povolení, má jazyk ActionScript
ze souborů SWF v doméně Loader přístup k údajům v načteném obrazu; jinými slovy pro přístup k údajům v
načteném obrazu můžete použít příkaz BitmapData.draw().
Upozorňujeme, že soubor SWF z jiných domén, než z domén objektu Loader, může vyvolat
Security.allowDomain() pro povolení určité domény.
•
securityDomain: Tuto vlastnost používejte pouze při načítání souboru SWF (nikoliv obrazu). Určete ji pro soubor
SWF z domény jiné než domény souboru obsahujícího objekt Loader. Jestliže určíte tuto volbu, zkontroluje
přehrávač Flash Player existenci souboru postupů a jestliže existuje, soubory SWF z domén povolených v souboru
křížových postupů mohou skriptovat načtený obsah SWF. Jako tento parametr můžete určit
flash.system.SecurityDomain.currentDomain.
•
applicationDomain: Tuto vlastnost používejte pouze v případě, že načítáte soubor SWF napsaný v jazyku 3.0
(nikoliv obraz nebo soubor SWF napsaný v jazyce ActionScript 1.0 nebo ActionScript 2.0). Při načítání souboru
můžete stanovit, aby byl daný soubor zahrnut do stejné domény aplikace, jako je doména objektu Loader, a to
nastavením parametru applicationDomain na flash.system.ApplicationDomain.currentDomain. Umístění
načteného souboru SWF do stejné aplikační domény zajistí přímý přístup k jeho třídám. To může být užitečné v
případě, že načítáte soubor SWF, který obsahuje vložená média, ke kterým máte přístup pomocí názvů jejich
přidružených tříd. Více informací naleznete v části „Použití třídy ApplicationDomain“ na stránce 641.
Zde je příklad vyhledání souboru zásad při načítání bitmapy z jiné domény:
var context:LoaderContext = new LoaderContext();
context.checkPolicyFile = true;
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/photo11.jpg");
var ldr:Loader = new Loader();
ldr.load(urlReq, context);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 308
Programování zobrazení
Zde je příklad vyhledání souboru zásad při načítání souboru SWF z jiné domény, pro umístění souboru do stejné
bezpečnostní schránky jako v případě objektu Loader. Kód dále přidá třídy v načteném souboru SWF do stejné
domény aplikace, jako v případě objektu Loader:
var context:LoaderContext = new LoaderContext();
context.securityDomain = SecurityDomain.currentDomain;
context.applicationDomain = ApplicationDomain.currentDomain;
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/library.swf");
var ldr:Loader = new Loader();
ldr.load(urlReq, context);
Pro více informací viz popis třídy LoaderContext v Referenční příručce jazyka ActionScript 3.0 a jeho komponent.
Příklad: SpriteArranger
Vzorová aplikace SpriteArranger je založena na vzorové aplikaci geometrických tvarů, která je popsána zvlášť (viz
„Příklad: GeometricShapes“ na stránce 121).
Vzorová aplikace SpriteArranger uvádí několik konceptů pro práci s objekty zobrazení:
• Rozšíření tříd objektů zobrazení
• Přidávání objektů zobrazení k seznamu zobrazení
• Vrstvení objektů zobrazení a práce s kontejnery objektů zobrazení
• Odezvy na události objektů zobrazení
• Používání vlastností a metod objektů zobrazení
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace SpriteArranger naleznete ve složce Examples/SpriteArranger. Aplikace sestává z následujících
souborů:
Soubor
Popis
SpriteArranger.mxml
Hlavní soubor aplikace v programu Flash (FLA)
nebo Flex (MXML).
nebo
SpriteArranger.fla
com/example/programmingas3/SpriteArranger/CircleSprite.as
Třída definující typ objektu Sprite, který rendruje
kruh na obrazovce.
com/example/programmingas3/SpriteArranger/DrawingCanvas.as
Třída definující plátna, což je kontejner objektu
zobrazení, který obsahuje objekty
GeometricSprite.
com/example/programmingas3/SpriteArranger/SquareSprite.as
Třída definující typ objektu Sprite, který rendruje
čtverec na obrazovce.
com/example/programmingas3/SpriteArranger/TriangleSprite.as
Třída definující typ objektu Sprite, který rendruje
trojúhelník na obrazovce.
com/example/programmingas3/SpriteArranger/GeometricSprite.as
Třída, která rozšiřuje objekt Sprite, používaná pro
určení tvaru na obrazovce. CircleSprite,
SquareSprite a TriangleSprite rozšiřují tuto třídu.
com/example/programmingas3/geometricshapes/IGeometricShape.as
Metody definující základní rozhraní, které budou
použity všemi třídami geometrických tvarů.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 309
Programování zobrazení
Soubor
Popis
com/example/programmingas3/geometricshapes/IPolygon.as
Metody definující základní rozhraní, které budou
použity třídami geometrických tvarů, které mají
více stran.
com/example/programmingas3/geometricshapes/RegularPolygon.as
Typ geometrického tvaru, který má stejně dlouhé
strany, umístěné symetricky okolo středu tvaru.
com/example/programmingas3/geometricshapes/Circle.as
Typ geometrického tvaru, který definuje kruh.
com/example/programmingas3/geometricshapes/EquilateralTriangle.as
Podtřída RegularPolygon, která definuje
trojúhelník, jehož strany mají stejné délky.
com/example/programmingas3/geometricshapes/Square.as
Podtřída RegularPolygon definující obdélník, jehož
všechny strany jsou stejně dlouhé.
com/example/programmingas3/geometricshapes/GeometricShapeFactory.as
Třída obsahující „metodu závodu“ pro vytvoření
tvarů se stanoveným typem a velikostí.
Definice tříd SpriteArranger
Aplikace SpriteArranger umožňuje uživateli přidávat různé objekty zobrazení k „plátnům“ na obrazovce.
Třída DrawingCanvas definuje prostor pro kreslení, typ kontejneru objektů zobrazení, do kterého může uživatel
přidávat tvary na obrazovce. Tyto tvary na obrazovce jsou instancemi jedné z podtříd třídy GeometricSprite.
Třída DrawingCanvas
Třída DrawingCanvas rozšiřuje třídu Sprite a tato dědičnost je definována v popisu třídy DrawingCanvas následovně:
public class DrawingCanvas extends Sprite
Třída Sprite je podtřídou tříd DisplayObjectContainer a DisplayObject a třída DrawingCanvas používá metody a
vlastnosti těchto tříd.
Metoda konstruktoru DrawingCanvas() nastaví obdélníkový objekt bounds, což je vlastnost, která se později používá
v kreslení obrysu plátna. Poté vyvolá metodu initCanvas() následovně:
this.bounds = new Rectangle(0, 0, w, h);
initCanvas(fillColor, lineColor);
Jak ukazuje následující příklad, metoda initCanvas() definuje různé vlastnosti objektu DrawingCanvas, které byly
přidány jako argumenty k funkci konstruktoru:
this.lineColor = lineColor;
this.fillColor = fillColor;
this.width = 500;
this.height = 200;
Metoda initCanvas() poté vyvolá metodu drawBounds(), které nakreslí plátna pomocí vlastnosti graphics třídy
DrawingCanvas. Vlastnost graphics je zděděna ze třídy Shape.
this.graphics.clear();
this.graphics.lineStyle(1.0, this.lineColor, 1.0);
this.graphics.beginFill(this.fillColor, 1.0);
this.graphics.drawRect(bounds.left - 1,
bounds.top - 1,
bounds.width + 2,
bounds.height + 2);
this.graphics.endFill();
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 310
Programování zobrazení
Následující dodatečné metody třídy DrawingCanvas jsou vyvolány na základě interakcí uživatele a aplikace:
• Metody addShape() a describeChildren(), které jsou popsány v části „Přidávání objektů zobrazení k plátnům“
na stránce 310
• Metody moveToBack(), moveDown(), moveToFront() a moveUp(), které jsou popsány v části „Nové uspořádání
rozmístění objektů zobrazení“ na stránce 313
• Metoda onMouseUp(), která je popsána v části „Klepnutí na objekty zobrazení a jejich tažení“ na stránce 312
Třída GeometricSprite a její podtřídy
Každý objekt zobrazení, který uživatel může přidat do plátna, je instancí následujících podtříd třídy GeometricSprite:
• CircleSprite
• SquareSprite
• TriangleSprite
Třída GeometricSprite rozšiřuje třídu flash.display.Sprite:
public class GeometricSprite extends Sprite
Třída GeometricSprite zahrnuje několik vlastností, které jsou společné pro všechny objekty GeometricSprite. Tyto
vlastnosti jsou nastaveny ve funkci konstruktoru, na základě parametrů přiřazených dané funkci. Například:
this.size = size;
this.lineColor = lColor;
this.fillColor = fColor;
Vlastnost geometricShape třídy GeometricSprite definuje rozhraní IGeometricShape, které definuje matematické
vlastnosti, ale nikoliv vizuální vlastnosti tvaru. Třídy, které implementují rozhraní IGeometricShape jsou definovány
ve vzorové aplikaci GeometricShapes (viz. „Příklad: GeometricShapes“ na stránce 121).
Třída GeometricSprite definuje metodu drawShape(), která je dále znovu definována v potlačených definicích v
každé podtřídě GeometricSprite. Více informací naleznete v následující části „Přidávání objektů zobrazení k
plátnům“.
Třída GeometricSprite také nabízí následující metody:
• Metody onMouseDown() a onMouseUp(), které jsou popsány v části „Klepnutí na objekty zobrazení a jejich tažení“
na stránce 312
• Metody showSelected() a hideSelected(), které jsou popsány v části „Klepnutí na objekty zobrazení a jejich
tažení“ na stránce 312
Přidávání objektů zobrazení k plátnům
Jestliže uživatel klepne na tlačítko Přidat tvar, aplikace vyvolá metodu addShape() třídy DrawingCanvas. Tato metoda
zkonkretizuje novou třídu GeometricSprite vyvoláním příslušné funkce konstruktoru z jedné z podtříd
GeometricSprite, dle následujícího příkladu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 311
Programování zobrazení
public function addShape(shapeName:String, len:Number):void
{
var newShape:GeometricSprite;
switch (shapeName)
{
case "Triangle":
newShape = new TriangleSprite(len);
break;
case "Square":
newShape = new SquareSprite(len);
break;
case "Circle":
newShape = new CircleSprite(len);
break;
}
newShape.alpha = 0.8;
this.addChild(newShape);
}
Každá metoda konstruktoru vyvolá metodu drawShape(), která používá vlastnost graphics dané třídy (zděděnou ze
třídy Sprite) pro nakreslení příslušné vektorové grafiky. Například metoda drawShape() třídy CircleSprite obsahuje
následující kód:
this.graphics.clear();
this.graphics.lineStyle(1.0, this.lineColor, 1.0);
this.graphics.beginFill(this.fillColor, 1.0);
var radius:Number = this.size / 2;
this.graphics.drawCircle(radius, radius, radius);
Druhý až poslední řádek funkce addShape() nastaví hodnotu vlastnosti alpha objektu zobrazení (zděděnou z třídy
DisplayObject), takže každý objekt zobrazení přidaný do plátna je lehce průhledný a uživatel tak může vidět objekty
za ním.
Poslední řádek metody addChild() přidá nový objekt zobrazení na podřízený seznam instance třídy DrawingCanvas,
která je již na seznamu zobrazení. Tím se nový objekt zobrazení objeví na ploše.
Rozhraní pro aplikaci zahrnuje dvě textová pole, selectedSpriteTxt a outputTxt. Vlastnosti textu těchto dvou
textových polích jsou aktualizovány informací o objektech GeometricSprite, které byly přidány na plátno nebo zvoleny
uživatelem. Třída GeometricSprite zachází s touto úlohou hlášení informací potlačením metody toString(), a to
následovně:
public override function toString():String
{
return this.shapeType + " of size " + this.size + " at " + this.x + ", " + this.y;
}
Vlastnost shapeType je nastavena na příslušnou hodnotu v metodě konstruktoru každé podtřídy GeometricSprite.
Například metoda toString() může vrátit následující hodnotu pro instanci CircleSprite nedávno přidanou k instanci
DrawingCanvas:
Circle of size 50 at 0, 0
Metoda describeChildren() třídy DrawingCanvas se opakuje v podřízeném seznamu plátna a pomocí vlastnosti
numChildren (zděděné z třídy DisplayObjectContainer) nastaví limit opakování for cyklu. Vytvoří řetězec uvádějící
každý podřízený prvek, a to následovně:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 312
Programování zobrazení
var desc:String = "";
var child:DisplayObject;
for (var i:int=0; i < this.numChildren; i++)
{
child = this.getChildAt(i);
desc += i + ": " + child + '\n';
}
Výsledný řetězec se používá k nastavení vlastnosti text textového pole outputTxt.
Klepnutí na objekty zobrazení a jejich tažení
Když uživatel klepne na instanci GeometricSprite, aplikace vyvolá obsluhu události onMouseDown(). Jak je uvedeno
níže, tato obsluha události je nastavena na poslouchání událostí „myš dolů“ ve funkci konstruktoru třídy
GeometricSprite:
this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
Metoda onMouseDown() poté vyvolá metodu showSelected() objektu GeometricSprite. Jestliže byla v tomto případě
tato metoda pro objekt vyvolána poprvé, metoda vytvoří nový objekt Shape s názvem selectionIndicator a použije
jej jako vlastnost graphic objektu Shape pro nakreslení červeně zvýrazněného obdélníku, a to následovně:
this.selectionIndicator = new Shape();
this.selectionIndicator.graphics.lineStyle(1.0, 0xFF0000, 1.0);
this.selectionIndicator.graphics.drawRect(-1, -1, this.size + 1, this.size + 1);
this.addChild(this.selectionIndicator);
Jestliže se nejedná o první vyvolání metody onMouseDown(), metoda jednoduše nastaví vlastnost visibletvaru
selectionIndicator (zděděnou z třídy DisplayObject) následovně:
this.selectionIndicator.visible = true;
Metoda hideSelected() skryje tvar selectionIndicator předešle zvoleného objektu nastavením jeho vlastnosti
visible na hodnotu false (nepravda).
Metoda obsluhy události onMouseDown() také vyvolá metodu startDrag() (zděděnou ze třídy Sprite), která
obsahuje následující kód:
var boundsRect:Rectangle = this.parent.getRect(this.parent);
boundsRect.width -= this.size;
boundsRect.height -= this.size;
this.startDrag(false, boundsRect);
To umožní uživateli přetáhnout vybraný objekt kolem plátna, uvnitř hranic stanovených obdélníkem boundsRect.
Když uživatel uvolní tlačítko myši, událost mouseUp bude odeslána. Metoda konstruktoru DrawingCanvas nastaví
následující poslouchač události:
this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
Tento poslouchač události je nastaven pro objekt DrawingCanvas, spíše než pro jednotlivé objekty GeometricSprite.
Důvodem je to, že při tažení objektu GeometricSprite může být objekt při uvolnění myši umístěn za jiný objekt
zobrazení (jiný objekt GeometricSprite). Objekt zobrazení v popředí obdrží událost uvolnění myši, ale objekt
zobrazení tažený uživatelem nikoliv. Přidání poslouchače k objektu DrawingCanvas zajistí, že událost bude vždy
zpracována.
Metoda onMouseUp() vyvolá metodu onMouseUp() objektu GeometricSprite, která zase vyvolá metodu stopDrag()
objektu GeometricSprite.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 313
Programování zobrazení
Nové uspořádání rozmístění objektů zobrazení
Uživatelské rozhraní aplikace obsahuje tlačítka označená Pohyb zpět, Pohyb dolů, Pohyb nahoru a Pohyb vpřed.
Jestliže uživatel klepne na jedno z těchto tlačítek, aplikace vyvolá odpovídající metodu třídy DrawingCanvas:
moveToBack(), moveDown(), moveUp() nebo moveToFront(). Například metoda moveToBack() obsahuje
následující kód:
public function moveToBack(shape:GeometricSprite):void
{
var index:int = this.getChildIndex(shape);
if (index > 0)
{
this.setChildIndex(shape, 0);
}
}
Metoda používá metodu setChildIndex() (zděděnou ze třídy DisplayObjectContainer) pro umístění objektu
zobrazení na indexovou polohu 0 v podřízeném souboru instance DrawingCanvas (this).
Metoda moveDown() funguje podobně, s výjimkou, že snižuje indexovou pozici objektu zobrazení v podřízeném
seznamu instance DrawingCanvas o 1:
public function moveDown(shape:GeometricSprite):void
{
var index:int = this.getChildIndex(shape);
if (index > 0)
{
this.setChildIndex(shape, index - 1);
}
}
Metody moveUp() a moveToFront() pracují podobně jako metody moveToBack() a moveDown().
314
Kapitola 14: Používání kreslicího rozhraní
API
I když jsou importované obrazy a kresby důležité, funkce známé jako kreslicí rozhraní API, které umožňuje kreslit čáry
a tvary v jazyku ActionScript, poskytuje svobodu v možnosti zahájit aplikaci v počítačovém ekvivalentu čistého plátna,
na kterém můžete vytvořit jakýkoliv obraz. Schopnost vytvářet vlastní grafiku otevírá pro vaši aplikaci široké
možnosti. S technikami probranými v této kapitole můžete vytvořit kreslicí program, vytvářet animovanou,
interaktivní grafiku nebo programově vytvářet své vlastní elementy uživatelského rozhraní a jiné.
Základy použití kreslicího rozhraní API
Úvod k používání kreslicího rozhraní API
Kreslicí rozhraní API je název pro funkci zabudovanou do jazyka ActionScript, která vám umožňuje vyvářet
vektorovou grafiku—rovné čáry, křivky, tvary, výplň a přechody—a zobrazí je na obrazovce pomocí jazyka
ActionScript. Třída flash.display.Graphics tuto funkci poskytuje. S jazykem ActionScript můžete vykreslit jakoukoliv
instanci Shape, Sprite nebo MovieClip pomocí vlastnosti graphics definované v každé z těchto tříd. (Každá z
vlastností těchto tříd graphics je vlastně instancí třídy Graphics.)
Jestliže s kreslením svého kódu teprve začínáte, zahrnuje třída Graphics několik metod usnadňujících kreslení běžných
tvarů, např. kruhů, elips, obdélníků a obdélníků se zaoblenými rohy. Tyto tvary můžete kreslit jako prázdné čáry nebo
plné tvary. Jestliže potřebujete více pokročilé funkce, třída Graphics také zahrnuje metody pro kreslení čar a
kvadratických Bézierových křivek, které lze použít ve spojení s trigonometrickými funkcemi ve třídě Math pro
vytvoření jakýchkoliv tvarů.
Přehrávač Flash Player 10 a aplikace Adobe AIR 1.5 přidávají dodatečná rozhraní API pro kreslení, která vám
umožňují programaticky kreslit celé tvary pomocí jediného příkazu. Jakmile se seznámíte s třídou Graphics a úlohami
uvedenými v tématu „Základy používání kreslicích rozhraní API“, pokračujte s částí „Pokročilé použití kreslicího
rozhraní API“ na stránce 326 pro více informací o funkcích těchto kreslicích rozhraní API.
Běžné úlohy kreslicího rozhraní API
Následující úlohy budete pravděpodobně chtít provést pomocí kreslicích rozhraní API v jazyce ActionScript, která
jsou popsána v této kapitole:
• Definování stylů čar a výplní pro kreslení tvarů
• Kreslení rovných čar a křivek
• Používání metod pro kreslení tvarů, například kruhů, elips a obdélníků
• Kreslení čar s přechodem a výplní
• Definice matrice pro vytvoření přechodu
• Používání trigonometrie s kreslicími rozhraními API
• Začlenění kreslicího rozhraní API do animace
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 315
Používání kreslicího rozhraní API
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Kotevní bod: jeden ze dvou koncových bodů kvadratické Bézierovy křivky.
• Řídicí bod: bod definující směr a množství křivky kvadratické Bézierovy křivky. Zakřivená čára nikdy nedosáhne
řídicího bodu; čára se nicméně zakřiví, jako by byla tažena směrem k řídicímu bodu.
• Souřadnicový prostor: graf se souřadnicemi obsažený v objektu zobrazení, na který jsou umísťovány podřízené
elementy.
• Výplň: plná vnitřní část tvaru, která má čáru vyplněnou barvou nebo celý tvar bez obrysu.
• Přechod: barva složená z postupného přechodu z jedné barvy na jinou nebo více barev (oproti plné barvě).
• Bod: jednotlivé umístění v souřadnicovém prostoru. V soustavě souřadnic 2-d používané v jazyku ActionScript, je
bod definován svým umístěním podél osy x a osy y (souřadnicemi bodu).
• Kvadratická Bézierova křivka: typ křivky definované určitým matematickým vzorcem. U tohoto typu křivky je tvar
křivky vypočten na pozicích kotevních bodů (koncový bod dané křivky) a řídicího bodu, který definuje množství a
směr dané křivky.
• Měřítko: velikost určitého objektu vzhledem k jeho původní velikosti. Nastavení měřítka, resp. velikosti určitého
objektu znamená změnu jeho velikosti zvětšením, resp. zmenšením daného objektu.
• Tah: část obrysu tvaru, který má čáru vyplněnou barvou nebo čáry nevyplněného tvaru.
• Posunutí: změna souřadnic určitého bodu z jednoho souřadnicového prostoru na jiný.
• Osa x: vodorovná osa ve dvojrozměrné soustavě souřadnic používané v jazyku ActionScript.
• Osa y: svislá osa ve dvojrozměrné soustavě souřadnic používané v jazyku ActionScript.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Protože
se tato kapitola věnuje kreslení vizuálního obsahu, testování kódu zahrnuje spuštění kódu a zobrazení výsledků v
souboru SWF, který je vytvořen. Postup testování uvedených příkladů kódu:
1 Vytvořte prázdný dokument Flash.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
Výsledky kódu budou zobrazeny v souboru SWF, který je vytvořen.
Vysvětlení třídy Graphics
Každý objekt Shape, Sprite a MovieClip má vlastnost graphics, která je instancí třídy Graphics. Třída Graphics
zahrnuje vlastnosti a metody pro kreslení čar, výplní a tvarů. Chcete-li využívat objekt zobrazení pouze jako plátno pro
obsah kreslení, můžete použít instanci Shape. Instance Shape bude pro kreslení fungovat lépe než jiné objekty
zobrazení, protože nemá nadbytečné funkce ve třídách Sprite a MovieClip. Chcete-li objekt zobrazení, na který můžete
kreslit grafický obsah a současně chcete, aby tento objekt obsahoval jiné objekty zobrazení, můžete použít instanci
Sprite. Další informace k rozhodnutí, jaký objekt zobrazení použít pro různé úlohy, viz „Výběr podtřídy
DisplayObject“ na stránce 284.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 316
Používání kreslicího rozhraní API
Kreslení čar a křivek
Všechny kresby prováděné s instancí Graphics jsou založeny na základním kreslení čar a křivek. V důsledku toho musí
být všechny kresby v jazyku ActionScript prováděny podle stejného postupu:
• Definování stylů čáry a výplně
• Nastavení počáteční polohy kresby
• Kreslení čar, křivek a tvarů (volitelně přesouvání kreslicího bodu)
• Zakončení vytvořením výplně v případě potřeby
Definování stylů čáry a výplně
Chcete-li kreslit pomocí vlastnosti graphics, instance Shape, Sprite nebo MovieClip, musíte nejprve definovat styl
(velikost a barvu čáry, barvu výplně), který se při kreslení použije. Stejně jako při použití kreslicích nástrojů v aplikaci
Adobe® Flash® CS4 Professional nebo jiné kreslicí aplikaci můžete při použití jazyka ActionScript kreslit s tahem nebo
bez a s barvou výplně nebo bez. Vzhled tahu určíte pomocí metody lineStyle() nebo lineGradientStyle().
Chcete-li vytvořit plnou čáru, použijte metodu lineStyle(). Při volání této metody budete nejčastěji zadávat první
tři parametry: tloušťku čáry, barvu a hodnotu alfa. Například tento řádek kódu sdělí instanci Shape s názvem myShape,
aby kreslila čáry 2 obr. body tlusté, červené (0x990000) a ze 75 % průhledné:
myShape.graphics.lineStyle(2, 0x990000, .75);
Výchozí hodnota parametru alfa je 1,0 (100 %), takže chcete-li, aby byla čára zcela neprůhledná, můžete tento parametr
nechat vypnutý. Metoda lineStyle() přijímá také dva další parametry pro hintování obr. bodů a režim měřítka.
Další informace o používání těchto parametrů najdete v popisu metody Graphics.lineStyle() v Referenční
příručce jazyka ActionScript 3.0 a jeho součástí.
Chcete-li vytvořit čáru přechodu, použijte metodu lineGradientStyle(). Tato metoda je popsána v části „Vytváření
čar a výplní přechodu“ na stránce 319.
Chcete-li vytvořit vyplněný tvar, vyvolejte před započetím kreslení metodu beginFill(), beginGradientFill(),
beginBitmapFill() nebo beginShaderFill(). Nejzákladnější metoda z nich, beginFill(), přijímá dva
parametry: barvu výplně a (volitelně) hodnotu alfa pro barvu výplně. Chcete-li například nakreslit tvar s plnou zelenou
výplní, měli byste použít následující kód (za předpokladu, že kreslíte na objekt s názvem myShape):
myShape.graphics.beginFill(0x00FF00);
Vyvolání jakékoli metody výplně implicitně ukončí případnou předchozí výplň, než se začne vytvářet nová. Volání
libovolné metody, která určuje styl tahu, nahradí předchozí tah, ale nezmění dříve určenou výplň a naopak.
Jakmile jste určili styl čáry a vlastnosti výplně, další krok je určit počáteční bod kresby. Instance Graphics má kreslicí
bod, jako hrot pera na kousku papíru. Příští akce kreslení začne právě v místě umístění kreslicího bodu. Na začátku
začne objekt Graphics s kreslicím bodem v bodě 0, 0 v souřadnicovém prostoru objektu, na který kreslíte. Chcete-li
začít kreslit v jiném bodě, můžete před vyvoláním některé z kreslicích metod vyvolat nejprve metodu moveTo(). To je
stejné jako zvednutí hrotu pera z papíru a přesunutí na novou pozici.
S kreslicím bodem na místě kreslíte pomocí série volání kreslicích metod lineTo() (pro kreslení rovných čar) a
curveTo() (pro kreslení zakřivených čar).
Během kreslení můžete kdykoli vyvolat metodu moveTo() pro přesunutí kreslicího bodu na novou pozici bez kreslení.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 317
Používání kreslicího rozhraní API
Jestliže jste určili barvu výplně, můžete během kreslení sdělit aplikaci Flash Player nebo Adobe® AIR™, aby vyvoláním
metody endfill() ukončila výplň. Jestliže jste nenakreslili uzavřený tvar (jinými slovy, jestliže v době, kdy voláte
metodu endFill(), není kreslicí bod v počátečním bodu tvaru), když voláte metodu endFill(), aplikace Flash Player
nebo AIR automaticky uzavře tvar nakreslením rovné čáry od aktuálního kreslicího bodu k místu určenému při
posledním volání metody moveTo(). Jestliže jste zahájili výplň a nevyvolali jste metodu endFill(), uzavře volání
metody beginFill() (nebo některé z ostatních metod výplně) aktuální výplň a zahájí novou.
Kreslení rovných čar
Když vyvoláte metodu lineTo(), objekt Graphics nakreslí rovnou čáru od aktuálního kreslicího bodu po souřadnice,
které určíte jako dva parametry při volání metody, přičemž použije styl čáry, který jste určili. Například následující
řádek kódu nastaví kreslicí bod do bodu 100, 100 a poté nakreslí čáru do bodu 200, 200:
myShape.graphics.moveTo(100, 100);
myShape.graphics.lineTo(200, 200);
V následujícím příkladu se nakreslí červené a zelené trojúhelníky o výšce 100 obr. bodů:
var triangleHeight:uint = 100;
var triangle:Shape = new Shape();
// red triangle, starting at point 0, 0
triangle.graphics.beginFill(0xFF0000);
triangle.graphics.moveTo(triangleHeight / 2, 0);
triangle.graphics.lineTo(triangleHeight, triangleHeight);
triangle.graphics.lineTo(0, triangleHeight);
triangle.graphics.lineTo(triangleHeight / 2, 0);
// green triangle, starting at point 200, 0
triangle.graphics.beginFill(0x00FF00);
triangle.graphics.moveTo(200 + triangleHeight / 2, 0);
triangle.graphics.lineTo(200 + triangleHeight, triangleHeight);
triangle.graphics.lineTo(200, triangleHeight);
triangle.graphics.lineTo(200 + triangleHeight / 2, 0);
this.addChild(triangle);
Kreslení křivek
Metoda curveTo() nakreslí kvadratickou Beziérovu křivku. Tento kód nakreslí oblouk, který spojuje dva body
(nazývané kotvící body), přičemž se bude ohýbat směrem ke třetímu bodu (nazývanému ovládací bod). Objekt
Graphics použije jako první kotvící bod aktuální kreslicí pozici. Při volání metody curveTo() předáváte čtyři
parametry: souřadnice x a y ovládacího bodu, následované souřadnicemi x a y druhého kotvícího bodu. Například
následující kód nakreslí křivku začínající v bodě 100, 100 a končící v bodě 200, 200. Protože ovládací bod je v bodě 175,
125, vytvoří se křivka, která je nakloněná doprava a potom směrem dolů:
myShape.graphics.moveTo(100, 100);
myShape.graphics.curveTo(175, 125, 200, 200);
V následujícím příkladu se nakreslí červené a zelené kružnice o šířce a výšce 100 obr. bodů. Všimněte si, že kvůli
povaze kvadratické Bézierovy rovnice to nejsou dokonalé kružnice:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 318
Používání kreslicího rozhraní API
var size:uint = 100;
var roundObject:Shape = new Shape();
// red circular shape
roundObject.graphics.beginFill(0xFF0000);
roundObject.graphics.moveTo(size / 2, 0);
roundObject.graphics.curveTo(size, 0, size, size / 2);
roundObject.graphics.curveTo(size, size, size / 2, size);
roundObject.graphics.curveTo(0, size, 0, size / 2);
roundObject.graphics.curveTo(0, 0, size / 2, 0);
// green circular shape
roundObject.graphics.beginFill(0x00FF00);
roundObject.graphics.moveTo(200 + size / 2, 0);
roundObject.graphics.curveTo(200 + size, 0, 200 + size, size / 2);
roundObject.graphics.curveTo(200 + size, size, 200 + size / 2, size);
roundObject.graphics.curveTo(200, size, 200, size / 2);
roundObject.graphics.curveTo(200, 0, 200 + size / 2, 0);
this.addChild(roundObject);
Kreslení tvarů pomocí vestavěných metod
Pro pohodlné kreslení obecných tvarů, jako kruhů, elips, obdélníků a obdélníků se zaoblenými rohy jsou v jazyku
ActionScript 3.0 metody, které tyto běžné tvary nakreslí za vás. Jsou to metody drawCircle(), drawEllipse(),
drawRect(), drawRoundRect() a drawRoundRectComplex() z třídy Graphics. Tyto metody můžete použít místo
metod lineTo() a curveTo(). Všimněte si však, že i přesto musíte před voláním těchto metod určit styl čáry a výplně.
V následujícím příkladu jsou znovu vytvořeny červené, zelené a modré čtverce o šířce a výšce 100 obr. bodů. Tento
kód použije metodu drawRect() a navíc určí, že barva výplně bude mít hodnotu alfa 50 % (0,5):
var squareSize:uint = 100;
var square:Shape = new Shape();
square.graphics.beginFill(0xFF0000, 0.5);
square.graphics.drawRect(0, 0, squareSize, squareSize);
square.graphics.beginFill(0x00FF00, 0.5);
square.graphics.drawRect(200, 0, squareSize, squareSize);
square.graphics.beginFill(0x0000FF, 0.5);
square.graphics.drawRect(400, 0, squareSize, squareSize);
square.graphics.endFill();
this.addChild(square);
V objektu Sprite nebo MovieClip se obsah kreslení vytvořený pomocí vlastnosti graphics vždy objeví za všemi
podřízenými objekty zobrazení, které daný objekt obsahuje. Obsah vlastnosti graphics také není nezávislý objekt
zobrazení, takže se neobjevuje v seznamu potomků objektu Sprite nebo MovieClip. Například následující objekt Sprite
má kruh nakreslený pomocí své vlastnosti graphics a ve svém seznamu podřízených objektů zobrazení má objekt
TextField:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 319
Používání kreslicího rozhraní API
var mySprite:Sprite = new Sprite();
mySprite.graphics.beginFill(0xFFCC00);
mySprite.graphics.drawCircle(30, 30, 30);
var label:TextField = new TextField();
label.width = 200;
label.text = "They call me mellow yellow...";
label.x = 20;
label.y = 20;
mySprite.addChild(label);
this.addChild(mySprite);
Všimněte si, že objekt TextField se objeví nad kruhem nakresleným pomocí objektu grafiky.
Vytváření čar a výplní přechodu
Grafický objekt může kreslit také tahy a výplně s přechody místo plných barev. Tah přechodu vytvoříte pomocí metody
lineGradientStyle() a výplň přechodu pomocí metody beginGradientFill().
Obě metody přijímají stejné parametry. První čtyři parametry jsou vyžadované: typ, barvy, hodnoty alfa a poměry.
Zbývající čtyři jsou volitelné, ale užitečné pro pokročilé přizpůsobení.
• První parametr určuje typ přechodu, který chcete vytvořit. Přijatelné hodnoty jsou GradientFill.LINEAR nebo
GradientFill.RADIAL.
• Druhý parametr určuje pole hodnot barev, které budou použity. U lineárního přechodu budou barvy uspořádány
zleva doprava. U radiálního přechodu budou uspořádány zevnitř ven. Pořadí barev pole představuje pořadí, ve
kterém budou barvy v přechodu malovány.
• Třetí parametr určuje hodnoty průhlednosti alfa odpovídajících barev v předchozím parametru.
• Čtvrtý parametr určuje poměry neboli zvýraznění jednotlivých barev v rámci přechodu. Přípustné hodnoty jsou v
rozsahu od 0 do 255. Tyto hodnoty nepředstavují šířku ani výšku, ale polohu v rámci přechodu: 0 představuje
počátek přechodu, 255 představuje konec přechodu. Pole poměrů musí narůstat spojitě a musí mít stejný počet
zadání jako pole barev i hodnot alfa určená ve druhém a třetím parametru.
I když pátý parametr, matice transformace, je volitelný, je často používaný, protože poskytuje snadný a účinný způsob
ovládání vzhledu přechodu. Tento parametr přijímá instanci Matrix. Nejjednodušší způsob vytvoření objektu Matrix
pro přechod je použít metodu createGradientBox() třídy Matrix.
Definování objektu Matrix pro použití s přechodem
Metody beginGradientFill() a lineGradientStyle() z třídy flash.display.Graphics slouží k definování přechodů
pro použití u tvarů. Když definujete přechod, dodáte matici jako jeden z parametrů těchto metod.
Nejjednodušší způsob definování matice je pomocí metody createGradientBox() třídy Matrix, která vytvoří matici
používanou k definování přechodu. Pomocí parametrů předaných metodě createGradientBox() definujete
měřítko, natočení a polohu přechodu. Metoda createGradientBox() přijímá následující parametry:
• Šířka pole přechodu: šířka (v obr. bodech), přes kterou bude přechod roztažen
• Výška pole přechodu: výška (v obr. bodech), přes kterou bude přechod roztažen
• Natočení pole přechodu: natočení (v radiánech), které bude aplikováno na přechod
• Vodorovný posun: jak rychle (v obr. bodech) bude přechod vodorovně posouván
• Svislý posun: jak rychle (v obr. bodech) bude přechod svisle posouván
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 320
Používání kreslicího rozhraní API
Například uvažujte přechod s následujícími charakteristickými rysy:
•
GradientType.LINEAR
• Dvě barvy, zelená a modrá s polem ratios nastaveným na [0,
•
SpreadMethod.PAD
•
InterpolationMethod.LINEAR_RGB
255]
Následující příklady ukazují přechody, u kterých se parametr rotation metody createGradientBox() liší, jak je
naznačeno, ale všechna ostatní nastavení zůstávají stejná:
width = 100;
height = 100;
rotation = 0;
tx = 0;
ty = 0;
width = 100;
height = 100;
rotation = Math.PI/4; // 45°
tx = 0;
ty = 0;
width = 100;
height = 100;
rotation = Math.PI/2; // 90°
tx = 0;
ty = 0;
Příklady: zobrazit efekt lineárního přechodu ze zelené na modrou, kde se rotation, tx a ty parametry z metody
createGradientBox() liší jak je uvedeno, ale všechna ostatní nastavení zůstávají stejná:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 321
Používání kreslicího rozhraní API
width = 50;
height = 100;
rotation = 0;
tx = 0;
ty = 0;
width = 50;
height = 100;
rotation = 0
tx = 50;
ty = 0;
width = 100;
height = 50;
rotation = Math.PI/2; // 90°
tx = 0;
ty = 0;
width = 100;
height = 50;
rotation = Math.PI/2; // 90°
tx = 0;
ty = 50;
Parametry width, height, tx a ty metody createGradientBox() ovlivňují také velikost a polohu radiální výplně
přechodu, jak ukazuje následující příklad:
width = 50;
height = 100;
rotation = 0;
tx = 25;
ty = 0;
Následující kód vytvoří poslední znázorněný radiální přechod:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 322
Používání kreslicího rozhraní API
import flash.display.Shape;
import flash.display.GradientType;
import flash.geom.Matrix;
var
var
var
var
var
var
var
type:String = GradientType.RADIAL;
colors:Array = [0x00FF00, 0x000088];
alphas:Array = [1, 1];
ratios:Array = [0, 255];
spreadMethod:String = SpreadMethod.PAD;
interp:String = InterpolationMethod.LINEAR_RGB;
focalPtRatio:Number = 0;
var matrix:Matrix = new Matrix();
var boxWidth:Number = 50;
var boxHeight:Number = 100;
var boxRotation:Number = Math.PI/2; // 90°
var tx:Number = 25;
var ty:Number = 0;
matrix.createGradientBox(boxWidth, boxHeight, boxRotation, tx, ty);
var square:Shape = new Shape;
square.graphics.beginGradientFill(type,
colors,
alphas,
ratios,
matrix,
spreadMethod,
interp,
focalPtRatio);
square.graphics.drawRect(0, 0, 100, 100);
addChild(square);
Všimněte si, že šířka a výška výplně přechodu je určena šířkou a výškou matice přechodu a ne šířkou a výškou, která
je nakreslena pomocí objektu Graphics. Při kreslení pomocí objektu Graphics nakreslíte to, co existuje na daných
souřadnicích v matici přechodu. I když použijete jednu z metod tvaru objektu Graphics, např. drawRect(), přechod
se neroztáhne na velikost nakresleného tvaru–velikost přechodu musí být určena v samotné matici přechodu.
Následuje znázornění vizuálního rozdílu mezi rozměry matice přechodu a rozměry samotné kresby:
var myShape:Shape = new Shape();
var gradientBoxMatrix:Matrix = new Matrix();
gradientBoxMatrix.createGradientBox(100, 40, 0, 0, 0);
myShape.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x00FF00, 0x0000FF], [1,
1, 1], [0, 128, 255], gradientBoxMatrix);
myShape.graphics.drawRect(0, 0, 50, 40);
myShape.graphics.drawRect(0, 50, 100, 40);
myShape.graphics.drawRect(0, 100, 150, 40);
myShape.graphics.endFill();
this.addChild(myShape);
Tento kód nakreslí přechody se stejným stylem výplně, určené stejným rozložením červené, zelené a modré. Přechody
se nakreslí pomocí metody drawRect() s šířkami 50, 100, resp. 150 obr. bodů. Matice přechodu, která je určena v
metodě beginGradientFill(), je vytvořena s šířkou 100 obr. bodů. To znamená, že první přechod obsáhne pouze
polovinu spektra přechodu, druhý obsáhne celé a třetí obsáhne celé spektrum a dalších 50 obr. bodů modré s přesahem
doprava.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 323
Používání kreslicího rozhraní API
Metoda lineGradientStyle() funguje podobně jako metoda beginGradientFill() s tím rozdílem, že kromě
definování přechodu musíte před kreslením určit i tloušťku tahu pomocí metody lineStyle(). Následující kód
nakreslí čtverec s červeným, zeleným a modrým tahem přechodu:
var myShape:Shape = new Shape();
var gradientBoxMatrix:Matrix = new Matrix();
gradientBoxMatrix.createGradientBox(200, 40, 0, 0, 0);
myShape.graphics.lineStyle(5, 0);
myShape.graphics.lineGradientStyle(GradientType.LINEAR, [0xFF0000, 0x00FF00, 0x0000FF], [1,
1, 1], [0, 128, 255], gradientBoxMatrix);
myShape.graphics.drawRect(0, 0, 200, 40);
this.addChild(myShape);
Další informace o třídě Matrix najdete v části „Používání objektů Matrix“ na stránce 340.
Použití třídy Math s kreslicími metodami
Objekt Graphics kreslí kružnice a čtverce, ale může kreslit i složitější tvary, zvláště při použití kreslicích metod v
kombinaci s vlastnostmi a metodami třídy Math. Třída Math obsahuje běžné matematické konstanty, např. Math.PI
(cca 3,14159265...), konstantu pro poměr obvodu kruhu k jeho průměru. Obsahuje takém metody pro trigonometrické
funkce, včetně Math.sin(), Math.cos() a Math.tan() aj. Kreslení tvarů pomocí těchto metod a konstant vytváří
dynamičtější vizuální efekty, zvláště při použití s opakováním nebo rekurzí.
Mnohé metody třídy Math očekávají kruhové míry v radiánech a ne ve stupních. Převody mezi těmito dvěma typy
jednotek patří k běžným využitím třídy Math:
var degrees = 121;
var radians = degrees * Math.PI / 180;
trace(radians) // 2.111848394913139
V následujícím příkladu je vytvořena sinusová vlna a kosinusová vlna pro zvýraznění rozdílu mezi metodami
Math.sin() a Math.cos() při dané hodnotě.
var
var
var
var
var
var
sinWavePosition = 100;
cosWavePosition = 200;
sinWaveColor:uint = 0xFF0000;
cosWaveColor:uint = 0x00FF00;
waveMultiplier:Number = 10;
waveStretcher:Number = 5;
var i:uint;
for(i = 1; i < stage.stageWidth; i++)
{
var sinPosY:Number = Math.sin(i / waveStretcher) * waveMultiplier;
var cosPosY:Number = Math.cos(i / waveStretcher) * waveMultiplier;
graphics.beginFill(sinWaveColor);
graphics.drawRect(i, sinWavePosition + sinPosY, 2, 2);
graphics.beginFill(cosWaveColor);
graphics.drawRect(i, cosWavePosition + cosPosY, 2, 2);
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 324
Používání kreslicího rozhraní API
Animování s kreslicím rozhraním API
Jednou z výhod vytváření obsahu pomocí kreslicího rozhraní API je, že nejste omezeni jedním nastavením pozice
obsahu. To, co nakreslíte, můžete změnit údržbou a úpravou proměnných, které používáte při kreslení. Animaci
můžete vést změnou proměnných a překreslením, buď v určitém intervalu snímků nebo pomocí časovače.
Například následující kód změní zobrazení s každým snímkem (posloucháním události Event.ENTER_FRAME),
přičemž zvýší aktuální počet stupňů a předá grafickému objektu instrukci, aby se vymazal a překreslil s aktualizovanou
polohou.
stage.frameRate = 31;
var currentDegrees:Number = 0;
var radius:Number = 40;
var satelliteRadius:Number = 6;
var container:Sprite = new Sprite();
container.x = stage.stageWidth / 2;
container.y = stage.stageHeight / 2;
addChild(container);
var satellite:Shape = new Shape();
container.addChild(satellite);
addEventListener(Event.ENTER_FRAME, doEveryFrame);
function doEveryFrame(event:Event):void
{
currentDegrees += 4;
var radians:Number = getRadians(currentDegrees);
var posX:Number = Math.sin(radians) * radius;
var posY:Number = Math.cos(radians) * radius;
satellite.graphics.clear();
satellite.graphics.beginFill(0);
satellite.graphics.drawCircle(posX, posY, satelliteRadius);
}
function getRadians(degrees:Number):Number
{
return degrees * Math.PI / 180;
}
Chcete-li dostat značně odlišný výsledek, můžete experimentovat se změnou počátečních proměnných na začátku
kódu, currentDegrees, radius a satelliteRadius. Zkuste například zmenšit proměnnou radius, popř. zvýšit
proměnnou totalSatellites. Toto je pouze jeden příklad toho, jak může kreslicí rozhraní API vytvářet vizuální
zobrazení, jehož složitost zakrývá jednoduchost jeho tvorby.
Příklad: Algoritmický vizuální generátor
Příklad algoritmického vizuálního generátoru dynamicky nakreslí do vymezené plochy několik „satelitů“, neboli
kružnic pohybujících se po kruhové oběžné dráze. Mezi zkoumané vlastnosti patří:
• Použití kreslicího rozhraní API ke kreslení základních tvarů s dynamickým vzhledem
• Spojení interakce s uživatelem s vlastnostmi používanými při kreslení
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 325
Používání kreslicího rozhraní API
• Vedení animace vymazáním a překreslením vymezené plochy při každém snímku
V příkladu v předchozí podsekci byl animován jediný „satelit“ pomocí události Event.ENTER_FRAME. Tento příklad
je toho rozšířením, kdy je vytvořen ovládací panel s řadou posuvníků, které okamžitě aktualizují vizuální zobrazení
několika satelitů. V tomto příkladu se kód formalizuje do externích tříd a kód pro vytvoření satelitu se zalomí do
smyčky, přičemž se odkazy na jednotlivé satelity uloží do pole satellites.
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Aplikační soubory najdete ve složce Samples/AlgorithmicVisualGenerator. Tato složka obsahuje následující soubory:
Soubor
Popis
AlgorithmicVisualGenerator.fla
Hlavní aplikační soubor v programu Flash (FLA).
com/example/programmingas3/algorithmic/AlgorithmicVisualGenerator.as
Třída, která poskytuje hlavní funkce aplikace, včetně
kreslení satelitů do vymezené plochy a reagování na
události z ovládacího panelu za účelem aktualizace
proměnných, které ovlivňují kreslení satelitů.
com/example/programmingas3/algorithmic/ControlPanel.as
Třída, která spravuje interakci s uživatelem, s několika
posuvníky a odesíláním událostí při jejich výskytu.
com/example/programmingas3/algorithmic/Satellite.as
Třída, která představuje objekt zobrazení, který se otáčí
po oběžné dráze kolem středu a obsahuje vlastnosti
týkající se jeho aktuálního stavu kreslení.
Nastavení posluchačů
Aplikace vytvoří nejprve tři posluchače. První poslouchá událost odeslanou z ovládacího panelu oznamující nutnost
nového vytvoření satelitů. Druhý poslouchá změny velikosti vymezené plochy souboru SWF. Třetí poslouchá
přecházení jednotlivých snímků v souboru SWF za účelem překreslení pomocí funkce doEveryFrame().
Vytvoření satelitů
Jakmile jsou zmíněné posluchače nastaveny, bude vyvolána funkce build(). Tato funkce nejprve vyvolá funkci
clear(), která vyprázdní pole satellites a vymaže všechny dosavadní kresby ve vymezené ploše. To je nutné,
protože funkce build() by mohla být znovu vyvolána vždy, když ovládací panel pošle nějakou událost, např. když
dojde ke změně nastavení barev. V takovém případě je třeba satelity odstranit a vytvořit znovu.
Daná funkce pak vytvoří satelity, přičemž nastaví počáteční vlastnosti potřebné pro vytvoření, např. proměnnou
position, která začíná na náhodné pozici na oběžné dráze, a proměnnou color, která se v tomto příkladu po
vytvoření satelitu nemění.
Jakmile je každý satelit vytvořen, do pole satellites je na něj přidán odkaz. Jakmile bude vyvolána funkce
doEveryFrame(), aktualizuje se na všechny satelity v tomto poli.
Aktualizace polohy satelitu
Funkce doEveryFrame() je jádrem animačního procesu aplikace. Je vyvolávána pro každý snímek, rychlostí rovnající
se rychlosti snímků souboru SWF. Protože proměnné kreslení se mírně liší, určuje to vzhled animace.
Uvedená funkce nejprve vymaže všechny dosavadní kresby a znovu nakreslí pozadí. Dále bude cyklicky procházet
kontejner každého satelitu a zvyšovat jeho vlastnost position a aktualizuje vlastnosti radius a orbitRadius, které
se mohly díky interakci uživatele s ovládacím panelem změnit. Nakonec satelit aktualizuje vyvoláním metody draw()
třídy Satellite na svou novou polohu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 326
Používání kreslicího rozhraní API
Všimněte si, že počitadlo i se zvyšuje pouze do hodnoty proměnné visibleSatellites. To je z toho důvodu, že
kdyby uživatel prostřednictvím ovládacího panelu omezil množství zobrazených satelitů, zbývající satelity ve smyčce
by se neměly překreslovat, ale měly by být skryté. To se vyskytuje ve smyčce, která následuje ihned po smyčce
odpovědné za kreslení.
Jakmile je funkce doEveryFrame() dokončena, počet viditelných satelitů, visibleSatellites, na obrazovce se
aktualizuje.
Reagování na interakci s uživatelem
Interakce s uživatelem je realizována prostřednictvím ovládacího panelu, který je spravován třídou ControlPanel. Tato
třída nastaví posluchač spolu s individuálním minimem, maximem a výchozími hodnotami jednotlivých posuvníků.
Když uživatel těmito posuvníky pohne, vyvolá se funkce changeSetting(). Tato funkce aktualizuje vlastnosti
ovládacího panelu. Jestliže změna vyžaduje nové vytvoření zobrazení, je odeslána událost, která je následně zpracována
v hlavním aplikačním souboru. Po změně nastavení ovládacího panelu nakreslí funkce doEveryFrame() jednotlivé
satelity s aktualizovanými proměnnými.
Další přizpůsobení
Tento příklad je pouze základním schématem způsobu generování vizuálních objektů pomocí kreslicího rozhraní API.
Pomocí relativně pár řádků kódu je v něm vytvořen interaktivní zážitek, který vypadá poměrně složitě. Přesto by tento
kód mohl být s menšími změnami rozšířen. Pár nápadů:
• Funkce doEveryFrame() by mohla zvyšovat hodnotu barvy satelitu.
• Funkce doEveryFrame() by mohla zmenšovat nebo zvětšovat poloměr satelitu v závislosti na času.
• Poloměr satelitu nemusí být kruhový. Mohl by se měnit pomocí třídy Math např. na sinusovou vlnu.
• Satelity by mohly reagovat na dotyk s jinými satelity.
Kreslicí rozhraní API je možno použít jako alternativu pro vytváření vizuálních efektů ve vývojovém prostředí Flash
ke kreslení základních tvarů při běhu. Může však také sloužit k vytváření vizuálních efektů takové rozmanitosti a
rozsahu, jakých při ručním kreslení nelze dosáhnout. Pomocí kreslicího rozhraní API a trochy matematiky může autor
kódu ActionScript zplodit mnoho neočekávaných výtvorů.
Pokročilé použití kreslicího rozhraní API
Úvod k používání pokročilého kreslicího rozhraní API
Verze Flash Player 10 a Adobe AIR 1.5 zavádí podporu pokročilé sady kreslících funkcí. Vylepšení kreslícího rozhraní
API rozšiřují kreslicí metody z předchozích verzí, takže můžete zavést množiny dat pro vygenerování tvarů, měnit
tvary za běhu i vytvářet trojrozměrné efekty. Vylepšení kreslícího rozhraní API slučují stávající metody do
alternativních příkazů. Tyto příkazy využívají vektorová pole a třídy výčtu k poskytování množin dat pro metody
kreslení. Používání vektorových polí vám umožňuje rychlejší vykreslování složitějších tvarů a vývojáři tak mohou
programaticky změnit hodnoty pole pro vykreslování dynamického tvaru v době běhu.
Funkce kreslení zavedené v přehrávači Flash Player 10 jsou popsány v následujících tématech: „Cesty kreslení“ na
stránce 327, „Definování pravidel vinutí“ na stránce 329, „Používání tříd grafických dat“ na stránce 330, a „O použití
metody drawTriangles()“ na stránce 333.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 327
Používání kreslicího rozhraní API
Běžné úlohy pokročilého kreslicího rozhraní API
Následující úlohy jsou věci, které budete pravděpodobně chtít pomocí pokročilých kreslicích rozhraní API v jazyce
ActionScript zrealizovat:
• Použití vektorových objektů k ukládání dat pro metody kreslení
• Definování cest pro programatické kreslení tvarů
• Pravidla vinutí pro určení výplně překrývajících se tvarů
• Používání tříd grafických dat
• Použití trojúhelníků a metod kreslení pro 3D efekty
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této části:
• Vektor: pole hodnot se stejným datovým typem. Objekt Vector může uchovávat pole hodnot, které metody kreslení
používají ke konstrukci čar a tvarů pomocí jediného příkazu. Více informací o objektech Vector naleznete v tématu
„Indexovaná pole“ na stránce 154.
• Cesta: cesta je tvořena jedním nebo více přímými nebo zakřivenými segmenty. Začátek a konec každého segmentu
jsou označeny souřadnicemi, které fungují jako špendlíky, držící na místě drát. Cesta může být buď uzavřená
(například kružnice), nebo otevřená, to znamená se zřetelnými koncovými body (například vlnovka).
• Vinutí: směr cesty dle interpretace autora, buď kladný (po směru hodinových ručiček) nebo záporný (proti směru
hodinových ručiček).
• GraphicsStroke: třída pro nastavení stylu čáry. I když termín „tah“ (anglicky „stroke“) není součástí vylepšení
kreslícího rozhraní API, použití třídy určené k navržení stylu čáru s vlastní vlastností výplně je součástí tohoto
vylepšení. Styl čáry můžete dynamicky upravit pomocí třídy GraphicsStroke.
• Objekt výplně: objekty vytvořené pomocí tříd zobrazení, např. flash.display.GraphicsBitmapFill a
flash.display.GraphicsGradientFill, které jsou předány kreslicímu příkazu Graphics.drawGraphicsData().
Objekty výplně a vylepšené příkazy kreslení zavádějí programovací přístup více orientovaný na objekt pro replikaci
Graphics.beginBitmapFill() a Graphics.beginGradientFill().
Cesty kreslení
Část o kreslení čar a křivek (viz „Kreslení čar a křivek“ na stránce 316) uvedla příkazy k vytvoření tvaru kreslením
jediné čáry (Graphics.lineTo()) nebo křivky (Graphics.curveTo()) a následným přesunutím čáry do jiného bodu
(Graphics.moveTo()). Přehrávač Flash Player 10 a aplikace Adobe AIR 1.5 zavádí podporu pro vylepšení kreslicího
rozhraní API jazyka ActionScript, např. Graphics.drawPath()a Graphics.drawTriangles(), která využívají
stávající kreslicí příkazy a parametry. Série příkazů Graphics.lineTo(), Graphics.curveTo() nebo
Graphics.moveTo() jsou tak spuštěny v jediném příkazu.
Dvě z těchto vylepšení kreslicího rozhraní API umožňují slučovat stávající příkazy pomocí metod
Graphics.drawPath() a Graphics.drawTriangles():
• Třída výčtu GraphicsPathCommand: třída GraphicsPathCommand spojí několik kreslicích příkazů s konstantními
hodnotami. Série těchto hodnot můžete použít jako parametry pro metodu Graphics.drawPath(). Poté můžete
pomocí jediného příkazu vykreslit celý tvar nebo několik tvarů. Můžete také dynamicky změnit hodnoty předané
k těmto metodám a změnit tak již existující tvar.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 328
Používání kreslicího rozhraní API
• Vektorová pole: vektorová pole obsahují hodnoty specifického datového typu. Proto ukládáte sérii konstant
GraphicsPathCommand do objektu Vector a sérii souřadnic do jiného objektu Vector. Graphics.drawPath()
nebo Graphics.drawTriangles() přiřadí tyto hodnoty společně a vytvoří cestu kreslení nebo tvar.
Již nepotřebujete oddělené příkazy pro každý segment tvaru. Například metoda Graphics.drawPath() sloučí
Graphics.moveTo(), Graphics.lineTo() a Graphics.curveTo() do jediné metody. Namísto toho, aby byly
metody volány samostatně, jsou abstraktně vytvořeny do numerických identifikátorů, dle definice ve třídě
GraphicsPathCommand. Operace moveTo() je označena 1, zatímco operace lineTo() je označena 2. Pole těchto
hodnot uložte do objektu Vector.<int> a použijte jej v parametru commands. Poté vytvořte další pole obsahující
souřadnice v objektu Vector.<Number> pro parametr data. Každá hodnota GraphicsPathCommand odpovídá
hodnotám souřadnic uložených v datovém parametru, kde dvě po sobě jdoucí čísla definují umístění v cílovém
prostoru souřadnic.
Poznámka: Hodnoty ve vektoru nejsou objekty Point; vektor je řada čísel, kde každá skupina dvou čísel představuje
dvojici souřadnic x/y.
Metoda Graphics.drawPath() přiřadí ke každému příkazu jeho příslušné hodnoty bodů (soubor dvou nebo čtyř
čísel) pro vytvoření cesty v objektu Graphics:
package{
import flash.display.*;
public class DrawPathExample extends Sprite {
public function DrawPathExample(){
var square_commands:Vector.<int> = new Vector.<int>(5,true);
square_commands[0] = 1;//moveTo
square_commands[1] = 2;//lineTo
square_commands[2] = 2;
square_commands[3] = 2;
square_commands[4] = 2;
var square_coord:Vector.<Number> = new Vector.<Number>(10,true);
square_coord[0] = 20; //x
square_coord[1] = 10; //y
square_coord[2] = 50;
square_coord[3] = 10;
square_coord[4] = 50;
square_coord[5] = 40;
square_coord[6] = 20;
square_coord[7] = 40;
square_coord[8] = 20;
square_coord[9] = 10;
graphics.beginFill(0x442266);//set the color
graphics.drawPath(square_commands, square_coord);
}
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 329
Používání kreslicího rozhraní API
Definování pravidel vinutí
Verze Flash Player 10 a Adobe AIR 1.5 zavádí také koncept „vinutí“ (směru) cesty. Vinutí cesty je buď kladné (po
směru hodinových ručiček) nebo záporné (proti směru hodinových ručiček). Pořadí, ve kterém vykreslování udává
souřadnice poskytnuté vektorem pro daný datový parametr, určuje vinutí.
A
0
1
0
3
3
2
1
2
B
C
Kladné a záporné vinutí
A. Šipky udávají směr kreslení B. Kladné vinutí (po směru hodinových ručiček) C. Záporné vinutí (proti směru hodinových ručiček)
Dále si všimněte, že metoda Graphics.drawPath() má volitelný třetí parametr nazvaný „vinutí“:
drawPath(commands:Vector.<int>, data:Vector.<Number>, winding:String = "evenOdd"):void
V tomto kontextu je třetí parametr řetězec nebo konstanta, která určuje vinutí nebo pravidlo výplně pro protínající se
cesty. (Hodnoty konstanty jsou definovány ve třídě GraphicsPathWinding jako GraphicsPathWinding.EVEN_ODD
nebo GraphicsPathWinding.NON_ZERO.) Pravidlo vinutí je důležité při protnutí cest.
Pravidlo lichý-sudý je standardním pravidlem vinutí a je používáno všemi staršími kreslicími rozhraními API.
Pravidlo lichý-sudý je také výchozím pravidlem pro metodu Graphics.drawPath(). V případě pravidla lichý-sudý
jsou jakékoliv protnuté cesty střídavě otevřené a vyplněné. Pokud se protnou dva čtverce se stejnou výplní, oblast
průniku se vyplní. Obecně nejsou obě oblasti ani vyplněny ani nevyplněny.
Na druhou stranu nenulové pravidlo závisí na vinutí (směru kreslení) pro určení, zda budou oblasti definované
protínajícími se cestami vyplněny. Pokud se protnou cesty s opačným vinutím, budou definovány jako nevyplněné,
stejně jako v případě pravidla lichý-sudý. U cest se stejným vinutím bude vyplněna oblast, která by jinak zůstala bez
výplně:
A
B
Pravidla vinutí pro protínající se oblasti
A. Pravidlo vinutí lichý-sudý B. Nenulové pravidlo vinutí
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 330
Používání kreslicího rozhraní API
Názvy pravidel vinutí
Názvy se vztahují ke specifičtějšímu pravidlu, které definuje zpracování těchto výplní. Kladně vinutým cestám je
přiřazena hodnota +1; záporně vinutým cestám je přiřazena hodnota -1. Z bodu v uzavřené oblasti tvaru nakreslete
nekonečnou čáru. Počet průsečíků čáry s cestou a kombinované hodnoty těchto cest jsou použity k určení výplně. Pro
vinutí lichý-sudý se použije počet míst, kde čára přetíná cestu. Je-li tento počet lichý, oblast se vyplní. V případě sudého
počtu zůstane oblast nevyplněna. U nenulového vinutí jsou použity hodnoty přiřazené k cestám. Jestliže kombinované
hodnoty cesty nejsou 0, oblast se vyplní. Jestliže je kombinovaná hodnota 0, oblast zůstane nevyplněna.
A
B
Počty a výplně pravidla vinutí
A. Pravidlo vinutí lichý-sudý B. Nenulové pravidlo vinutí
Použití pravidel vinutí
Tato pravidla vinutí jsou složitá, ale v určitých situacích jsou nezbytná. Zvažte například nakreslení tvaru hvězdy. U
standardního pravidla lichý-sudý by daný tvar vyžadoval deset různých čar. U nenulového pravidla vinutí je počet čar
snížen na pět. Zde je jazyk ActionScript pro hvězdu s pěti čarami a nenulovým pravidlem vynutí:
fill.graphics.beginFill(0x60A0FF);graphics.drawPath( Vector.<int>([1,2,2,2,2]),
Vector.<Number>([66,10, 23,127, 122,50, 10,49, 109,127]),
GraphicsPathWinding.NON_ZERO);
A zde je tvar hvězdy:
A
B
C
Tvar hvězdy pomocí různých pravidel vinutí
A. Lichý-sudý 10 čar B. Lichý-sudý 5 čar C. Nenulový 5 čar
Když jsou obrazy animovány nebo používány na 3D objektech a překrývají se, pravidla vynutí se jsou důležitější.
Používání tříd grafických dat
Verze Flash Player 10 a Adobe AIR 1.5 zavádí v balíčku flash.display nový soubor tříd, které mají typ IGraphicsData
(rozhraní, které každá třída implementuje). Třídy, které implementují rozhraní IGraphicsData, slouží jako datové
kontejnery pro metody kreslicích rozhraní API.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 331
Používání kreslicího rozhraní API
Následující třídy implementují rozhraní IGraphicsData:
• GraphicsBitmapFill
• GraphicsEndFill
• GraphicsGradientFill
• GraphicsPath
• GraphicsShaderFill
• GraphicsSolidFill
• GraphicsStroke
• GraphicsTrianglePath
Pomocí těchto tříd můžete ukládat kompletní výkresy do pole vektorového objektu typu IGraphicsData.
(Vector.<IGraphicsData>), který lze znovu použít jako zdroj dat pro instance jiných tvarů nebo k ukládání informací
kreslení pro pozdější použití.
Všimněte si, že pro každý styl výplně existuje více tříd výplně, ale pouze jedna třída tahu. Jazyk ActionScript má pouze
jednu třídu tahu IGraphicsData, protože daná třída tahu používá třídy výplně k definici svého stylu. Proto je každý tah
vlastně třídou tahu a třídou výplně. V opačném případě odrážejí kreslicí rozhraní API pro tyto třídy grafických dat
metody, které představují ve třídě flash.display.Graphics:
Grafické metody
Třída Data
beginBitmapFill()
GraphicsBitmapFill
beginFill()
GraphicsSolidFill
beginGradientFill()
GraphicsGradientFill
beginShaderFill()
GraphicsShaderFill
lineBitmapStyle()
GraphicsStroke + GraphicsBitmapFill
lineGradientStyle()
GraphicsStroke + GraphicsGradientFill
lineShaderStyle()
GraphicsStroke + GraphicsShaderFill
lineStyle()
GraphicsStroke + GraphicsSolidFill
moveTo()
GraphicsPath
lineTo()
curveTo()
drawPath()
drawTriangles()
GraphicsTrianglePath
Dále má třída GraphicsPath svou vlastní metodu utility GraphicsPath.moveTo(), GraphicsPath.lineTo(),
GraphicsPath.curveTo(), GraphicsPath.wideLineTo() a GraphicsPath.wideMoveTo() pro snadné definování
příkazů pro instanci GraphicsPath. Tyto metody utility také přímo definují nebo aktualizují příkazy a hodnoty dat.
Máte-li soubor instancí IGraphicsData, použijte metodu Graphics.drawGraphicsData() k vykreslení grafiky.
Metoda Graphics.drawGraphicsData() spustí vektor instancí IGraphicsData pomocí kreslicích rozhraní API v
sekvenčním pořadí:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 332
Používání kreslicího rozhraní API
// stroke object
var stroke:GraphicsStroke = new GraphicsStroke(3);
stroke.joints = JointStyle.MITER;
stroke.fill = new GraphicsSolidFill(0x102020);// solid stroke
// fill object
var fill:GraphicsGradientFill = new GraphicsGradientFill();
fill.colors = [0x0000FF, 0xEEFFEE];
fill.matrix = new Matrix();
fill.matrix.createGradientBox(70,70, Math.PI/2);
// path object
var path:GraphicsPath = new GraphicsPath(new Vector.<int>(), new Vector.<Number>());
path.commands.push(1,2,2);
path.data.push(125,0, 50,100, 175,0);
// combine objects for complete drawing
var drawing:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
drawing.push(stroke, fill, path);
// draw the drawing
graphics.drawGraphicsData(drawing);
Úpravou jedné hodnoty v cestě použité kreslením v tomto příkladě lze tvar několikrát překreslit a získat tak složitější
obraz:
// draw the drawing multiple times
// change one value to modify each variation
graphics.drawGraphicsData(drawing);
path.data[2] += 200;
graphics.drawGraphicsData(drawing);
path.data[2] -= 150;
graphics.drawGraphicsData(drawing);
path.data[2] += 100;
graphics.drawGraphicsData(drawing);
path.data[2] -= 50;graphicsS.drawGraphicsData(drawing);
Ačkoliv mohou objekty IGraphicsData definovat styly výplně a tahů, nejsou tyto styly vyžadovány. Jinak řečeno,
metody třídy Graphics lze použít k nastavení stylů, zatímco objekty IGraphicsData lze použít k nakreslení uloženého
souboru cest, či naopak.
Poznámka: Pokud nepokračujete v původním výkresu (viz výše uvedený příklad), vyčistěte před zahájením nového
výkresu předchozí výkres pomocí metody Graphics.clear(). Při změně jedné části cesty nebo souboru objektů
IGraphicsData překreslete celý výkres, aby se zobrazily změny.
Při používání tříd grafických dat je výplň vykreslena kdykoliv při nakreslení tří nebo více bodů, protože daný tvar je
dědičně v daném bodě uzavřen. Výplň se uzavře, ale tah nikoliv. Toto chování se liší v případě použití více příkazů
Graphics.lineTo() nebo Graphics.moveTo().
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 333
Používání kreslicího rozhraní API
O použití metody drawTriangles()
Další pokročilá metoda zavedená ve verzích Flash Player 10 a Adobe AIR 1.5, Graphics.drawTriangles(), je
podobná metodě Graphics.drawPath(). Metoda Graphics.drawTriangles() také používá objekt
Vector.<Number> k určení polohy bodů pro nakreslení cesty.
Opravdovým účelem metody Graphics.drawTriangles() je nicméně umožnit 3D efekty pomocí jazyka
ActionScript. Informace o používání metody Graphics.drawTriangles() k vytvoření 3D efektů naleznete v tématu
„Používání trojúhelníků pro 3D efekty“ na stránce 507.
334
Kapitola 15: Práce s geometrií
Balíček flash.geom obsahuje třídy, které definují geometrické objekty jako body, obdélníky a matice transformace.
Tyto třídy slouží k definování vlastností objektů, které se používají v jiných třídách.
Základy geometrie
Úvod k práci s geometrií
Geometrie je možná předmět, který se mnoho lidí snaží ve škole nějak překlepat a přitom si zapamatovat co nejméně,
ale trocha znalostí z geometrie může být v jazyku ActionScript mocným nástrojem.
Balíček flash.geom obsahuje třídy, které definují geometrické objekty jako body, obdélníky a matice transformace.
Tyto třídy neposkytují nutně funkce samy o sobě. Avšak používají se k definování vlastností objektů, které se používají
v jiných třídách.
Všechny geometrické třídy jsou založeny na skutečnosti, že každé umístění na obrazovce je reprezentováno jako
dvojrozměrná rovina. Obrazovka je nahlížena jako plochý graf s vodorovnou osou (x) a svislou osou (y). Jakékoli
umístění (neboli bod) na obrazovce může být představen jako pár hodnot x a y – souřadnice tohoto umístění.
Každý objekt zobrazení, včetně vymezené plochy, má vlastní souřadnicový prostor – v podstatě svůj vlastní graf pro
vynášení umístění podřízených objektů zobrazení, kreseb atd. Počátek (místo se souřadnicemi 0, 0, kde je průsečík osy
x a osy y) je většinou umístěn v levém horním rohu objektu zobrazení. Ačkoli toto vždy platí pro vymezenou plochu,
nemusí to nutně platit pro jiný objekt zobrazení. Jako ve standardním dvojrozměrném souřadnicovém prostoru,
hodnoty na ose x narůstají směrem doprava a klesají směrem doleva – u umístění vlevo od počátku jsou hodnoty osy
x záporné. Avšak narozdíl od tradičních souřadnicových soustav, v jazyku ActionScript hodnoty na ose y na obrazovce
narůstají směrem dolů a klesají směrem nahoru (přičemž hodnoty nad počátkem jsou záporné). Protože levý horní
roh vymezené plochy je počátek jeho souřadnicového prostoru, každý objekt ve vymezené ploše bude mít souřadnici
x větší než 0 a menší než šířka vymezené plochy a souřadnici y větší než 0 a menší než výška vymezené plochy.
Instance třídy Point můžete použít k reprezentaci jednotlivých bodů v souřadnicovém prostoru. Můžete vytvořit
instanci Rectangle k reprezentaci obdélníkové plochy v souřadnicovém prostoru. Pokročilí uživatelé mohou použít
instanci třídy Matrix k aplikaci několika transformací nebo nějaké složité transformace na objekt zobrazení. Pomocí
vlastností určitého objektu zobrazení můžete přímo na tento objekt aplikovat mnoho jednoduchých transformací,
např. změna natočení, polohy a velikosti. Další informace o aplikování transformací pomocí vlastností objektu
zobrazení viz „Manipulace s objekty zobrazení“ na stránce 285.
Běžné geometrické úlohy
Následující úlohy jsou věci, které budete pravděpodobně chtít pomocí tříd geometrie v jazyku ActionScript
zrealizovat:
• Výpočet vzdálenosti mezi dvěma body
• Určování souřadnic bodu v různých souřadnicových prostorech
• Posouvání objektu zobrazení pomocí úhlu a vzdálenosti
• Práce s instancemi Rectangle:
• Přemístění instance Rectangle
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 335
Práce s geometrií
• Změna velikosti instance Rectangle
• Určování kombinované velikosti nebo překrývajících se oblastí instancí Rectangle
• Vytváření objektů Matrix
• Používání objektů Matrix k aplikaci transformací na objekt zobrazení
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Pravoúhlé souřadnice: souřadnice jsou obvykle zapisovány jako pár čísel (např. 5, 12 nebo 17, -23). Tato dvě čísla
vyjadřují hodnotu na ose x, resp. y.
• Souřadnicový prostor: graf se souřadnicemi obsažený v objektu zobrazení, na který jsou umísťovány podřízené
elementy.
• Počátek: bod v souřadnicovém prostoru, kde je průsečík osy x a osy y. Tento bod má souřadnice 0, 0.
• Bod: jednotlivé umístění v souřadnicovém prostoru. V soustavě souřadnic 3D používané v jazyku ActionScript, je
bod definován svým umístěním podél osy x a osy y (souřadnicemi bodu).
• Vztažný bod: v objektu zobrazení počátek (souřadnice 0, 0) jeho souřadnicového prostoru.
• Měřítko: velikost určitého objektu vzhledem k jeho původní velikosti. Nastavení měřítka, resp. velikosti určitého
objektu znamená změnu jeho velikosti zvětšením, resp. zmenšením daného objektu.
• Posunutí: změna souřadnic určitého bodu z jednoho souřadnicového prostoru na jiný.
• Transformace: Úprava vizuálních vlastností grafiky, jako je otočení objektu, změna velikosti, zkosení nebo
deformace tvaru či změna barvy.
• Osa x: vodorovná osa ve dvojrozměrné soustavě souřadnic používané v jazyku ActionScript.
• Osa y: svislá osa ve dvojrozměrné soustavě souřadnic používané v jazyku ActionScript.
Procházení příkladů v kapitole
Mnoho z příkladů v této kapitole představuje výpočty nebo změny hodnot. Většina z těchto příkladů zahrnuje volání
odpovídající funkce trace() za účelem demonstrace výsledků kódu. Zde je postup pro vyzkoušení těchto příkladů:
1 Pomocí vývojového nástroje Flash vytvořte prázdný dokument.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
Výsledky funkcí trace() uvedených kódů uvidíte v panelu Výstup.
Některé z příkladů v této kapitole ukazují aplikování transformací na objekty zobrazení. U těchto příkladů budou
výsledky příkladu spíše vizuální než textové. Zde je postup pro vyzkoušení příkladů transformace:
1 Pomocí vývojového nástroje Flash vytvořte prázdný dokument.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Vytvořte ve vymezené ploše instanci symbolu filmového klipu. Například nakreslete tvar, vyberte jej, zvolte příkaz
Změnit > Převést na symbol... a pojmenujte symbol.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 336
Práce s geometrií
5 V Inspektoru vlastností vyberte filmový klip Stage a udělte mu název instance. Tento název by se měl shodovat s
názvem použitým pro objekt zobrazení v uvedeném příkladu kódu – např. jestliže uvedený kód aplikuje
transformaci na objekt s názvem myDisplayObject, měli byste instanci filmového klipu pojmenovat také
myDisplayObject.
6 Spusťte program pomocí příkazu Ovládání > Testovat film.
Na obrazovce uvidíte výsledky transformací aplikovaných na daný objekt, jak jsou určeny v příkladu kódu.
Techniky pro zkoušení uvedených příkladů kódů jsou podrobněji vysvětleny v části „Testování příkladů kódu v této
kapitole“ na stránce 34.
Používání objektů Point
Objekt Point definuje pár pravoúhlých souřadnic. Představuje umístění v dvourozměrném souřadnicovém systému,
kde x představuje vodorovnou osu y představuje svislou osu.
Chcete-li definovat objekt Point, nastavte jeho vlastnosti x a y, viz níže:
import flash.geom.*;
var pt1:Point = new Point(10, 20); // x == 10; y == 20
var pt2:Point = new Point();
pt2.x = 10;
pt2.y = 20;
Nalezení vzdálenosti mezi dvěma body
Pomocí metody distance() třídy Point můžete zjistit rozdíl mezi dvěma body v souřadnicovém prostoru. Například
následující kód najde rozdíl mezi vztažnými body dvou objektů zobrazení, circle1 a circle2 ve stejném kontejneru
objektu zobrazení:
import flash.geom.*;
var pt1:Point = new Point(circle1.x, circle1.y);
var pt2:Point = new Point(circle2.x, circle2.y);
var distance:Number = Point.distance(pt1, pt2);
Posouvání souřadnicových prostorů
Jsou-li dva objekty zobrazení v různých kontejnerech objektu zobrazení, mohou se nacházet v různých
souřadnicových prostorech. Pomocí metody localToGlobal() třídy DisplayObject můžete posunout souřadnice do
stejného (globálního) souřadnicového prostoru náležejícího k vymezené ploše. Například následující kód najde rozdíl
mezi vztažnými body dvou objektů zobrazení, circle1 a circle2 v různých kontejnerech objektu zobrazení:
import flash.geom.*;
var pt1:Point = new Point(circle1.x, circle1.y);
pt1 = circle1.localToGlobal(pt1);
var pt2:Point = new Point(circle2.x, circle2.y);
pt2 = circle2.localToGlobal(pt2);
var distance:Number = Point.distance(pt1, pt2);
Podobně chcete-li zjistit vzdálenost vztažného bodu objektu zobrazení s názvem target od určitého bodu ve
vymezené ploše, můžete použít metodu localToGlobal() třídy DisplayObject:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 337
Práce s geometrií
import flash.geom.*;
var stageCenter:Point = new Point();
stageCenter.x = this.stage.stageWidth / 2;
stageCenter.y = this.stage.stageHeight / 2;
var targetCenter:Point = new Point(target.x, target.y);
targetCenter = target.localToGlobal(targetCenter);
var distance:Number = Point.distance(stageCenter, targetCenter);
Posouvání objektu zobrazení pomocí zadaného úhlu a vzdálenosti
Pomocí metody polar() třídy Point můžete posunout objekt zobrazení o určitou vzdálenost a pod určitým úhlem.
Například následující kód posune objekt myDisplayObject o 100 obr. bodů pod úhlem 60 stupňů:
import flash.geom.*;
var distance:Number = 100;
var angle:Number = 2 * Math.PI * (90 / 360);
var translatePoint:Point = Point.polar(distance, angle);
myDisplayObject.x += translatePoint.x;
myDisplayObject.y += translatePoint.y;
Další použití třídy Point
Objekty Point můžete použít s následujícími metodami a vlastnostmi:
Třída
Metody nebo vlastnosti
Popis
DisplayObjectContainer
areInaccessibleObjectsUnderPoint()getObject
sUnderPoint()
Používá se k vrácení seznamu objektů pod
bodem v kontejneru objektu zobrazení.
BitmapData
hitTest()
Používá se k definování obrazového bodu v
objektu BitmapData a také bodu, který
označujete pro klepnutí.
BitmapData
applyFilter()
Používá se k definování pozic obdélníků, které
definují operace.
copyChannel()
merge()
paletteMap()
pixelDissolve()
threshold()
Matice
deltaTransformPoint()
transformPoint()
Obdélník
bottomRight
Používá se k definování bodů, u kterých chcete
aplikovat transformaci.
Používá se k definování těchto vlastností.
size
topLeft
Používání objektů Rectangle
Objekt Rectangle definuje obdélníkovou plochu. Objekt Rectangle má polohu definovanou souřadnicemi x a y svého
levého horního rohu, vlastnost width a vlastnost height. U nového objektu Rectangle můžete tyto vlastnosti definovat
pomocí metody Rectangle(), viz níže:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 338
Práce s geometrií
import flash.geom.Rectangle;
var rx:Number = 0;
var ry:Number = 0;
var rwidth:Number = 100;
var rheight:Number = 50;
var rect1:Rectangle = new Rectangle(rx, ry, rwidth, rheight);
Změna velikosti a přemístění objektů Rectangle
Existuje několik způsobů změny velikosti a přemístění objektů Rectangle.
Objekt Rectangle můžete přemístit přímo změnou jeho vlastností x a y. To nemá vliv na šířku ani na výšku objektu
Rectangle.
import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace(rect1) // (x=0, y=0, w=100, h=50)
rect1.x = 20;
rect1.y = 30;
trace(rect1); // (x=20, y=30, w=100, h=50)
Jak ukazuje následující kód, změníte-li vlastnost left nebo top objektu Rectangle, objekt se také přemístí, přičemž
jeho souřadnice x a y budou odpovídat vlastnostem left a top. Poloha levého dolního rohu objektu Rectangle se však
při změně velikosti nezmění.
import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace(rect1) // (x=0, y=0, w=100, h=50)
rect1.left = 20;
rect1.top = 30;
trace(rect1); // (x=20, y=30, w=80, h=20)
Podobně, jak ukazuje následující příklad, změníte-li vlastnost bottom nebo right objektu Rectangle, poloha jeho
levého horního rohu se nezmění, takže se odpovídajícím způsobem změní jeho velikost.
import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace(rect1) // (x=0, y=0, w=100, h=50)
rect1.right = 60;
trect1.bottom = 20;
trace(rect1); // (x=0, y=0, w=60, h=20)
Objekt Rectangle můžete také přemístit pomocí metody offset() viz níže:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 339
Práce s geometrií
import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace(rect1) // (x=0, y=0, w=100, h=50)
rect1.offset(20, 30);
trace(rect1); // (x=20, y=30, w=100, h=50)
Metoda offsetPt() funguje podobně, s tou výjimkou, že bere jako svůj parametr objekt Point a ne hodnoty posunu
x a y.
Velikost objektu Rectangle můžete změnit také pomocí metody inflate(), která zahrnuje dva parametry, dx a dy.
Parametr dx představuje počet obrazových bodů, o který se posune levá a pravá strana obdélníku od středu, a parametr
dy představuje počet obrazových bodů, o které se posune horní a dolní strana obdélníku od středu:
import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace(rect1) // (x=0, y=0, w=100, h=50)
rect1.inflate(6,4);
trace(rect1); // (x=-6, y=-4, w=112, h=58)
Metoda inflatePt() funguje podobně, s tou výjimkou, že bere jako svůj parametr objekt Point a ne hodnoty dx a dy.
Nalezení sjednocení a průsečíků objektů Rectangle
Metoda union() slouží k nalezení obdélníkové plochy tvořené hranicemi dvou obdélníků:
import flash.display.*;
import flash.geom.Rectangle;
var rect1:Rectangle = new Rectangle(0, 0, 100, 100);
trace(rect1); // (x=0, y=0, w=100, h=100)
var rect2:Rectangle = new Rectangle(120, 60, 100, 100);
trace(rect2); // (x=120, y=60, w=100, h=100)
trace(rect1.union(rect2)); // (x=0, y=0, w=220, h=160)
Metoda intersection() slouží k nalezení obdélníkové plochy tvořené překrývající se plochou dvou obdélníků:
import flash.display.*;
import flash.geom.Rectangle;
var rect1:Rectangle = new Rectangle(0, 0, 100, 100);
trace(rect1); // (x=0, y=0, w=100, h=100)
var rect2:Rectangle = new Rectangle(80, 60, 100, 100);
trace(rect2); // (x=120, y=60, w=100, h=100)
trace(rect1.intersection(rect2)); // (x=80, y=60, w=20, h=40)
Pomocí metody intersects() můžete zjistit, zda se dva obdélníky protínají. Metodu intersects() můžete také
použít k zjištění, zda se objekt zobrazení nachází v určité oblasti vymezené plochy. Například v následujícím kódu se
předpokládá, že souřadnicový prostor kontejneru objektu zobrazení, který obsahuje objekt circle, je stejný jako
souřadnicový prostor vymezené plochy. Tento příklad ukazuje použití metody intersects() k určení, jestli objekt
circle protíná určené oblasti vymezené plochy, definované pomocí objektů Rectangle target1 a target2:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 340
Práce s geometrií
import flash.display.*;
import flash.geom.Rectangle;
var circle:Shape = new Shape();
circle.graphics.lineStyle(2, 0xFF0000);
circle.graphics.drawCircle(250, 250, 100);
addChild(circle);
var circleBounds:Rectangle = circle.getBounds(stage);
var target1:Rectangle = new Rectangle(0, 0, 100, 100);
trace(circleBounds.intersects(target1)); // false
var target2:Rectangle = new Rectangle(0, 0, 300, 300);
trace(circleBounds.intersects(target2)); // true
Podobně můžete pomocí metody intersects() zjistit, zda se ohraničující obdélníky dvou objektů zobrazení
překrývají. Metoda getRect() třídy DisplayObject slouží k zahrnutí určitého dodatečného prostoru, jenž mohou tahy
objektu zobrazení přidat, k ohraničující oblasti.
Další použití objektů Rectangle
Objekty Rectangle se používají v následujících metodách a vlastnostech:
Třída
Metody nebo vlastnosti
Popis
BitmapData
applyFilter(), colorTransform(),
copyChannel(), copyPixels(), draw(),
fillRect(), generateFilterRect(),
getColorBoundsRect(), getPixels(), merge(),
paletteMap(), pixelDissolve(), setPixels() a
threshold()
Používá se jako typ pro některé parametry k definování
oblasti objektu BitmapData.
DisplayObject
getBounds(), getRect(), scrollRect,
scale9Grid
Používá se jako typ dat pro vlastnost nebo vrácený typ
dat.
PrintJob
addPage()
Používá se k definování parametru printArea.
Sprite
startDrag()
Používá se k definování parametru bounds.
TextField
getCharBoundaries()
Používá se jako vrácený typ hodnoty.
Transformace
pixelBounds
Používá se jako typ dat.
Používání objektů Matrix
Třída Matrix představuje matici transformace, která určuje, jak se mají mapovat body od jednoho souřadnicového
prostoru k druhému. Na objektu zobrazení můžete vykonávat různé grafické transformace nastavením vlastností
objektu Matrix, aplikováním objektu Matrix na vlastnost matrix objektu Transform a pak aplikováním objektu
Transform jako vlastnosti transform objektu zobrazení. Tyto transformační funkce zahrnují posun (přemístění x a
y), natočení, změnu velikosti a zkosení.
Definování objektů Matrix
I když byste matici mohli definovat přímo úpravou vlastností (a, b, c, d, tx, ty) objektu Matrix, je jednodušší použít
metodu createBox(). Tato metoda zahrnuje parametry, které umožňují přímo definovat efekty změny velikosti,
natočení a posunutí výsledné matice. Například následující kód vytvoří objekt Matrix, který má efekt vodorovné
změny velikosti objektu o 2,0, svislé změny velikosti o 3,0, natočení o 45 stupňů, posun (posunutí) o 10 obr. bodů
doprava a posunutí o 20 obr. bodů dolů:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 341
Práce s geometrií
var matrix:Matrix = new Matrix();
var scaleX:Number = 2.0;
var scaleY:Number = 3.0;
var rotation:Number = 2 * Math.PI * (45 / 360);
var tx:Number = 10;
var ty:Number = 20;
matrix.createBox(scaleX, scaleY, rotation, tx, ty);
Můžete upravit také efekty změny velikosti, natočení a posunutí objektu Matrix pomocí metod scale(), rotate() a
translate(). Všimněte si, že tyto metody se kombinují s hodnotami stávajícího objektu Matrix. Například
následující kód nastaví objekt Matrix, který změní velikost objektu čtyřnásobně a otočí jej o 60 stupňů, protože metody
scale() a rotate() jsou vyvolány dvakrát:
var matrix:Matrix = new Matrix();
var rotation:Number = 2 * Math.PI * (30 / 360); // 30°
var scaleFactor:Number = 2;
matrix.scale(scaleFactor, scaleFactor);
matrix.rotate(rotation);
matrix.scale(scaleX, scaleY);
matrix.rotate(rotation);
myDisplayObject.transform.matrix = matrix;
Chcete-li na objekt Matrix aplikovat transformaci zkosení, upravte jeho vlastnost b nebo c. Úprava vlastnosti b způsobí
svislé zkosení matice a úprava vlastnosti c vodorovné zkosení matice. Následující kód zkosí objekt Matrix myMatrix
svisle dvojnásobně:
var skewMatrix:Matrix = new Matrix();
skewMatrix.b = Math.tan(2);
myMatrix.concat(skewMatrix);
Transformaci Matrix můžete aplikovat na vlastnost transform objektu zobrazení. Například následující kód aplikuje
transformaci matice na objekt zobrazení s názvem myDisplayObject:
var matrix:Matrix = myDisplayObject.transform.matrix;
var scaleFactor:Number = 2;
var rotation:Number = 2 * Math.PI * (60 / 360); // 60°
matrix.scale(scaleFactor, scaleFactor);
matrix.rotate(rotation);
myDisplayObject.transform.matrix = matrix;
První řádek nastaví objekt Matrix na stávající matici transformace používanou objektem zobrazení myDisplayObject
(vlastnost matrix vlastnosti transformation objektu zobrazení myDisplayObject). Takto budou mít metody třídy
Matrix, které vyvoláte, kumulativní účinek na stávající polohu, měřítko a natočení daného objektu zobrazení.
Poznámka: Třída ColorTransform je také součástí balíčku flash.geometry. Tato třída se používá k nastavení vlastnosti
colorTransform objektu Transform. Protože neaplikuje žádné geometrické transformace, není v této kapitole
probírána. Další informace viz třídu ColorTransform Referenční příručce jazyka ActionScript 3.0 a jeho součástí.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 342
Práce s geometrií
Příklad: Použití transformace matice na objekt
zobrazení
Aplikace ukázky DisplayObjectTransformer ukazuje několik funkcí použití třídy Matrix k transformaci objektu
zobrazení, včetně následujících:
• Natočení objektu zobrazení
• Změna velikosti objektu zobrazení
• Posunutí (přemístění) objektu zobrazení
• Zkosení objektu zobrazení
Tato aplikace poskytuje rozhraní pro úpravu parametrů transformace matice, viz níže:
Jakmile uživatel klepne na tlačítko Transformace, aplikace použije příslušnou transformaci.
Původní objekt zobrazení a objekt zobrazení otočený o -45° a se změnou velikosti o 50 %
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace DisplayObjectTransformer najdete ve složce Samples/DisplayObjectTransformer. Aplikace sestává
z následujících souborů:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 343
Práce s geometrií
Soubor
Popis
DisplayObjectTransformer.mxml
Hlavní aplikační soubor v aplikaci Flash (FLA) nebo Flex
(MXML)
nebo
DisplayObjectTransformer.fla
com/example/programmingas3/geometry/MatrixTransformer.as
Třída, která obsahuje metody pro použití transformací matice.
img/
Adresář obsahující ukázkové obrazové soubory používané
touto aplikací.
Definování třídy MatrixTransformer
Třída MatrixTransformer obsahuje statické metody, které aplikují geometrické transformace objektů Matrix.
Metoda transform()
Metoda transform() zahrnuje parametry pro následující:
•
sourceMatrix – vstupní matice, kterou metoda transformuje
•
xScale a yScale – měřítko x a y
•
dx a dy – velikost posunutí x a y v obrazových bodech
•
rotation – velikost natočení ve stupních
•
skew – míra zkosení v procentech
•
skewType – směr zkosení, buď "right" nebo "left"
Vrácená hodnota je výsledná matice.
Metoda transform() vyvolá následující statické metody dané třídy:
•
skew()
•
scale()
•
translate()
•
rotate()
Každá z těchto metod vrátí zdrojovou matici s použitou transformací.
Metoda skew()
Metoda skew() zkosí matici úpravou vlastností b a c dané matice. Volitelný parametr, unit, určuje jednotky
používané k definování úhlu zkosení a v případě potřeby tato metoda převede hodnotu angle na radiány:
if (unit ==
{
angle =
}
if (unit ==
{
angle =
}
"degrees")
Math.PI * 2 * angle / 360;
"gradients")
Math.PI * 2 * angle / 100;
Vytvoří se objekt Matrix skewMatrix a upraví se pro použití transformace zkosení. Na počátku je to jednotková
matice, viz níže:
var skewMatrix:Matrix = new Matrix();
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 344
Práce s geometrií
Parametr skewSide určuje stranu, na kterou se zkosení aplikuje. Je-li nastaven na "right", nastaví následující kód
vlastnost b dané matice:
skewMatrix.b = Math.tan(angle);
Jinak bude zkosena spodní strana úpravou vlastnosti c matice, viz níže:
skewMatrix.c = Math.tan(angle);
Výsledné zkosení bude poté aplikováno na stávající matici sloučením dvou matic, jak ukazuje následující příklad:
sourceMatrix.concat(skewMatrix);
return sourceMatrix;
Metoda scale()
Jak ukazuje následující příklad, metoda scale() nejprve upraví měřítko, je-li dodáno v procentuální hodnotě, a dále
použije metodu scale() objektu matice:
if (percent)
{
xScale = xScale / 100;
yScale = yScale / 100;
}
sourceMatrix.scale(xScale, yScale);
return sourceMatrix;
Metoda translate()
Metoda translate() jen aplikuje činitele posunutí dx a dy vyvoláním metody translate() objektu matice, viz níže:
sourceMatrix.translate(dx, dy);
return sourceMatrix;
Metoda rotate()
Metoda rotate() převede vstupní činitel natočení na radiány (je-li dodán ve stupních nebo gradientech) a poté vyvolá
metodu rotate() objektu matice:
if (unit == "degrees")
{
angle = Math.PI * 2 * angle / 360;
}
if (unit == "gradients")
{
angle = Math.PI * 2 * angle / 100;
}
sourceMatrix.rotate(angle);
return sourceMatrix;
Volání metody MatrixTransformer.transform() z aplikace
Tato aplikace obsahuje uživatelské rozhraní pro získání parametrů transformace od uživatele. Ty potom předá, spolu
s vlastností matrix vlastnosti transform objektu zobrazení, metodě Matrix.transform(), viz níže:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 345
Práce s geometrií
tempMatrix = MatrixTransformer.transform(tempMatrix,
xScaleSlider.value,
yScaleSlider.value,
dxSlider.value,
dySlider.value,
rotationSlider.value,
skewSlider.value,
skewSide );
Aplikace poté použije vrácenou hodnotu na vlastnost matrix vlastnosti transform objektu zobrazení a tím spustí
transformaci:
img.content.transform.matrix = tempMatrix;
346
Kapitola 16: Filtrování objektů zobrazení
Použití efektů filtrů na snímky bitmapy je doménou specializovaného software pro úpravu snímků, například
programů Adobe Photoshop® a Adobe Fireworks®. Jazyk ActionScript 3.0 zahrnuje balík flash.filters, který obsahuje
třídy filtrů efektů bitmap a umožňuje tak vývojářům programaticky použít filtry na bitmapy a objekty zobrazení a
dosáhnout mnoha stejných efektů, které jsou dostupné v aplikacích pro manipulaci s grafikou.
Základní informace o filtrování objektů zobrazení
Úvod k filtrování objektů zobrazení
Jedním způsobem vylepšení aplikace je přidání jednoduchých grafických efektů, například vrženého stínu za fotografii
pro vytvoření iluze třetího rozměru nebo záře okolo tlačítka, která ukazuje, že tlačítko je aktivní. Jazyk ActionScript
3.0 obsahuje devět filtrů, které můžete použít na jakýkoliv objekt zobrazení nebo na instanci BitmapData. Tyto filtry
se pohybují od základních filtrů, například vrženého stínu a filtru záře, po složité filtry k vytváření různých efektů,
například filtry mapy přestavění a filtr konvoluce.
Běžné úlohy filtrování
Následující úlohy představují výsledky, kterých budete pravděpodobně chtít použitím filtrů v jazyce ActionScript
dosáhnout:
• Vytváření filtru
• Použití filtru na objekt zobrazení
• Odstranění filtru z objektu zobrazení
• Použití filtru na data obrazu v instanci BitmapData
• Odstranění filtrů z objektu
• Vytváření různých efektů filtru, například záře, rozostření, vrženého stínu, zostření, přestavění, detekce okrajů,
reliéf a jiných.
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Úkos: Okraj vytvořený osvětlením obrazových bodů na dvou stranách a ztmavením obrazových bodů na opačných
dvou stranách. Vytvoří se tak efekt trojrozměrné hranice, který se běžně používá pro vyvýšená nebo odsazená
tlačítka a podobnou grafiku.
• Konvoluce: Zkreslení obrazových bodů v obrazu kombinováním hodnoty každého obrazového bodu s hodnotami
některých nebo všech jeho sousedících obrazových bodů, a to pomocí různých poměrů.
• Přestavění: Posouvání nebo pohybování obrazovými body na obrazu do nových poloh.
• Matice: Mřížka čísel používaná pro provedení určitých matematických výpočtů aplikací čísel ve mřížce na různé
hodnoty a následným zkombinováním výsledků.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 347
Filtrování objektů zobrazení
Procházení příkladů v kapitole
Při práci s kapitolou si můžete přát otestovat ukázky kódů, které jsou k dispozici. Protože se tato kapitola věnuje
vytváření a zpracovávání vizuálního obsahu, testování kódu zahrnuje spuštění kódu a zobrazení výsledků v souboru
SWF, který je vytvořen. Skoro všechny příklady buď vytvoří obsah pomocí výkresových API nebo nahrají obrazy, na
které se filtry použijí.
Chcete-li testovat kód v této kapitole:
1 Pomocí vývojového nástroje Flash vytvořte prázdný dokument.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte kód do panelu Skript.
4 Spusťte program pomocí příkazu Ovládání > Testovat film.
Výsledky kódu budou zobrazeny v souboru SWF, který je vytvořen.
Skoro všechny příklady kódu zahrnují kód, který vytváří obraz bitmapy, takže kód můžete testovat přímo bez potřeby
poskytnout obsah bitmapy. Alternativně můžete změnit ukázku kódu, nahrát tak své vlastní obrazy a použít je namísto
obrazů v příkladu.
Vytváření a používání filtrů
Filtry vám umožňují použít různé efekty na bitmapy a objekty zobrazení, od vržených stínů až po úkosy a rozostření.
Každý filtr je definován jako třída, takže použití filtrů zahrnuje vytvoření instancí objektů filtrů, což se neliší od
konstruování jakéhokoliv jiného objektu. Jakmile jste vytvořili instanci objektu filtru, můžete ji snadno použít na
objekty zobrazení pomocí vlastnosti objektu filters, nebo v případě objektu BitmapData použitím metody
applyFilter().
Vytváření nového filtru
Pro vytvoření nového objektu filtru jednoduše volejte metodu konstruktoru své vybrané třídy filtru. Například pro
vytvoření nového objektu DropShadowFilter použijte následující kód:
import flash.filters.DropShadowFilter;
var myFilter:DropShadowFilter = new DropShadowFilter();
Ačkoliv to zde není ukázáno, konstruktor DropShadowFilter() (jako všechny konstruktory tříd filtru) přijímá
několik volitelných parametrů, které lze použít pro vlastní nastavení vzhledu efektu filtru.
Použití filtru
Jakmile jste vytvořili objekt filtru, můžete jej použít na objekt zobrazení nebo objekt BitmapData; způsob použití filtru
závisí na objektu, na který jej používáte.
Použití filtru na objekt zobrazení
Když použijete efekty filtru na objekt zobrazení, použijete je pomocí vlastnosti filters . Vlastnost filters objektu
zobrazení je instance Array, jejíž elementy jsou objekty zobrazení použité na objekt zobrazení. Pro použití jediného
filtru na objekt zobrazení vytvořte instanci filtru, přidejte ji k instanci Array a přiřaďte daný objekt Array k vlastnosti
objektu zobrazení filters:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 348
Filtrování objektů zobrazení
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.filters.DropShadowFilter;
// Create a bitmapData object and render it to screen
var myBitmapData:BitmapData = new BitmapData(100,100,false,0xFFFF3300);
var myDisplayObject:Bitmap = new Bitmap(myBitmapData);
addChild(myDisplayObject);
// Create a DropShadowFilter instance.
var dropShadow:DropShadowFilter = new DropShadowFilter();
// Create the filters array, adding the filter to the array by passing it as
// a parameter to the Array() constructor.
var filtersArray:Array = new Array(dropShadow);
// Assign the filters array to the display object to apply the filter.
myDisplayObject.filters = filtersArray;
Jestliže si k objektu přejete přiřadit více filtrů, jednoduše přidejte všechny filtry k instanci Array před tím, než ji
přiřadíte k vlastnosti filters. Více objektů k instanci Array lze přidat tak, že je předáte jako parametry k jejich
konstruktoru. Tento kód například použije filtr úkosu a vrženého stínu na předchozí vytvořený objekt zobrazení:
import flash.filters.BevelFilter;
import flash.filters.GlowFilter;
// Create the filters and add them to an array.
var bevel:BevelFilter = new BevelFilter();
var glow:GlowFilter = new GlowFilter();
var filtersArray:Array = new Array(bevel, glow);
// Assign the filters array to the display object to apply the filter.
myDisplayObject.filters = filtersArray;
Při vytváření pole obsahujícího filtry jej můžete vytvořit pomocí konstruktoru new Array() (jak je uvedeno v
předchozím příkladě) nebo můžete použít syntaxi literálu a vložit filtry do hranatých závorek ([]). Například tento
řádek kódu:
var filters:Array = new Array(dropShadow, blur);
má stejnou funkci jako tento řádek kódu:
var filters:Array = [dropShadow, blur];
Jestliže na objekty zobrazení použijete více filtrů, použijí se kumulativním, sekvenčním způsobem. Jestliže má
například pole filtrů dva elementy, filtr úkosu přidal první a filtr vrženého stínu přidal druhý element. Filtr vrženého
stínu je použit na filtr úkosu i na objekt zobrazení. Důvodem je to, že filtr vrženého stínu je v poli filtru na druhé pozici.
Jestliže si přejete použít filtry nikoliv kumulativním způsobem, musíte každý filtr použít na novou kopii objektu
zobrazení.
Jestliže objektu zobrazení přiřazujete pouze jeden nebo několik málo filtrů, můžete vytvořit instanci filtru a přiřadit ji
danému objektu v jediném příkazu. Například následující řádek kódu použije efekt rozostření na objekt zobrazení
nazvaný myDisplayObject:
myDisplayObject.filters = [new BlurFilter()];
Předcházející kód vytvoří instanci Array pomocí syntaxe literálu Array (čtvercové závorky), vytvoří novou instanci
BlurFilter jako element ve třídě Array a přiřadí dané pole vlastnosti filters objektu zobrazení pojmenovanému
myDisplayObject.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 349
Filtrování objektů zobrazení
Odstranění filtrů z objektu zobrazení
Odstraňování všech filtrů z objektu zobrazení je stejně jednoduché jako přiřazení nulové hodnoty k vlastnosti
filters:
myDisplayObject.filters = null;
Jestliže jste na objekt použili více filtrů a přejete si odstranit pouze jeden z těchto filtrů, musíte pro změnu pole
vlastnosti filters provést několik kroků. Pro více informací viz „Možné problémy při práci s filtry“ na stránce 349.
Použití filtru na objekt BitmapData
Použití filtru na objekt BitmapData vyžaduje použití metody BitmapData applyFilter():
var rect:Rectangle = new Rectangle();
var origin:Point = new Point();
myBitmapData.applyFilter(sourceBitmapData, rect, origin, new BlurFilter());
Metoda applyFilter() použije filtr na zdrojový objekt BitmapData a vytvoří nový filtrovaný obraz. Tato metoda
neupravuje původní zdrojový obraz; namísto toho je výsledek filtru použitého na zdrojový obraz uložen v instanci
BitmapData, na které je volána metoda applyFilter().
Jak filtr funguje
Filtrování objektu zobrazení pracuje pomocí uložení kopie původního objektu zobrazení do vyrovnávací paměti jako
průhledné bitmapy.
Jakmile byl filtr použit na objekt zobrazení, program Adobe Flash Player nebo Adobe® AIR™ uloží daný objekt do
vyrovnávací paměti jako bitmapu, po tak dlouho dobu, po jakou má daný objekt platný seznam filtrů. Tato zdrojová
bitmapa je poté použita jako původní obraz pro všechny následně použité efekty filtrů.
Každý objekt zobrazení obvykle obsahuje dvě bitmapy: jednu s původním nefiltrovaným objektem zobrazení a další
pro konečný obraz po filtrování. Konečný obraz se použije při vykreslení. Dokud se objekt zobrazení nezmění,
konečný obraz není třeba aktualizovat.
Možné problémy při práci s filtry
Existuje několik možných zdrojů nejasností nebo potíží, které je třeba mít při používání filtrů na paměti. Tyto zdroje
jsou popsány v následujících částech.
Filtry a ukládání bitmap do vyrovnávací paměti
Pro použití filtru na objekt zobrazení musí být pro daný objekt aktivováno stahování bitmap do vyrovnávací paměti.
Jestliže použijete filtr na objekt zobrazení, jehož vlastnost cacheAsBitmap je nastavena na false, přehrávač Flash
Player nebo program AIR automaticky nastaví hodnotu vlastnosti objektu cacheAsBitmap na true. Jestliže později
odstraníte všechny filtry z objektu zobrazení, přehrávač Flash Player nebo program AIR znovu nastaví vlastnost
cacheAsBitmap na poslední hodnotu, na kterou byla nastavena.
Změna filtrů v době běhu
Jestliže je na objekt zobrazení již použit jeden nebo více filtrů, nemůžete nastavení filtrů změnit přidáním dodatečných
filtrů nebo odstraněním filtrů z pole vlastnosti filters. Namísto toho musíte pro přidání nebo změnu sady použitých
filtrů provést změny v samostatném poli a poté dané pole přiřadit vlastnostem filtrů objektu zobrazení, aby byly filtry
na objekt použity. Nejjednodušším způsobem provedení změn je načíst pole vlastnosti filters do proměnné Array
a provést své úpravy do tohoto přechodného pole. Poté můžete toto pole přiřadit zpět vlastnosti filters objektu
zobrazení. Ve složitějších případech můžete potřebovat zachovat samostatné hlavní pole filtrů. V daném hlavním poli
filtru provedete libovolné změny a po každé změně jej znovu přiřadíte vlastnosti objektu zobrazení filters.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 350
Filtrování objektů zobrazení
Přidání dodatečného filtru
Následující kód uvádí proces přidání dodatečných filtru k objektu zobrazení, na který je již použit jeden nebo více
filtrů. Původně je filtr záře použit na objekt zobrazení pojmenovaný myDisplayObject; později je po klepnutí na
objekt zobrazení volána metoda addFilters(). V této funkci jsou na myDisplayObjectpoužity dva dodatečné filtry:
import flash.events.MouseEvent;
import flash.filters.*;
myDisplayObject.filters = [new GlowFilter()];
function addFilters(event:MouseEvent):void
{
// Make a copy of the filters array.
var filtersCopy:Array = myDisplayObject.filters;
// Make desired changes to the filters (in this case, adding filters).
filtersCopy.push(new BlurFilter());
filtersCopy.push(new DropShadowFilter());
// Apply the changes by reassigning the array to the filters property.
myDisplayObject.filters = filtersCopy;
}
myDisplayObject.addEventListener(MouseEvent.CLICK, addFilters);
Odstranění jednoho filtru ze sady filtrů
Jestliže je na objekt zobrazení použito více filtrů a přejete-li si jeden z těchto filtrů odstranit, zatímco ostatní filtry
budou i nadále na daný objekt použity, odstraňte nechtěný filtr z daného pole a přechodné pole znovu přiřaďte
vlastnosti objektu zobrazení filters. Několik způsobů pro odstranění jednoho nebo více elementů z jakéhokoliv pole
je popsáno v části „Načítání hodnot a odstraňování elementů pole“ na stránce 158.
Nejjednodušší situace je odstranění filtru na nejvyšší úrovni objektu (poslední filtr použitý na daný objekt). Pro
odstranění filtru z pole můžete použít metodu třídy Array pop():
// Example of removing the top-most filter from a display object
// named "filteredObject".
var tempFilters:Array = filteredObject.filters;
// Remove the last element from the Array (the top-most filter).
tempFilters.pop();
// Apply the new set of filters to the display object.
filteredObject.filters = tempFilters;
Podobně pro odstranění filtru na nejnižší úrovni (první použitý na objekt) můžete použít stejný kód a nahradit tak
metodou třídy Array shift() metodu pop().
Pro odstranění filtru ze středu pole filtrů (za předpokladu, že má dané pole více než dva filtry) můžete použít metodu
splice(). Musíte znát index (polohu v poli) filtru, který si přejete odstranit. Například následující kód odstraní z
objektu zobrazení druhý filtr (filtr v indexu 1):
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 351
Filtrování objektů zobrazení
// Example of removing a filter from the middle of a stack of filters
// applied to a display object named "filteredObject".
var tempFilters:Array = filteredObject.filters;
// Remove the second filter from the array. It's the item at index 1
// because Array indexes start from 0.
// The first "1" indicates the index of the filter to remove; the
// second "1" indicates how many elements to remove.
tempFilters.splice(1, 1);
// Apply the new set of filters to the display object.
filteredObject.filters = tempFilters;
Určení indexu filtru
Musíte vědět, který filtr má být z pole odstraněn. To znamená, že musíte znát index daného filtru. Musíte buď znát
(díky způsobu, jakým je aplikace navržena) nebo vypočítat index filtru, který si přejete odstranit.
Nejlepším přístupem je navrhnout vaší aplikaci tak, aby byl filtr, který si přejete odstranit, v sadě filtrů vždy ve stejné
pozici. Jestliže máte například jediný objekt zobrazení s filtrem konvoluce, na který je použit filtr vrženého stínu (v
tomto pořadí) a přejete si filtr vrženého stínu odstranit, ale filtr konvoluce zachovat, filtr je ve známé pozici (filtr na
nejvyšší úrovni), takže dopředu víte, kterou metodu Array použít (v tomto příkladě metodu Array.pop() pro
odstranění filtru vrženého stínu).
Jestliže má filtr, který si přejete odstranit, určitý typ, ale není vždy v sadě filtrů na stejné pozici, můžete zkontrolovat
datový typ každého filtru v daném poli a určit tak, který filtr má být odstraněn. Například následující kód ukazuje,
který ze sady filtrů je filtr záře a tento filtr odstraní ze seznamu.
// Example of removing a glow filter from a set of filters, where the
//filter you want to remove is the only GlowFilter instance applied
// to the filtered object.
var tempFilters:Array = filteredObject.filters;
// Loop through the filters to find the index of the GlowFilter instance.
var glowIndex:int;
var numFilters:int = tempFilters.length;
for (var i:int = 0; i < numFilters; i++)
{
if (tempFilters[i] is GlowFilter)
{
glowIndex = i;
break;
}
}
// Remove the glow filter from the array.
tempFilters.splice(glowIndex, 1);
// Apply the new set of filters to the display object.
filteredObject.filters = tempFilters;
Ve složitějších případech, například pokud je filtr k odstranění vybrán v době běhu, je nejlepším přístupem zachovat
samostatnou trvalou kopii pole filtru, která slouží jako hlavní seznam filtrů. Kdykoliv provedete změnu nastavení filtrů
(přidáváte filtr nebo odstraňujete filtr), změňte hlavní seznam a poté dané pole filtru použijte jako vlastnost filters
objektu zobrazení.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 352
Filtrování objektů zobrazení
Například v následující ukázce kódu jsou na objekt zobrazení pro vytvoření vizuálních efektů použity násobné filtry
konvoluce a později je v aplikaci jeden z těchto filtrů odstraněn, zatímco jiné jsou zachovány. V tomto případě kód
uchová hlavní kopii pole filtrů, i referenci na filtr, který má být odstraněn. Vyhledávání a odstraňování filtru je
podobné předcházejícímu přístupu s výjimkou, že namísto vytvoření přechodné kopie pole filtrů je zpracována hlavní
kopie a je poté použita na objekt zobrazení.
//
//
//
//
Example of removing a filter from a set of
filters, where there may be more than one
of that type of filter applied to the filtered
object, and you only want to remove one.
// A master list of filters is stored in a separate,
// persistent Array variable.
var masterFilterList:Array;
// At some point, you store a reference to the filter you
// want to remove.
var filterToRemove:ConvolutionFilter;
// ... assume the filters have been added to masterFilterList,
// which is then assigned as the filteredObject.filters:
filteredObject.filters = masterFilterList;
// ... later, when it's time to remove the filter, this code gets called:
// Loop through the filters to find the index of masterFilterList.
var removeIndex:int = -1;
var numFilters:int = masterFilterList.length;
for (var i:int = 0; i < numFilters; i++)
{
if (masterFilterList[i] == filterToRemove)
{
removeIndex = i;
break;
}
}
if (removeIndex >= 0)
{
// Remove the filter from the array.
masterFilterList.splice(removeIndex, 1);
// Apply the new set of filters to the display object.
filteredObject.filters = masterFilterList;
}
V tomto přístupu (jestliže porovnáváte uloženou referenci filtru s položkami v poli filtrů a přejete si určit, který filtr
má být odstraněn), musíte zachovat samostatnou kopii pole filtrů - kód nefunguje, jestliže porovnáváte uloženou
referenci filtru s elementy v přechodném poli zkopírovaném z vlastnosti objektu zobrazení filters. Důvod je interní
- pokud přiřazujete pole k vlastnosti filtrů filters, přehrávač Flash Player nebo program AIR vytvoří kopii každého
objektu filtru v daném poli. Tyto kopie (spíše než původní objekty) se použijí na objekt zobrazení a když načtete
vlastnost filters do přechodného pole, obsahuje přechodné pole reference na kopírované objekty filtru, spíše než
reference na původní objekty filtru. Jestliže se v předcházejícím příkladě pokusíte určit index filterToRemove jeho
porovnáním s filtry v přechodném poli filtrů, nebude nalezena žádná shoda.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 353
Filtrování objektů zobrazení
Transformace filtrů a objektů
Žádná filtrovaná oblast - například vržený stín - mimo ohraničující rámeček objektu zobrazení není za účelem detekce
shody považována za část povrchu (určení, jestli instance přesahuje nebo protíná jinou instanci). Protože jsou metody
pro detekci shody třídy DisplayObject založeny na vektorech, nemůžete detekci shody provést na výsledku bitmapy.
Jestliže například použijete filtr úkosu na instanci tlačítka, detekce shody není na zkosené části instance dostupná.
Změna měřítka, otočení a zkosení nejsou filtry podporovány; jestliže je u samotného objektu zobrazení změněno
měřítko, (jestliže scaleX a scaleY nejsou 100%), účinek filtru nezmění měřítko společně s instancí. To znamená, že
původní tvar instance rotuje, mění měřítko nebo je zkosený; nicméně filtr nerotuje, nemění měřítko a není zkosený
společně s instancí.
Pomocí filtru můžete animovat instanci a vytvořit tak realistické efekty, nebo můžete instance vnořit, použít třídu
BitmapData pro animaci filtrů a dosáhnout tak požadovaného efektu.
Filtry a objekty Bitmap
Jestliže na objekt BitmapData použijete libovolný filtr, vlastnost cacheAsBitmap je automaticky nastavena na true.
Tímto způsobem je filtr vlastně použit na kopii objektu, nikoliv na jeho originál.
Tato kopie je poté umístěna do hlavního zobrazení (překryje původní objekt) co nejblíže nejbližšímu obrazovému
bodu. Jestliže se hranice původní bitmapy změní, bitmapa filtrované kopie je znovu vytvořena z originálu a není
natažena nebo zdeformována.
Jestliže vymažete všechny filtry pro objekt zobrazení, vlastnost cacheAsBitmap je resetována na původní hodnotu
před použitím filtru.
Dostupné filtry zobrazení
Jazyk ActionScript 3.0 zahrnuje deset tříd filtrů, které lze použít na objekty zobrazení a objekty BitmapData:
• Filtr úkosu (třída BevelFilter)
• Filtr rozostření (třída BlurFilter)
• Filtr vrženého stínu (třída DropShadowFilter)
• Filtr záře (třída GlowFilter)
• Filtr úkosu s přechodem (třída GradientBevelFilter)
• Filtr záře s přechodem (třída GradientGlowFilter)
• Filtr matice barev (třída ColorMatrixFilter)
• Filtr konvoluce (Třída ConvolutionFilter)
• Filtr mapy přestavění (třída DisplacementMapFilter)
• Třída clony (třída ShaderFilter)
Prvních šest filtrů jsou jednoduché filtry, které lze použít pro vytvoření jednoho specifického efektu, s určitým
uživatelským nastavením dostupného efektu. Těchto šest filtrů lze použít pomocí jazyka ActionScript a lze je také
použít na objekty v programu Adobe Flash CS4 Professional pomocí panelu Filtry. I když tedy používáte filtry pomocí
jazyka ActionScript, jestliže máte vývojový nástroj Flash, můžete použít vizuální rozhraní pro rychlé vyzkoušení
různých filtrů a nastavení a zjistit, jak vytvořit požadovaný efekt.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 354
Filtrování objektů zobrazení
Závěrečné čtyři filtry jsou dostupné pouze v jazyce ActionScript. Tyto filtry, filtr matice barev, filtr konvoluce, filtr
mapy přestavění a filtr clony, jsou o mnoho flexibilnější co do typů efektů, které mohou vytvořit. Spíše než optimalizaci
pro jediný efekt poskytují výkon a flexibilitu. Například výběrem různých hodnot pro svou matici lze filtr konvoluce
použít pro vytvoření efektů, například rozostření, reliéf, zostření, nalezení okrajů barev, transformace a další.
Každý z těchto filtrů, ať už jednoduchý nebo složitý, lze pomocí jeho vlastností upravit na míru. Obecně máte při
nastavování vlastností filtrů dvě volby. Všechny filtry vám umožňují nastavit vlastnosti předáním hodnot jejich
parametru do konstruktoru objektu filtru. Ať už vlastnosti filtru nastavíte nebo nenastavíte předáním parametrů,
můžete filtry upravit později nastavením hodnot na vlastnosti daného objektu filtru. Aby byly příklady snazší, většina
uvedených příkladů kódu nastaví vlastnosti přímo. Nicméně stejného výsledku můžete obvykle dosáhnout v méně
řádcích kódu, a to předáním hodnot jako parametrů do konstruktoru objektu filtru. Více informací o specifikacích
každého filtru, jeho vlastnostech a parametrech jeho konstruktoru naleznete v ukázkách pro balík flash.filters v
Referenční příručce jazyka ActionScript 3.0 a jeho komponent.
Filtr úkosu
Třída BevelFilter vám umožňuje přidat k filtrovanému objektu 3D zkosený okraj. Tento filtr vytváří pevné okraje nebo
hrany vašeho objektu, které vypadají, jako by byly opracovány nebo zkoseny směrem pryč.
Vlastnosti třídy BevelFilter vám umožňují upravit vzhled úkosu. Můžete nastavit barvy zvýraznění a stínu, rozostření
úhlu úkosu, úhly úkosu a umístění hrany úkosu; můžete také vytvořit efekt vyseknutí.
Následující příklad načte externí obraz a použije na něj filtr úkosu.
import
import
import
import
import
flash.display.*;
flash.filters.BevelFilter;
flash.filters.BitmapFilterQuality;
flash.filters.BitmapFilterType;
flash.net.URLRequest;
// Load an image onto the Stage.
var imageLoader:Loader = new Loader();
var url:String = "http://www.helpexamples.com/flash/images/image3.jpg";
var urlReq:URLRequest = new URLRequest(url);
imageLoader.load(urlReq);
addChild(imageLoader);
// Create the bevel filter and set filter properties.
var bevel:BevelFilter = new BevelFilter();
bevel.distance = 5;
bevel.angle = 45;
bevel.highlightColor = 0xFFFF00;
bevel.highlightAlpha = 0.8;
bevel.shadowColor = 0x666666;
bevel.shadowAlpha = 0.8;
bevel.blurX = 5;
bevel.blurY = 5;
bevel.strength = 5;
bevel.quality = BitmapFilterQuality.HIGH;
bevel.type = BitmapFilterType.INNER;
bevel.knockout = false;
// Apply filter to the image.
imageLoader.filters = [bevel];
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 355
Filtrování objektů zobrazení
Filtr rozostření
Třída BlurFilter rozmaže nebo rozostří objekt zobrazení a jeho obsah. Efekty rozostření jsou užitečné pro vyvolání
dojmu, že je objekt nezaostřen nebo pro simulaci rychlého pohybu, například při rozostření pohybu. Nastavením
vlastnosti quality filtru rozostření na nízkou hodnotu můžete simulovat jemný efekt nezaostřené čočky. Nastavením
vlastnosti quality na vysoké hodnoty vytvoříte hladký efekt rozostření, podobný gausově rozostření.
Následující příklad vytvoří použitím metody drawCircle() třídy Graphics kruhový objekt a použije na něj filtr
rozostření:
import flash.display.Sprite;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
// Draw a circle.
var redDotCutout:Sprite = new Sprite();
redDotCutout.graphics.lineStyle();
redDotCutout.graphics.beginFill(0xFF0000);
redDotCutout.graphics.drawCircle(145, 90, 25);
redDotCutout.graphics.endFill();
// Add the circle to the display list.
addChild(redDotCutout);
// Apply the blur filter to the rectangle.
var blur:BlurFilter = new BlurFilter();
blur.blurX = 10;
blur.blurY = 10;
blur.quality = BitmapFilterQuality.MEDIUM;
redDotCutout.filters = [blur];
Filtr vrženého stínu
Vržené stíny vyvolají dojem, že je nad cílovým objektem umístěn samostatný zdroj světla. Polohu a intenzitu tohoto
zdroje světla lze upravit tak, aby vznikly různé efekty vrženého stínu.
Třída DropShadowFilter používá algoritmus, který se podobá algoritmu filtru rozostření. Hlavním rozdílem je to, že
filtr vrženého stínu má o více vlastností, které lze upravit a simulovat tak různé atributu zdroje světla (například alfa,
barva, odsazení a jas).
Filtr vrženého stínu vám také umožňuje použít vlastní volby transformace na styl vrženého stínu, včetně vnitřního a
vnějšího stínu a režimu vyseknutí (známého také jako režim vystřižení).
Následující kód vytvoří pohyblivý symbol čtvercového rámečku a použije na něj filtr vrženého stínu:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 356
Filtrování objektů zobrazení
import flash.display.Sprite;
import flash.filters.DropShadowFilter;
// Draw a box.
var boxShadow:Sprite = new Sprite();
boxShadow.graphics.lineStyle(1);
boxShadow.graphics.beginFill(0xFF3300);
boxShadow.graphics.drawRect(0, 0, 100, 100);
boxShadow.graphics.endFill();
addChild(boxShadow);
// Apply the drop shadow filter to the box.
var shadow:DropShadowFilter = new DropShadowFilter();
shadow.distance = 10;
shadow.angle = 25;
// You can also set other properties, such as the shadow color,
// alpha, amount of blur, strength, quality, and options for
// inner shadows and knockout effects.
boxShadow.filters = [shadow];
Filtr záře
Třída GlowFilter použije na objekty zobrazení efekt osvětlení a vyvolá dojem, že světlo vychází zpod objektu a vytváří
tak jemnou záři.
Podobně jako u filtru vrženého stínu, zahrnuje filtr záře vlastnosti pro úpravu vzdálenosti, úhlu a barvy zdroje světla,
které vytvoří vlastní efekty. Filtr GlowFilter má také několik možností úprav stylu záře, včetně vnitřní a vnější záře a
režimu vyseknutí.
Následující kód vytvoří řez pomocí třídy Sprite a použije na něj filtr záře:
import flash.display.Sprite;
import flash.filters.BitmapFilterQuality;
import flash.filters.GlowFilter;
// Create a cross graphic.
var crossGraphic:Sprite = new Sprite();
crossGraphic.graphics.lineStyle();
crossGraphic.graphics.beginFill(0xCCCC00);
crossGraphic.graphics.drawRect(60, 90, 100, 20);
crossGraphic.graphics.drawRect(100, 50, 20, 100);
crossGraphic.graphics.endFill();
addChild(crossGraphic);
// Apply the glow filter to the cross shape.
var glow:GlowFilter = new GlowFilter();
glow.color = 0x009922;
glow.alpha = 1;
glow.blurX = 25;
glow.blurY = 25;
glow.quality = BitmapFilterQuality.MEDIUM;
crossGraphic.filters = [glow];
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 357
Filtrování objektů zobrazení
Filtr úkosu s přechodem
Třída GradientBevelFilter vám umožňuje použít pokročilý efekt zkosení na objekty zobrazení nebo na objekty
BitmapData. Použitím barvy přechodu na úkos výrazně vylepšíte prostorovou hloubku úkosu a hrany budou mít tak
realističtější 3D vzhled.
Následující kód vytvoří pomocí metody drawRect() třídy Shape obdélníkový objekt a použije na něj filtr úkosu s
přechodem.
import flash.display.Shape;
import flash.filters.BitmapFilterQuality;
import flash.filters.GradientBevelFilter;
// Draw a rectangle.
var box:Shape = new Shape();
box.graphics.lineStyle();
box.graphics.beginFill(0xFEFE78);
box.graphics.drawRect(100, 50, 90, 200);
box.graphics.endFill();
// Apply a gradient bevel to the rectangle.
var gradientBevel:GradientBevelFilter = new GradientBevelFilter();
gradientBevel.distance = 8;
gradientBevel.angle = 225; // opposite of 45 degrees
gradientBevel.colors = [0xFFFFCC, 0xFEFE78, 0x8F8E01];
gradientBevel.alphas = [1, 0, 1];
gradientBevel.ratios = [0, 128, 255];
gradientBevel.blurX = 8;
gradientBevel.blurY = 8;
gradientBevel.quality = BitmapFilterQuality.HIGH;
// Other properties let you set the filter strength and set options
// for inner bevel and knockout effects.
box.filters = [gradientBevel];
// Add the graphic to the display list.
addChild(box);
Filtr záře s přechodem
Třída GradientGlowFilter vám umožňuje použít pokročilý efekt záře na objekty zobrazení nebo na objekty
BitmapData. Tento efekt vám umožňuje lépe ovládat záři a vytváří tak realističtější efekt záře. Dále vám filtr záře s
přechodem umožňuje použít záři s přechodem na vnitřní, vnější nebo horní hrany objektu.
Následující příklad nakreslí na ploše čtverec a použije na něj filtr záře. Při posouvání myši dále doprava a dolů vzroste
množství rozostření v horizontálním, respektive vertikálním směru. Kdykoliv klepnete na plochu, intenzita rozostření
se zvýší.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 358
Filtrování objektů zobrazení
import
import
import
import
flash.events.MouseEvent;
flash.filters.BitmapFilterQuality;
flash.filters.BitmapFilterType;
flash.filters.GradientGlowFilter;
// Create a new Shape instance.
var shape:Shape = new Shape();
// Draw the shape.
shape.graphics.beginFill(0xFF0000, 100);
shape.graphics.moveTo(0, 0);
shape.graphics.lineTo(100, 0);
shape.graphics.lineTo(100, 100);
shape.graphics.lineTo(0, 100);
shape.graphics.lineTo(0, 0);
shape.graphics.endFill();
// Position the shape on the Stage.
addChild(shape);
shape.x = 100;
shape.y = 100;
// Define a gradient glow.
var gradientGlow:GradientGlowFilter = new GradientGlowFilter();
gradientGlow.distance = 0;
gradientGlow.angle = 45;
gradientGlow.colors = [0x000000, 0xFF0000];
gradientGlow.alphas = [0, 1];
gradientGlow.ratios = [0, 255];
gradientGlow.blurX = 10;
gradientGlow.blurY = 10;
gradientGlow.strength = 2;
gradientGlow.quality = BitmapFilterQuality.HIGH;
gradientGlow.type = BitmapFilterType.OUTER;
// Define functions to listen for two events.
function onClick(event:MouseEvent):void
{
gradientGlow.strength++;
shape.filters = [gradientGlow];
}
function onMouseMove(event:MouseEvent):void
{
gradientGlow.blurX = (stage.mouseX / stage.stageWidth) * 255;
gradientGlow.blurY = (stage.mouseY / stage.stageHeight) * 255;
shape.filters = [gradientGlow];
}
stage.addEventListener(MouseEvent.CLICK, onClick);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
Příklad: Kombinování základních filtrů
Následující příklad kódu používá několik základních filtrů kombinovaných s časovačem pro vytvoření opakujících se
akcí, za účelem vytvoření animované simulace dopravních světel.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 359
Filtrování objektů zobrazení
import
import
import
import
import
import
import
import
var
var
var
var
var
var
var
var
var
var
var
var
flash.display.Shape;
flash.events.TimerEvent;
flash.filters.BitmapFilterQuality;
flash.filters.BitmapFilterType;
flash.filters.DropShadowFilter;
flash.filters.GlowFilter;
flash.filters.GradientBevelFilter;
flash.utils.Timer;
count:Number = 1;
distance:Number = 8;
angleInDegrees:Number = 225; // opposite of 45 degrees
colors:Array = [0xFFFFCC, 0xFEFE78, 0x8F8E01];
alphas:Array = [1, 0, 1];
ratios:Array = [0, 128, 255];
blurX:Number = 8;
blurY:Number = 8;
strength:Number = 1;
quality:Number = BitmapFilterQuality.HIGH;
type:String = BitmapFilterType.INNER;
knockout:Boolean = false;
// Draw the rectangle background for the traffic light.
var box:Shape = new Shape();
box.graphics.lineStyle();
box.graphics.beginFill(0xFEFE78);
box.graphics.drawRect(100, 50, 90, 200);
box.graphics.endFill();
// Draw the 3 circles for the three lights.
var stopLight:Shape = new Shape();
stopLight.graphics.lineStyle();
stopLight.graphics.beginFill(0xFF0000);
stopLight.graphics.drawCircle(145,90,25);
stopLight.graphics.endFill();
var cautionLight:Shape = new Shape();
cautionLight.graphics.lineStyle();
cautionLight.graphics.beginFill(0xFF9900);
cautionLight.graphics.drawCircle(145,150,25);
cautionLight.graphics.endFill();
var goLight:Shape = new Shape();
goLight.graphics.lineStyle();
goLight.graphics.beginFill(0x00CC00);
goLight.graphics.drawCircle(145,210,25);
goLight.graphics.endFill();
// Add the graphics to the display list.
addChild(box);
addChild(stopLight);
addChild(cautionLight);
addChild(goLight);
// Apply a gradient bevel to the traffic light rectangle.
var gradientBevel:GradientBevelFilter = new GradientBevelFilter(distance, angleInDegrees,
colors, alphas, ratios, blurX, blurY, strength, quality, type, knockout);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 360
Filtrování objektů zobrazení
box.filters = [gradientBevel];
// Create the inner shadow (for lights when off) and glow
// (for lights when on).
var innerShadow:DropShadowFilter = new DropShadowFilter(5, 45, 0, 0.5, 3, 3, 1, 1, true,
false);
var redGlow:GlowFilter = new GlowFilter(0xFF0000, 1, 30, 30, 1, 1, false, false);
var yellowGlow:GlowFilter = new GlowFilter(0xFF9900, 1, 30, 30, 1, 1, false, false);
var greenGlow:GlowFilter = new GlowFilter(0x00CC00, 1, 30, 30, 1, 1, false, false);
// Set the starting state of the lights (green on, red/yellow off).
stopLight.filters = [innerShadow];
cautionLight.filters = [innerShadow];
goLight.filters = [greenGlow];
// Swap the filters based on the count value.
function trafficControl(event:TimerEvent):void
{
if (count == 4)
{
count = 1;
}
switch (count)
{
case 1:
stopLight.filters = [innerShadow];
cautionLight.filters = [yellowGlow];
goLight.filters = [innerShadow];
break;
case 2:
stopLight.filters = [redGlow];
cautionLight.filters = [innerShadow];
goLight.filters = [innerShadow];
break;
case 3:
stopLight.filters = [innerShadow];
cautionLight.filters = [innerShadow];
goLight.filters = [greenGlow];
break;
}
count++;
}
// Create a timer to swap the filters at a 3 second interval.
var timer:Timer = new Timer(3000, 9);
timer.addEventListener(TimerEvent.TIMER, trafficControl);
timer.start();
Filtr matice barev
Třída ColorMatrixFilter se používá k manipulaci barvy a alfa hodnot filtrovaného objektu. To vám umožňuje měnit
sytost, natočení odstínu (posunutí palety z jednoho rozpětí barvy do jiného), změny osvětlení na alfa a další práci s
barevnými efekty pomocí hodnot z jednoho barevného kanálu a potenciálně je použít na jiné kanály.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 361
Filtrování objektů zobrazení
Koncepčně filtr postupně prochází obrazovými body ve zdrojovém obrazu a rozděluje každý obrazový bod na jeho
komponenty červené, zelené, modré a alfa. Poté pracuje s hodnotami poskytnutými v matrici barev každou z těchto
hodnot, výsledky sečte a určí tak výslednou hodnotu barvy, která bude pro daný obrazový bod na obrazovce zobrazena.
Vlastnost matrix filtru je pole obsahující 20 čísel, která jsou použita při výpočtu výsledné barvy. Podrobnosti o
určitém algoritmu použitém k výpočtu hodnot barev naleznete v zápisu popisujícím vlastnost matrice třídy
ColorMatrixFilter v Referenční příručce jazyka ActionScript 3.0 a jeho komponent.
Další informace a příklady filtru matice barev naleznete v článku „ Používání matric pro transformace, úpravy barev
a efekty konvoluce v programu Flash“ na internetové stránce Adobe Developer Center.
Filtr konvoluce
Třídu ConvolutionFilter lze použít k aplikování širokého rozpětí transformací obrazů na objekty BitmapData nebo na
objekty zobrazení, například rozostření, detekce okraje, zostření, reliéf a úkos.
Filtr konvoluce koncepčně prochází postupně každým obrazovým bodem ve zdrojovém obraze a určí konečnou barvu
daného obrazového bodu pomocí hodnoty obrazového bodu a s ním sousedících bodů. Matice, specifikovaná jako
pole s numerickými hodnotami, určuje, do jaké míry hodnota každého určitého sousedícího obrazového bodu
ovlivňuje konečnou hodnotu.
Vezměte v úvahu nejběžněji používaný typ matice, kterou je matice tři x tři. Matice obsahuje devět hodnot:
N
N
N
N
P
N
N
N
N
Jestliže přehrávač Flash Player nebo program AIR použije filtr konvoluce na určitý obrazový bod, zaměří se na
hodnotu barvy samotného obrazového bodu (v příkladu označeno jako „P“), i na hodnoty okolních obrazových bodů
(v příkladu označeno jako „N“). Nicméně nastavením hodnot v matrici můžete určit, jakou prioritu mají určité
obrazové body v ovlivňování výsledného obrazu.
Například následující matice použitá pomocí filtru konvoluce zachová obraz ve stejné podobně, jakou měl dříve:
0
0
0
0
1
0
0
0
0
Důvod, proč je obraz nezměněn, je, že původní hodnota obrazového bodu má v určení konečné barvy obrazového
bodu relativní sílu 1, zatímco hodnoty okolních obrazových bodů mají relativní sílu 0 - což znamená, že jejich barvy
neovlivňují výsledný obraz.
Podobně tato matice způsobí posun obrazových bodů obrazu o jeden obrazový bod doleva:
0
0
0
0
0
0
0
1
0
Všimněte si, že v tomto případě nemá samotný obrazový bod žádný vliv na výslednou hodnotu obrazového bodu
zobrazeného v daném umístění na výsledném obrazu - hodnota obrazového bodu napravo je pouze použita pro určení
výsledné hodnoty obrazového bodu.
V jazyku ActionScript vytvoříte matici jako kombinaci instance Array obsahující hodnoty a dvou vlastností
obsahujících počet řádků a sloupců v matici. Následující příklad načte obraz a po dokončení načítání obrazu použije
na obraz filtr konvoluce pomocí matice v předchozí ukázce:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 362
Filtrování objektů zobrazení
// Load an image onto the Stage.
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image1.jpg");
loader.load(url);
this.addChild(loader);
function applyFilter(event:MouseEvent):void
{
// Create the convolution matrix.
var matrix:Array = [0, 0, 0,
0, 0, 1,
0, 0, 0];
var convolution:ConvolutionFilter = new ConvolutionFilter();
convolution.matrixX = 3;
convolution.matrixY = 3;
convolution.matrix = matrix;
convolution.divisor = 1;
loader.filters = [convolution];
}
loader.addEventListener(MouseEvent.CLICK, applyFilter);
V tomto kódu není efekt použití hodnot v matici jiných než 1 nebo 0 zřejmý. Například stejná matice s číslem 8
namísto čísla 1 v pozici napravo provede stejnou akci (posunutí obrazových bodů doleva). Dále ovlivní barvy obrazu,
které budou osmkrát jasnější. Důvodem je vypočtení výsledných hodnot barvy obrazových bodů vynásobením hodnot
matice barvami původního obrazového bodu, sečtením hodnot a dělením hodnotou vlastnosti filtru divisor.
Všimněte si, že v daném příklad kódu je vlastnost divisor nastavena na 1. Obecné pravidlo zní, že pokud si přejete,
aby jas barev zůstal stejný jako v původním obraze, měl by se dělitel rovnat součtu hodnot matice. Takže v případě
matice, kde součet hodnot představuje 8 a dělitel má hodnotu 1, bude výsledný obraz přibližně 8krát jasnější než
původní obraz.
Ačkoliv není efekt této matice dobře viditelný, jiné hodnoty matice lze použít pro vytvoření různých efektů. Zde je
několik standardních sad hodnot matric pro odlišné efekty použitím matice tři krát tři:
• Základní rozostření (dělitel 5):
0 1 0
1 1 1
0 1 0
• Zaostření (dělitel 1):
0, -1, 0
-1, 5, -1
0, -1, 0
• Detekce okrajů (dělitel 1):
0, -1, 0
-1, 4, -1
0, -1, 0
• Efekt reliéfu (dělitel 1):
-2, -1, 0
-1, 1, 1
0, 1, 2
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 363
Filtrování objektů zobrazení
Všimněte si, že u většiny z těchto efektů je dělitel 1. Důvodem je to, že záporné hodnoty matice jsou přidány ke
kladným hodnotám matice a výsledek bude 1 (nebo 0 v případě detekce okrajů, ale hodnota vlastnosti divisor
nemůže být 0).
Filtr mapy přestavění
Třída DisplacementMapFilter používá hodnoty obrazových bodů z objektu BitmapData (známého jako obrazová
mapa přemístění) k provedení efektu přemístění na novém objektu. Obraz mapy přestavění je obvykle odlišný od
skutečného objektu zobrazení nebo instance BitmapData, na kterou se filtr použije. Efekt přestavění obsahuje
vychýlení obrazových bodů v daném filtrovaném obrazu - jinými slovy, do určité míry přesun obrazových hodnot
mimo jejich původní umístění. Tento filtr lze použít pro vytvoření posunutého a pokřiveného efektu, či efektu skvrn.
Umístění a množství přestavění použitého na daný obrazový bod je určeno hodnotou barvy obrazu mapy přestavění.
Při práci s filtrem určujete pro ovládání způsobu výpočtu přestavění z obrazu mapy vedle určení obrazu mapy
následující hodnoty:
• Bod mapy: Umístění na filtrovaném obrazu, kde se použije filtr přestavění horního levého rohu. Toho můžete
využít, pouze pokud si přejete filtr použít na část obrazu.
• Komponenta X: Jaký barevný kanál snímku mapy ovlivňuje polohu x obrazových bodů.
• Komponenta Y: Jaký barevný kanál snímku mapy ovlivňuje polohu y obrazových bodů.
• Měřítko X: Hodnota násobitele, která určuje, jak silné je přestavění osy x.
• Měřítko Y: Hodnota násobitele, která určuje, jak silné je přestavění osy y.
• Režim filtru: Určuje, co by měl přehrávač Flash Player nebo program AIR udělat v jakýchkoliv prázdných
prostorech vytvořených posunem obrazových bodů mimo. Tyto možnosti, definované jako konstanty ve třídě
DisplacementMapFilterMode, jsou určeny k zobrazení původních obrazových bodů (režim filtru IGNORE), pro
zabalení obrazových bodů ze druhé strany obrazu (režim filtru WRAP, který je implicitní), pro použití nejbližšího
posunutého obrazového bodu (režim filtru CLAMP), nebo pro vyplnění míst barvou (režim filtru COLOR).
K pochopení, jak filtr mapy přemístění pracuje, si všimněte následujícího příkladu. V následujícím kódu je načten
obraz a jakmile se stahování dokončí, je obraz vycentrován na ploše a je na něj použita mapa přestavěná, která způsobí
celkový horizontální posun celého obrazu doleva.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 364
Filtrování objektů zobrazení
import
import
import
import
import
import
flash.display.BitmapData;
flash.display.Loader;
flash.events.MouseEvent;
flash.filters.DisplacementMapFilter;
flash.geom.Point;
flash.net.URLRequest;
// Load an image onto the Stage.
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image3.jpg");
loader.load(url);
this.addChild(loader);
var mapImage:BitmapData;
var displacementMap:DisplacementMapFilter;
// This function is called when the image finishes loading.
function setupStage(event:Event):void
{
// Center the loaded image on the Stage.
loader.x = (stage.stageWidth - loader.width) / 2;
loader.y = (stage.stageHeight - loader.height) / 2;
// Create the displacement map image.
mapImage = new BitmapData(loader.width, loader.height, false, 0xFF0000);
// Create the displacement filter.
displacementMap = new DisplacementMapFilter();
displacementMap.mapBitmap = mapImage;
displacementMap.mapPoint = new Point(0, 0);
displacementMap.componentX = BitmapDataChannel.RED;
displacementMap.scaleX = 250;
loader.filters = [displacementMap];
}
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, setupStage);
Vlastnosti použité k definování přestavění jsou následující:
• Bitmapa mapy: Bitmapa přestavění je nová instance BitmapData vytvořená kódem. Její rozměry odpovídají
rozměrům načteného obrazu (přestavění je tedy použito na celý obraz). Obraz je vyplněn plnými červenými
obrazovými body.
• Bod mapy: Tato hodnota je nastavena na bod 0, 0 - a opět způsobí, že přestavění je použito na celý snímek.
• Komponenta X: Tato hodnota je nastavena na konstantu BitmapDataChannel.RED, což znamená, že červená
hodnota bitmapy mapy určí, kolik obrazových bodů bude vychýleno (jak moc se pohybují) podél osy x.
• Měřítko x: Tato hodnota je nastavena na 250. Úplné množství přestavění (z obrazu mapy, který je úplně červený)
vychýlí snímek pouze o malé množství (přibližně o polovinu obrazového bodu), takže pokud je tato hodnota
nastavena na 1, obraz se posune pouze o 0,5 obrazových bodů horizontálně. Nastavením této hodnoty na 250 se
obraz posune přibližně o 125 obrazových bodů.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 365
Filtrování objektů zobrazení
Toto nastavení způsobí posun obrazových bodů filtrovaného obrazu o 250 obrazových bodů doleva. Směr (vlevo nebo
vpravo) a míra posunutí je určen hodnotou barvy obrazových bodů v obrazu mapy. Přehrávač Flash Player nebo
program AIR koncepčně postupně projde obrazové body filtrovaného snímku (minimálně obrazové body v oblasti,
kde je filtr použit, což v tomto případě znamená všechny obrazové body) a s každým obrazovým bodem provede
následující:
1 Nalezne odpovídající obrazový bod v obrazu mapy. Například jestliže přehrávač Flash Player nebo program AIR
vypočítává míru přestavění pro obrazové body v horním levém rohu filtrovaného snímku, zaměří se na obrazové
body v levém horním rohu obrazu mapy.
2 Určuje hodnotu specifikovaného barevného kanálu v obrazovém bodu mapy. V tomto případě je barevný kanál
komponenty x červeným kanálem, takže přehrávač Flash Player a program AIR zjistí, která hodnota červeného
kanálu obrazu mapy je daný obrazový bod. Protože je obraz mapy plný červený, červený kanál obrazového bodu je
0xFF nebo 255. To je použito jako hodnota přestavění.
3 Porovná hodnotu přestavění se „středovou“ hodnotou (127, která je vždy v půlce mezi 0 a 255). Jestliže je hodnota
přestavění nižší než středová hodnota, obrazový bod se posune kladným směrem (napravo pro přestavění x; dolů
pro přestavění y). Je-li na druhou stranu hodnota přestavění vyšší než střední hodnota (jako v tomto příkladě),
posune se obrazový bod záporným směrem (doleva pro přestavění x; nahoru pro přestavění y). Přesněji, přehrávač
Flash Player a program AIR odečtou hodnotu přestavění od 127 a výsledkem (kladným nebo záporným) je
poměrná hodnota přestavění, která je použita.
4 Nakonec určí skutečnou hodnotu posunu určením toho, jaké procento plného posunu představuje relativní
hodnota posunu. V tomto případě znamená plná červená 100% posun. Toto procento je poté vynásobeno
hodnotou stupnice x nebo y pro určení počtu obrazových bodů posunu, který bude použit. V tomto příkladě, 100%
krát dělitel 250 určuje množství posunu - přibližně 125 obrazových bodů vlevo.
Protože pro komponentu y a stupnici y nejsou určeny žádné hodnoty, použijí se hodnoty výchozí (které nevyvolají
žádný posun)—to je důvod, proč se obraz ve vertikálním směru vůbec neposune.
V příkladě je použito výchozí nastavení režimu filtru, WRAP, takže jakmile se obrazové body posunou doleva, prázdné
místo napravo se vyplní obrazovými body, které posunuly pravý okraj obrazu. S touto hodnotou můžete
experimentovat a zobrazit tak různé efekty. Pokud například přidáte následující řádek k části kódu, kde jsou
nastavovány vlastnosti posunu (před řádek loader.filters = [displacementMap]), bude obraz vypadat, jako by
byl rozmazán přes plochu:
displacementMap.mode = DisplacementMapFilterMode.CLAMP;
U složitějšího případu ukazuje následující ukázka filtr mapy posunu pro vytvoření efektu skla na obraze:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 366
Filtrování objektů zobrazení
import
import
import
import
import
import
import
import
import
import
import
import
flash.display.Bitmap;
flash.display.BitmapData;
flash.display.BitmapDataChannel;
flash.display.GradientType;
flash.display.Loader;
flash.display.Shape;
flash.events.MouseEvent;
flash.filters.DisplacementMapFilter;
flash.filters.DisplacementMapFilterMode;
flash.geom.Matrix;
flash.geom.Point;
flash.net.URLRequest;
// Create the gradient circles that will together form the
// displacement map image
var radius:uint = 50;
var type:String = GradientType.LINEAR;
var redColors:Array = [0xFF0000, 0x000000];
var blueColors:Array = [0x0000FF, 0x000000];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var xMatrix:Matrix = new Matrix();
xMatrix.createGradientBox(radius * 2, radius * 2);
var yMatrix:Matrix = new Matrix();
yMatrix.createGradientBox(radius * 2, radius * 2, Math.PI / 2);
var xCircle:Shape = new Shape();
xCircle.graphics.lineStyle(0, 0, 0);
xCircle.graphics.beginGradientFill(type, redColors, alphas, ratios, xMatrix);
xCircle.graphics.drawCircle(radius, radius, radius);
var yCircle:Shape = new Shape();
yCircle.graphics.lineStyle(0, 0, 0);
yCircle.graphics.beginGradientFill(type, blueColors, alphas, ratios, yMatrix);
yCircle.graphics.drawCircle(radius, radius, radius);
// Position the circles at the bottom of the screen, for reference.
this.addChild(xCircle);
xCircle.y = stage.stageHeight - xCircle.height;
this.addChild(yCircle);
yCircle.y = stage.stageHeight - yCircle.height;
yCircle.x = 200;
// Load an image onto the Stage.
var loader:Loader = new Loader();
var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image1.jpg");
loader.load(url);
this.addChild(loader);
// Create the map image by combining the two gradient circles.
var map:BitmapData = new BitmapData(xCircle.width, xCircle.height, false, 0x7F7F7F);
map.draw(xCircle);
var yMap:BitmapData = new BitmapData(yCircle.width, yCircle.height, false, 0x7F7F7F);
yMap.draw(yCircle);
map.copyChannel(yMap, yMap.rect, new Point(0, 0), BitmapDataChannel.BLUE,
BitmapDataChannel.BLUE);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 367
Filtrování objektů zobrazení
yMap.dispose();
// Display the map image on the Stage, for reference.
var mapBitmap:Bitmap = new Bitmap(map);
this.addChild(mapBitmap);
mapBitmap.x = 400;
mapBitmap.y = stage.stageHeight - mapBitmap.height;
// This function creates the displacement map filter at the mouse location.
function magnify():void
{
// Position the filter.
var filterX:Number = (loader.mouseX) - (map.width / 2);
var filterY:Number = (loader.mouseY) - (map.height / 2);
var pt:Point = new Point(filterX, filterY);
var xyFilter:DisplacementMapFilter = new DisplacementMapFilter();
xyFilter.mapBitmap = map;
xyFilter.mapPoint = pt;
// The red in the map image will control x displacement.
xyFilter.componentX = BitmapDataChannel.RED;
// The blue in the map image will control y displacement.
xyFilter.componentY = BitmapDataChannel.BLUE;
xyFilter.scaleX = 35;
xyFilter.scaleY = 35;
xyFilter.mode = DisplacementMapFilterMode.IGNORE;
loader.filters = [xyFilter];
}
// This function is called when the mouse moves. If the mouse is
// over the loaded image, it applies the filter.
function moveMagnifier(event:MouseEvent):void
{
if (loader.hitTestPoint(loader.mouseX, loader.mouseY))
{
magnify();
}
}
loader.addEventListener(MouseEvent.MOUSE_MOVE, moveMagnifier);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 368
Filtrování objektů zobrazení
Kód nejprve vygeneruje dva přechodové kruhy, které jsou zkombinovány a vytvářejí obraz mapy přestavění. Červený
kruh vytvoří přestavění osy x xyFilter.componentX = BitmapDataChannel.RED) a modrý kruh vytvoří přestavění
osy y(xyFilter.componentY = BitmapDataChannel.BLUE). Abyste pochopili, jak obraz mapy přestavění vypadá,
přidá kód původní kruhy i kombinovaný kruh, který slouží jako obraz mapy na spodní část obrazovky.
Kód poté načte obraz a při pohybu myší použije filtr přestavění na část obrazu, která leží pod myší. Přechodové kruhy
použité jako obraz mapy přestavění způsobí, že se oblast přestavění rozšíří směrem od kurzoru myši. Všimněte si, že
šedé oblasti obrazu mapy přestavění žádné přestavění nezpůsobí. Šedá barva je 0x7F7F7F. Modré a červené kanály
daného odstínu šedé přesně odpovídají střednímu odstínu těchto barevných kanálů, takže v šedé oblasti obrazu mapy
nedojde k žádnému přestavění. Podobně také ve středu kruhu nedojde k žádnému přestavění. Ačkoliv barva není šedá,
modrý a červený kanál dané barvy jsou identické s modrým a červeným kanálem středně šedé, a protože jsou modrá
a červená barvy, které způsobují přestavění, nedojde zde k žádnému přestavění.
Filtr clony
Třída ShaderFilter vám umožňuje použít vlastní efekt filtru definovaný jako shader Pixel Bender. Protože je daný filtr
zapsán jako clona Pixel Bender, daný efekt lze kompletně upravit dle potřeby. Filtrovaný obsah je předán do clony jako
vstup obrazu a výsledek operace clony se stane výsledkem filtru.
Poznámka: Filtr clony je dostupný od verzí Flash Player 10 a Adobe AIR 1.5.
Pro použití filtru clony na objekt nejprve vytvořte instanci Shader reprezentující clonu Pixel Bender, kterou používáte.
Více podrobností o postupu vytvoření instance Shader a o způsobu určení vstupního obrazu a hodnot parametru
naleznete v části „Práce s shadery Pixel Bender“ na stránce 376.
Při používání clony jako filtru si je třeba zapamatovat tři důležité věci:
• Clona musí být definována tak, aby přijala minimálně jeden vstupní obraz.
• Filtrovaný objekt (objekt zobrazení nebo objekt BitmapData, na který je daný filtr použit) je předán ke cloně jako
první hodnota vstupního obrazu. Z tohoto důvodu byste neměli ručně určit hodnotu pro první vstup obrazu.
• Jestliže clona definuje více než jeden vstupní obraz, dodatečné vstupy musí být specifikovány ručně (tj. nastavením
vlastnosti input libovolné instance ShaderInput, která patří k instanci Shader).
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 369
Filtrování objektů zobrazení
Jakmile máte objekt Shader pro vaši clonu, vytvoříte instanci ShaderFilter. Jedná se o skutečný objekt filtru, který
používáte jako všechny ostatní filtry. Pro vytvoření ShaderFilter, který používá objekt Shader, volejte konstruktor
ShaderFilter() a předejte objekt Shader jako argument, viz. následující ukázka:
var myFilter:ShaderFilter = new ShaderFilter(myShader);
Kompletní příklad používání filtru shaderu naleznete v tématu „Použití shaderu jako filtru“ na stránce 393.
Příklad: Filter Workbench
Aplikace Filter Workbench poskytuje uživatelské rozhraní pro použití různých filtrů na obrazy a jiný vizuální obsah a
zobrazení výsledného kódu, který lze použít pro vytvoření stejného efektu v jazyce ActionScript. Vedle poskytování
nástroje pro pokusy s filtry, tato aplikace ukazuje následující techniky:
• Vytváření instancí různých filtrů
• Používání více filtrů na objekt zobrazení
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace Filter Workbench lze nalézt ve složce Samples/FilterWorkbench. Aplikace sestává z následujících
souborů:
Soubor
Popis
com/example/programmingas3/filterWorkbench/FilterWorkbenchController.as
Třída, která poskytuje hlavní funkce aplikace, včetně
přepínání obsahu, na který jsou soubory použity a
používání filtrů na obsah.
com/example/programmingas3/filterWorkbench/IFilterFactory.as
Rozhraní definující společné metody, které jsou
implementovány každou ze tříd rodiny filtru. Toto
rozhranní definuje společné funkce, které třída
FilterWorkbenchController používá pro interakci s
jednotlivými třídami rodiny filtrů.
ve složce com/example/programmingas3/filterWorkbench/:
Sada tříd, kde každá z nich implementuje rozhraní
IFilterFactory. Každá z těchto tříd poskytuje funkce
vytváření a nastavování hodnot pro jediný typ filtru.
Panely vlastnosti filtru v aplikaci používají tyto třídy
rodiny pro vytváření instancí svých určitých filtrů,
které třída FilterWorkbenchController dosazuje a
používá na obsah obrazu.
BevelFactory.as
BlurFactory.as
ColorMatrixFactory.as
ConvolutionFactory.as
DropShadowFactory.as
GlowFactory.as
GradientBevelFactory.as
GradientGlowFactory.as
com/example/programmingas3/filterWorkbench/IFilterPanel.as
Rozhranní definující společné metody
implementované třídami definující panely rozhraní
uživatele, které jsou použity pro manipulaci
hodnotami filtrů v dané aplikaci.
com/example/programmingas3/filterWorkbench/ColorStringFormatter.as
Třída utility, která zahrnuje metodu pro převedení
numerické hodnoty barvy na hexadecimální formát
řetězce.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 370
Filtrování objektů zobrazení
Soubor
Popis
com/example/programmingas3/filterWorkbench/GradientColor.as
Třída, která slouží jako objekt hodnoty, kombinuje
do jediného objektu tři hodnoty (barva, alfa a
poměr), které jsou spojeny s každou barvou v
GradientBevelFilter a GradientGlowFilter
Uživatelské rozhraní (Flash)
FilterWorkbench.fla
Hlavní soubor definující uživatelské rozhraní
aplikace.
flashapp/FilterWorkbench.as
Třída, která poskytuje funkce pro hlavní uživatelské
rozhraní aplikace; tato třída je používána jako třída
dokumentu pro soubor FLA aplikace.
Ve složce flashapp/filterPanels:
Sada tříd, která poskytuje funkci pro každý panel
použitý při nastavení voleb pro jediný filtr.
BevelPanel.as
BlurPanel.as
ColorMatrixPanel.as
ConvolutionPanel.as
DropShadowPanel.as
Pro každou třídu také existuje přidružený symbol
MovieClip v knihovně hlavního souboru aplikace
FLA, jehož název odpovídá názvu dané třídy
(například symbol „BlurPanel“ je propojen s třídou
definovanou v BlurPanel.as). Komponenty
vytvářející uživatelské rozhraní jsou umístěny a
pojmenovány v rámci těchto symbolů.
GlowPanel.as
GradientBevelPanel.as
GradientGlowPanel.as
flashapp/ImageContainer.as
Objekt zobrazení, který slouží jako kontejner pro
načtený snímek na obrazovce.
flashapp/BGColorCellRenderer.as
Vlastní objekt pro vykreslení buňky použitý pro
změnu barvy pozadí buňky v komponentě DataGrid
flashapp/ButtonCellRenderer.as
Vlastní objekt pro vykreslení buňky použitý pro
zahrnutí komponenty tlačítka do buňky v
komponentě DataGrid
Obsah filtrovaného snímku
com/example/programmingas3/filterWorkbench/ImageType.as
Tato třída slouží jako objekt hodnoty obsahující typ
a URL jediného souboru obrazu, který může aplikace
načíst a na který může použít filtry. Třída také
obsahuje sadu konstant reprezentujících skutečné
dostupné soubory obrazu.
images/sampleAnimation.swf,
Obrazy a jiný vizuální obsah, na který jsou filtry v
aplikaci použity.
images/sampleImage1.jpg,
images/sampleImage2.jpg
Experimentování s filtry jazyka ActionScript
Aplikace Filter Workbench je navržena tak, aby vám pomohla při pokusech s různými efekty filtrů a vytváření
relevantního kódu jazyka ActionScript pro daný efekt. Aplikace vám umožňuje výběr ze tří odlišných souborů
zahrnujících vizuální obsah, včetně obrazů bitmap a animace vytvořené nástrojem Flash, a použití osmi odlišných
filtrů jazyka ActionScript na zvolený obraz, a to buď jednotlivě nebo v kombinaci s jinými filtry. Aplikace zahrnuje
následující filtry:
• Úkos (flash.filters.BevelFilter)
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 371
Filtrování objektů zobrazení
• Rozostření (flash.filters.BlurFilter)
• Matice barvy (flash.filters.ColorMatrixFilter)
• Konvoluce (flash.filters.ConvolutionFilter)
• Vržený stín (flash.filters.DropShadowFilter)
• Záře (flash.filters.GlowFilter)
• Úkos s přechodem (flash.filters.GradientBevelFilter)
• Záře s přechodem (flash.filters.GradientGlowFilter)
Jakmile uživatel vybere obraz a filtr, který bude na daný obraz použit, aplikace zobrazí panel s ovládáním pro nastavení
specifických vlastností zvoleného filtru. Například následující obraz zobrazí aplikaci s vybraným filtrem úkosu:
Jakmile uživatel nastaví vlastnosti filtru, náhled se aktualizuje v reálném čase. Uživatel může také použít více filtrů, a
to vlastním nastavením jednoho filtru, klepnutím na tlačítko Použít, vlastním nastavením jiného filtru, klepnutím na
tlačítko Použít, atd.
Na panelech filtrů aplikace existuje několik funkcí a omezení:
• Filtr matice barev zahrnuje sadu ovládání pro přímé zpracovávání společných vlastností obrazu včetně jasu,
kontrastu, sytosti a odstínu. Dále lze určit vlastní hodnoty matice barev.
• Filtr konvoluce, který je dostupný pouze pomocí jazyka ActionScript, zahrnuje sadu běžně používaných hodnot
matice konvoluce, nebo můžete určit vlastní hodnoty. Nicméně zatímco třída ConvolutionFilter přijímá matici
libovolné velikosti, aplikace Filter Workbench používá fixní matici 3 x 3, nejběžněji používanou velikost filtru.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 372
Filtrování objektů zobrazení
• Filtr mapy přestavění a filtr clony, které jsou dostupné pouze v jazyku ActionScript, nejsou dostupné v aplikaci
Filter Workbench. Filtr mapy přestavění vyžaduje vedle obsahu filtrovaného obrazu mapu obrazu. Obraz mapy
filtru mapy přestavění je primární výstup, který určuje výsledek filtru, takže bez schopnosti načíst nebo vytvořit
obraz mapy by byla schopnost experimentovat s filtrem mapy přestavění velice omezená. Podobně filtr clony
vyžaduje vedle obsahu filtrovaného obsahu bytový kód Pixel Bender. Bez schopnosti načíst bytový kód clony je
nemožné filtr clony použít.
Vytváření instancí filtrů
Aplikace Filter Workbench obsahuje sadu tříd, jednu pro každý z dostupných filtrů, které jsou použity jednotlivými
panely pro vytvoření filtrů. Když uživatel vybere filtr, kód jazyka ActionScript připojený k panelu filtru vytvoří instanci
příslušné třídy rodiny filtru. (Tyto třídy jsou známé jako factory classes, protože jejich účelem je vytvoření instancí
jiných objektů, stejně jako továrny v reálném světě vytvářejí jednotlivé produkty.)
Kdykoliv uživatel změní hodnotu vlastnosti na panelu, kód panelu volá příslušnou metodu ve třídě rodiny. Každá třída
rodiny zahrnuje specifické metody, které panel používá pro vytvoření instance příslušného filtru. Jestliže uživatel
například vybere filtr rozostření, aplikace vytvoří instanci BlurFactory. Třída BlurFactory zahrnuje metodu
modifyFilter(), která přijímá tři parametry: blurX, blurYa quality, které jsou dohromady použity pro vytvoření
požadované instance BlurFilter:
private var _filter:BlurFilter;
public function modifyFilter(blurX:Number = 4, blurY:Number = 4, quality:int = 1):void
{
_filter = new BlurFilter(blurX, blurY, quality);
dispatchEvent(new Event(Event.CHANGE));
}
Jestliže uživatel naopak vybere filtr konvoluce, daný filtr umožní o mnoho větší flexibilitu a následně nabízí větší sadu
vlastností k ovládání. Když uživatel vybere na panelu filtru odlišnou hodnotu, je ve třídě ConvolutionFactory volán
následující kód:
private var _filter:ConvolutionFilter;
public function modifyFilter(matrixX:Number = 0,
matrixY:Number = 0,
matrix:Array = null,
divisor:Number = 1.0,
bias:Number = 0.0,
preserveAlpha:Boolean = true,
clamp:Boolean = true,
color:uint = 0,
alpha:Number = 0.0):void
{
_filter = new ConvolutionFilter(matrixX, matrixY, matrix, divisor, bias, preserveAlpha,
clamp, color, alpha);
dispatchEvent(new Event(Event.CHANGE));
}
Všimněte si, že v každém případě změny hodnot filtru, odešle objekt rodiny událost Event.CHANGE a upozorní tak
posluchače, že hodnoty filtru byly změněny. Třída FilterWorkbenchController, která vlastně používá filtry na
filtrovaný obsah, poslouchá danou událost pro zjištění, kdy musí získat novou kopii filtru a znovu jí použít na
filtrovaný obsah.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 373
Filtrování objektů zobrazení
Třída FilterWorkbenchController nepotřebuje znát specifické detaily každé třídy rodiny filtru - potřebuje pouze vědět,
že se filtr změnil a musí být schopna získat přístup ke kopii filtru. Proto aplikace obsahuje rozhraní IFilterFactory
definující chování, které třída rodiny filtru musí poskytnout, aby mohla instance aplikace FilterWorkbenchController
provést svoji funkci. IFilterFactory definuje metodu getFilter(), která je použita ve třídě
FilterWorkbenchController:
function getFilter():BitmapFilter;
Všimněte si, že definice metody rozhraní getFilter() určuje, že metoda vrátí instanci BitmapFilter, spíše než
specifický typ filtru. Třída BitmapFilter nedefinuje specifický typ filtru. BitmapFilter je spíše základní třídou, na které
jsou všechny filtry vystavěny. Každá třída rodiny filtru definuje specifickou implementaci metody getFilter(), ve
které metoda vrátí referenci na daný objekt filtru, který vytvořila. Zde je například zkrácená verze zdrojového kódu
třídy ConvolutionFactory:
public class ConvolutionFactory extends EventDispatcher implements IFilterFactory
{
// ------- Private vars ------private var _filter:ConvolutionFilter;
...
// ------- IFilterFactory implementation ------public function getFilter():BitmapFilter
{
return _filter;
}
...
}
V implementaci třídy ConvolutionFactory metody getFilter() vrátí instanci ConvolutionFilter, ačkoliv libovolný
objekt volající metodu getFilter() nemusí nutně vědět, že - podle definice metody getFilter(), která následuje
ConvolutionFactory, musí vrátit libovolnou instanci BitmapFilter, což by mohla být instance libovolné třídy jazyka
ActionScript.
Používání filtrů na objekty zobrazení
Jak bylo vysvětleno v předchozí části, aplikace Workbench používá instanci třídy FilterWorkbenchController (dále
uváděnou jako „instance ovladače“), která provádí skutečnou úlohu použití filtrů na vybraný vizuální objekt. Před tím,
než může instance kontroleru použít filtr, potřebuje nejprve znát, na který obraz nebo vizuální obsah by měl být filtr
použit. Když uživatel vybere obraz, aplikace volá metodu setFilterTarget() ve třídě FilterWorkbenchController a
předá jednu z konstant definovanou ve třídě ImageType:
public function setFilterTarget(targetType:ImageType):void
{
...
_loader = new Loader();
...
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, targetLoadComplete);
...
}
Pomocí dané informace načte instance ovladače určený soubor a jakmile se načte, uchová jej v proměnné instance
pojmenované _currentTarget:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 374
Filtrování objektů zobrazení
private var _currentTarget:DisplayObject;
private function targetLoadComplete(event:Event):void
{
...
_currentTarget = _loader.content;
...
}
Když uživatel vybere filtr, aplikace volá metodu ovladače instance setFilter() a předá ovladači referenci na
příslušný objekt rodiny filtru, kterou uchovává v proměnné instance pojmenované _filterFactory.
private var _filterFactory:IFilterFactory;
public function setFilter(factory:IFilterFactory):void
{
...
_filterFactory = factory;
_filterFactory.addEventListener(Event.CHANGE, filterChange);
}
Všimněte si, že jak již bylo popsáno výše, instance ovladače nezná určitý datový typ instance rodiny filtru, který je
zadán; instance ovladače pouze ví, že daný objekt implementuje instanci IFilterFactory, což znamená, že má metodu
getFilter() a při změně filtru odesílá událost change (Event.CHANGE).
Když uživatel změní vlastnosti filtru na panelu filtrů, instance ovladače zjistí, že se filtr změnil pomocí události rodiny
filtru change, která volá metodu instance ovladače filterChange(). Daná metoda naopak volá metodu
applyTemporaryFilter():
private function filterChange(event:Event):void
{
applyTemporaryFilter();
}
private function applyTemporaryFilter():void
{
var currentFilter:BitmapFilter = _filterFactory.getFilter();
// Add the current filter to the set temporarily
_currentFilters.push(currentFilter);
// Refresh the filter set of the filter target
_currentTarget.filters = _currentFilters;
// Remove the current filter from the set
// (This doesn't remove it from the filter target, since
// the target uses a copy of the filters array internally.)
_currentFilters.pop();
}
K použití filtru na objekt zobrazení dochází v rámci metody applyTemporaryFilter(). Ovladač nejprve získá
referenci na objekt filtru vyvoláním metody rodiny filtru getFilter().
var currentFilter:BitmapFilter = _filterFactory.getFilter();
Instance ovladače má proměnnou instance Array pojmenovanou _currentFilters, ve které uchovává všechny filtry,
které byly na objekt zobrazení použity. Dalším krokem je přidání nově aktualizovaného filtru do daného pole:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 375
Filtrování objektů zobrazení
_currentFilters.push(currentFilter);
Dále kód přiřadí pole filtrů vlastnosti objektu zobrazení filters, která vlastně dané filtry použije na obraz:
_currentTarget.filters = _currentFilters;
Nakonec, protože je tento nejnověji přidaný filtr stále aktivním filtrem, neměl by být permanentně použit na objekt
zobrazení a je tedy odstraněn z pole _currentFilters:
_currentFilters.pop();
Odstranění tohoto filtru z pole neovlivní filtrovaný objekt zobrazení, protože objekt zobrazení vytvoří při přiřazení k
vlastnosti filters kopii pole filtrů a použije dané interní pole spíše než pole původní. Z tohoto důvodu neovlivní
žádné změny provedené v poli filtrů objekt zobrazení, pokud dané pole není opět přiřazeno vlastnosti objektu
zobrazení filters.
376
Kapitola 17: Práce s shadery Pixel Bender
Sada nástrojů Adobe Pixel Bender umožňuje vývojovým pracovníkům psát shadery, které vytvářejí grafické efekty a
provádějí jiná zpracování obrazů a dat. Bytový kód sady Pixel Bender lze provést v jazyku ActionScript k použití efektu
na obrazová data nebo vizuální obsah. Použití shaderů Pixel Bender v jazyku ActionScript vám poskytne kapacitu pro
vytváření vlastních vizuálních efektů a provádění zpracování dat přesahující vestavěné schopnosti jazyka ActionScript.
Poznámka: Podpora sady nástrojů Pixel Bender je dostupná od verzí Flash Player 10 a Adobe AIR 1.5.
Základy shaderů Pixel Bender
Úvod k práci se shadery Pixel Bender
Adobe Pixel Bender je programovací jazyk, který se používá k vytvoření nebo manipulaci obsahem obrazu. Pomocí
jazyka Pixel Bender vytvoříte jádro, kterému se v tomto dokumentu také říká shader. Shader definuje jedinou funkci,
která je provedena na každém obrazovém bodu obrazu individuálně. Výsledek každého volání funkce je výstupní
barva na zadaných souřadnicích obrazového bodu v obraze. Vstupní hodnoty obrazů a parametrů lze určit k vlastní
úpravě operace. V jediném provedení shaderu jsou vstupní hodnoty a hodnoty parametru konstantní. Jediná věc, která
se mění, je souřadnice obrazového bodu, jehož barva je výsledkem volání funkce.
Pokud je to možné, funkce shaderu je volána pro více výstupních souřadnic obrazového pole paralelně. Tím dojde k
vylepšení výkonu shaderu a můžete využít zpracovávání s vysokým výkonem.
V programech Flash Player a Adobe AIR lze pomocí shaderu snadno vytvořit tři typy efektů.
• Výplň kresby
• režim prolnutí
• filtr
Shader lze také provést v nezávislém režimu. Pomocí nezávislého režimu můžete k výsledku shaderu získat přístup
přímo, místo toho, abyste předem určili jeho zamýšlené použití. K výsledku můžete získat přístup jako k obrazovým
datům nebo jako k binárním či numerickým datům. Daná data nemusí být vůbec data obrazu. Takto můžete udělit
shaderu množinu dat jako vstup. Shader zpracovává data a k výsledným datům vráceným daným shaderem můžete
získat přístup.
Poznámka: Podpora sady nástrojů Pixel Bender je dostupná od verzí Flash Player 10 a Adobe AIR 1.5.
Běžné úlohy shaderů Pixel Bender
Následující úlohy představují výsledky, kterých budete pravděpodobně chtít použitím filtrů v jazyce ActionScript
dosáhnout:
• Načtení shaderu do běžící SWF aplikace nebo vložení shaderu v době kompilace a přístup v době běhu.
• Přístup k metadatům shaderu
• Identifikace a určení hodnoty pro vstupy shaderu (obvykle obrazy)
• Identifikace a určování hodnot pro parametry shaderu
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 377
Práce s shadery Pixel Bender
• Shader můžete použít následujícími způsoby:
• Jako výplň kresby
• Jako režim prolnutí
• Jako filtr
• V nezávislém režimu
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny, na které narazíte v této kapitole:
• Jádro: v Pixel Bender je jádro shodné se shaderem. Pomocí Pixel Bender definuje váš kód jádro, které definuje
jedinou funkci provádějící na každém obrazovém bodu obraz individuálně.
• Bajtový kód Pixel Bender: při kompilaci jádra Pixel Bender je jádro transformováno do bajtového kódu Pixel
Bender. K bajtovému kódu můžete získat přístup a provést jej programem Flash Player nebo Adobe AIR v době
běhu.
• Jazyk Pixel Bender: programovací jazyk použitý k vytvoření jádra Pixel Bender.
• Sada nástrojů Pixel Bender: aplikace použitá k vytvoření souboru bajtového kódu Pixel Bender ze zdrojového kódu
Pixel Bender. Sada nástrojů vám vždy umožňuje zapsat, testovat a kompilovat zdrojový kód Pixel Bender.
• Shader: pro účely tohoto dokumentu je shader sada funkcí zapsaných v jazyce Pixel Bender. Kód shaderu vytvoří
vizuální efekt nebo provede výpočet. V obou případech vrátí shader sadu dat (obvykle obrazové body snímku).
Shader provede stejnou operaci na každém datovém bodu, kdy jediným rozdílem jsou souřadnice výstupního
obrazového bodu.
Shader není zapsán v jazyce ActionScript. Je zapsán v jazyce Pixel Bender a kompilován do bajtového kódu Pixel
Bender. Shader lze vložit do souboru SWF v době kompilace nebo jej lze načíst jako externí soubor v době běhu. V
obou případech je k shaderu získáván přístup v jazyce ActionScript vytvořením objektu Shader a propojením
daného objektu s bajtovým kódem shaderu.
• Vstup shaderu: komplexní vstup, obvykle data obrazu bitmapy, který je poskytnut shaderu k použití ve výpočtech
shaderu. Pro každou proměnnou vstupu definovanou v shaderu je jediná hodnota (tj. jediný obraz nebo binární
data) použita pro celé provedení shaderu.
• Parametr shaderu: jediná hodnota (nebo limitovaná množina hodnot), která je poskytnuta shaderu k použití ve
výpočtech. Každá hodnota parametru je definována pro jediné provedení shaderu a stejná hodnota je použita
během celého provádění shaderu.
Procházení příkladů v kapitole
Při práci s kapitolou si můžete přát otestovat ukázky kódů, které jsou k dispozici. Protože se tato kapitola věnuje
vytváření a zpracovávání vizuálního obsahu, testování kódu zahrnuje spuštění kódu a zobrazení výsledků v souboru
SWF, který je vytvořen. Všechny příklady vytváří pomocí kreslicích rozhraní API obsah, který používá efekt shaderu
nebo je pomocí tohoto efektu upraven.
Většina z příkladů kódu zahrnuje dvě části. Jedná část je zdrojový kód Pixel Bender pro shader použitý v daném
příkladu. Nejprve musíte použít sadu nástrojů Pixel Bender ke kompilaci zdrojového kódu na soubor bajtového kódu
Pixel Bender. Podle těchto kroků vytvoříte soubor bajtového kódu Pixel Bender:
1 Otevřete sadu nástrojů Adobe Pixel Bender. V případě potřeby vyberte z nabídky Build možnost „Zapnout
varování a chyby Flash Player“.
2 Zkopírujte výpis kódu Pixel Bender a vložte jej do panelu editoru kódu sady nástrojů Pixel Bender.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 378
Práce s shadery Pixel Bender
3 Z nabídky Soubor vyberte možnost „Exportovat filtr jádra pro Flash Player“.
4 Uložte soubor bajtového kódu Pixel Bender do stejného adresáře jako dokument Flash. Název souboru by měl
odpovídat názvu zadanému v popisu příkladu.
Část jazyka ActionScript každého příkladu je zapsána jako soubor třídy. Testování příkladu:
1 Vytvořte prázdný dokument Flash a uložte ho ve svém počítači.
2 Vytvořte nový soubor ActionScript a uložte ho do stejného adresáře jako dokument Flash. Název souboru by měl
být stejný jako název třídy ve výpisu kódu. Jestliže například výpis kódu definuje třídu s názvem MyApplication,
použijte k uložení souboru ActionScript název MyApplication.as.
3 Zkopírujte výpis kódu do souboru ActionScript a soubor uložte.
4 V dokumentu Flash klepněte na prázdnou část Plochy nebo pracovní oblasti a aktivujte Inspektor vlastností
dokumentu.
5 V Inspektoru vlastností zadejte do pole Třída dokumentu název třídy ActionScript vykopírovaný z textu.
6 Spusťte program pomocí volby Ovládání > Testovat film
Výsledky příkladu se zobrazí v okně náhledu.
Tyto techniky testování příkladu kódu jsou vysvětleny podrobněji v kapitole „Testování příkladů kódu v této kapitole“
na stránce 34.
Načtení nebo vložení shaderu
Prvním krokem je použití shaderu Pixel Bender v jazyku ActionScript k získání přístupu k shaderu ve vašem kódu
ActionScript. Protože shader je vytvořen pomocí sady nástrojů Adobe Pixel Bender a napsán v jazyku Pixel Bender,
nemůže být v jazyku ActionScript použit přímo. Musíte nejprve vytvořit instanci třídy Shader, která bude zastupovat
shader Pixel Bender v jazyku ActionScript. Objekt Shader umožňuje zjistit informace o shaderu, např. jestli očekává
parametry nebo vstupní obrazové hodnoty. Chcete-li shader skutečně použít, předáte objekt Shader jiným objektům.
Například, chcete-li použít shader jako filtr, přiřadíte objekt Shader vlastnosti shader objektu ShaderFilter. Nebo
chcete-li použít shader jako výplň kresby, předáte objekt Shader jako argument metodě
Graphics.beginShaderFill().
Váš kód ActionScript se k shaderu vytvořenému pomocí sady nástrojů Adobe Pixel Bender (soubor .pbj) může dostat
dvěma způsoby:
• Načtený při běhu: soubor shaderu je možno načíst jako externí datový zdroj pomocí objektu URLLoader. Tato
technika je jako načítání externího datového zdroje, např. textového souboru. Následující příklad demonstruje
načtení souboru bytového kódu shaderu za běhu a jeho propojení s instancí Shader:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 379
Práce s shadery Pixel Bender
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("myShader.pbj"));
var shader:Shader;
function onLoadComplete(event:Event):void {
// Create a new shader and set the loaded data as its bytecode
shader = new Shader();
shader.byteCode = loader.data;
// You can also pass the bytecode to the Shader() constructor like this:
// shader = new Shader(loader.data);
// do something with the shader
}
• Vložený v souboru SWF: soubor shaderu může být vložený v souboru SWF při kompilaci pomocí tagu metadat
[Embed]. Tag metadat [Embed] je dostupný, pouze použijete-li ke kompilaci SWF souboru aplikaci Flex SDK.
Parametr source tagu [Embed] ukazuje na soubor shaderu a jeho parametr mimeType je "application/octetstream", jako v následujícím příkladu:
[Embed(source="myShader.pbj", mimeType="application/octet-stream")]
var MyShaderClass:Class;
// ...
// create a shader and set the embedded shader as its bytecode
var shaderShader = new Shader();
shader.byteCode = new MyShaderClass();
// You can also pass the bytecode to the Shader() constructor like this:
// var shader:Shader = new Shader(new MyShaderClass());
// do something with the shader
V obou případech spojujete nezpracovaný bytový kód shaderu (vlastnost URLLoader.data nebo instanci datové třídy
[Embed]) s instancí Shader. Jak je vidět na předcházejících příkladech, bytový kód shaderu můžete přiřadit k instanci
Shader dvěma způsoby. Můžete zadat bytový kód shaderu jako argument konstruktoru Shader(). Případně můžete
nastavit vlastnost byteCode instance Shader.
Jakmile byl vytvořen objekt Shader a navázán na objekt Shader, můžete použít shader k vytváření efektů několika
způsoby. Můžete jej použít jako filtr, režim prolnutí, bitmapovou výplň nebo pro nezávislé zpracování bitmapy nebo
jiných dat. Pomocí vlastnosti data objektu Shader se také můžete dostat k metadatům shaderu, určit vstupní obrazy a
nastavit hodnoty parametrů.
Přístup k metadatům shaderu
Při vytváření jádra shaderu Pixel Bender může autor určit metadata o shaderu ve zdrojovém kódu Pixel Bender. Při
vytváření shaderu v kódu ActionScript můžete shader prověřit a vyjmout jeho metadata.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 380
Práce s shadery Pixel Bender
Když vytváříte instanci Shader a navazujete ji na shader Pixel Bender, bude vytvořen objekt ShaderData obsahující data
o shaderu a uložen do vlastnosti data objektu Shader. Třída ShaderData nedefinuje žádné svoje vlastní vlastnosti. Při
běhu je však vlastnost dynamicky přidána k objektu ShaderData pro každou hodnotu metadat definovanou ve
zdrojovém kódu shaderu. Název udělený každé vlastnosti je stejný jako název určený v metadatech. Například dejme
tomu, že zdrojový kód shaderu Pixel Bender obsahuje následující definici metadat:
namespace : "Adobe::Example";
vendor : "Bob Jones";
version : 1;
description : "Creates a version of the specified image with the specified brightness.";
Objekt ShaderData vytvořený pro daný shader je vytvořen s následujícími vlastnostmi a hodnotami:
•
namespace (String): "Adobe::Example"
•
vendor (String): "Bob Jones"
•
version (String): "1"
•
description (String): "Creates a version of the specified image with the specified brightness"
Protože vlastnosti metadat jsou dynamicky přidávány k objektu ShaderData, můžete pomocí smyčky for..in
prověřit objekt ShaderData. Pomocí této techniky můžete zjistit, jestli má shader nějaká metadata a jaké jsou jejich
hodnoty. Kromě vlastností metadata může mít objekt ShaderData vlastnosti představující vstupy a parametry, které
jsou definované v shaderu. Při použití smyčky for..in k prověření objektu ShaderData zkontrolujte typ dat
jednotlivých vlastností, abyste určili, jestli je vlastnost vstup (instance ShaderInput), parametr (instance
ShaderParameter) nebo hodnotou metadat (instance String). Následující příklad ukazuje použití smyčky for..in k
prověření dynamických vlastností vlastnosti data shaderu. Každá hodnota metadat bude přidána do instance Vector
s názvem metadata. Všimněte si, že v tomto příkladu se předpokládá, že instance Shader s názvem myShader je již
vytvořená:
var shaderData:ShaderData = myShader.data;
var metadata:Vector.<String> = new Vector.<String>();
for (var prop:String in shaderData)
{
if (!(shaderData[prop] is ShaderInput) && !(shaderData[prop] is ShaderParameter))
{
metadata[metadata.length] = shaderData[prop];
}
}
// do something with the metadata
Verze tohoto příkladu, kde jsou také vyjmuty vstupy a parametry shaderu je uvedena v části „Určení vstupů a
parametrů shaderu“ na stránce 381. Další informace o vlastnostech vstupu a parametrů najdete v části „Určení hodnot
vstupu a parametrů shaderu“ na stránce 380.
Určení hodnot vstupu a parametrů shaderu
Mnohé shadery Pixel Bender jsou definovány pro použití jednoho nebo více vstupních obrazů, které jsou použity ve
zpracování shaderu. Pro shader je například běžné, že přijme zdrojový obraz a odevzdá tento obraz s použitým
příslušným efektem. Podle toho, jak je shader použit, může být vstupní hodnota určena automaticky nebo může
vyžadovat explicitní poskytnutí hodnoty. Podobně mnohé shadery určují parametry, které se používají k přizpůsobení
výstupu shaderu. Před použitím shaderu musíte explicitně nastavit i hodnotu jednotlivých parametrů.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 381
Práce s shadery Pixel Bender
Vlastnost data objektu Shader slouží k nastavení vstupů a parametrů shaderu a k určení, jestli příslušný shader
očekává vstupy nebo parametry. Vlastnost data je instance ShaderData.
Určení vstupů a parametrů shaderu
Prvním krokem určení hodnot vstupu a parametrů shaderu je zjistit, zda daný shader, který používáte, očekává nějaké
vstupní obrazy nebo parametry. Každá instance Shader má vlastnost data obsahující objekt ShaderData. Definuje-li
shader nějaké vstupy nebo parametry, jsou přístupné jako vlastnosti toho objektu ShaderData. Názvy vlastností se
shodují s názvy určenými pro vstupy a parametry ve zdrojovém kódu shaderu. Například, definuje-li shader vstup s
názvem src, bude mít objekt ShaderData vlastnost s názvem src představující daný vstup. Každá vlastnost, která
představuje nějaký vstup, je instancí ShaderInput a každá vlastnost, která představuje nějaký parametr, je instancí
ShaderParameter.
V ideálním případě poskytne autor shaderu dokumentaci k shaderu, kde je uvedeno, jaké hodnoty a parametry
vstupního obrazu shader očekává, co představují, jejich vhodné hodnoty atd.
Není-li však k shaderu přiložená dokumentace (a nemáte jeho zdrojový kód), můžete určit vstupy a parametry
prozkoumáním dat shaderu. Vlastnosti představující vstupy a parametry jsou dynamicky přidány k objektu
ShaderData. Můžete tedy pomocí smyčky for..in prozkoumat objekt ShaderData, abyste zjistili, zda jeho přidružený
shader definuje nějaké vstupy nebo parametry. Jak je popsáno v části „Přístup k metadatům shaderu“ na stránce 379,
k hodnotě metadat definované pro daný shader je přístup také jako k dynamické vlastnosti přidané k vlastnosti
Shader.data. Při použití této techniky k určení vstupů a parametrů shaderu zkontrolujte typ dat dynamických
vlastností. Je-li vlastnost instancí ShaderInput, představuje vstup. Je-li vlastnost instancí ShaderParameter, představuje
parametr. Jinak je to hodnota metadat. Následující příklad ukazuje použití smyčky for..in k prověření dynamických
vlastností vlastnosti data shaderu. Každý vstup (objekt ShaderInput) bude přidán k instanci Vector s názvem inputs.
Každý parametr (objekt ShaderParameter) bude přidán k instanci Vector s názvem parameters. A konečně veškeré
vlastnosti metadat budou přidány k instanci Vector s názvem metadata. Všimněte si, že v tomto příkladu se
předpokládá, že instance Shader s názvem myShader je již vytvořená:
var
var
var
var
shaderData:ShaderData = myShader.data;
inputs:Vector.<ShaderInput> = new Vector.<ShaderInput>();
parameters:Vector.<ShaderParameter> = new Vector.<ShaderParameter>();
metadata:Vector.<String> = new Vector.<String>();
for (var prop:String in shaderData)
{
if (shaderData[prop] is ShaderInput)
{
inputs[inputs.length] = shaderData[prop];
}
else if (shaderData[prop] is ShaderParameter)
{
parameters[parameters.length] = shaderData[prop];
}
else
{
metadata[metadata.length] = shaderData[prop];
}
}
// do something with the inputs or properties
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 382
Práce s shadery Pixel Bender
Určení vstupních hodnot shaderu
Mnohé shadery očekávají jeden nebo více vstupních obrazů, které se použijí při zpracování shaderu. V mnoha
případech je však vstup určen automaticky při použití objektu Shader. Například dejme tomu, že shader vyžaduje
jeden vstup a že se tento shader používá jako filtr. Při aplikaci tohoto filtru na objekt zobrazení nebo objekt
BitmapData bude daný objekt automaticky nastaven jako vstup. V takovém případě nenastavujete explicitně vstupní
hodnotu.
Avšak v některých případech, zejména pokud shader definuje více vstupů, musíte explicitně nastavit hodnotu pro
vstup. Každý vstup, který je definován v shaderu, je v kódu ActionScript zastoupen objektem ShaderInput. Objekt
ShaderInput je vlastnost instance ShaderData ve vlastnosti data objektu Shader, jak je popsáno v části „Určení vstupů
a parametrů shaderu“ na stránce 381. Například dejme tomu, že shader definuje vstup s názvem src a že je tento
shader napojen na objekt Shader s názvem myShader. V takovém případě se dostanete k objektu ShaderInput
odpovídajícímu vstupu src pomocí následujícího identifikátoru:
myShader.data.src
Každý objekt ShaderInput má vlastnost input, která se používá k nastavení hodnoty pro vstup. Chcete-li určit
obrazová data, nastavte vlastnost input na instanci BitmapData. Vlastnost input můžete také nastavit na instanci
BitmapData nebo Vector.<Number> k určení binárních nebo číselných dat. Podrobnosti a omezení ohledně používání
instance BitmapData nebo Vektor.<Number> jako vstup najdete v přehledu ShaderInput.input v referenční
příručce jazyka.
Kromě vlastnosti input má objekt ShaderInput také vlastnosti, které můžete použít k určení, jaký typ obrazu je na
vstupu očekáván. Sem patří vlastnosti width, height a channels. Každý objekt ShaderInput má také vlastnost index,
která je užitečná pro určení, zda je pro vstup třeba poskytnout explicitní hodnotu. Jestliže shader očekává více vstupů,
než je automaticky nastavený počet, pak musíte hodnoty pro tyto vstupy nastavit sami. Podrobnosti k různým
způsobům použití shaderu a určení, zda se vstupní hodnoty nastavují automaticky, jsou uvedeny v části „Používání
shaderu“ na stránce 386.
Určení hodnot parametrů shaderu
Některé shadery definují hodnoty parametrů, které shader používá při vytváření svého výsledku. Například, shader,
který mění jas obrazu, může určovat parametr jas, který určuje, jaký vliv bude mít operace na jas. Jeden parametr
definovaný v shaderu může očekávat jednu hodnotu nebo více hodnot, podle definice parametru v shaderu. Každý
parametr, který je definován v shaderu, je v kódu ActionScript zastoupen objektem ShaderParameter. Objekt
ShaderParameter je vlastnost instance ShaderData ve vlastnosti data objektu Shader, jak je popsáno v části „Určení
vstupů a parametrů shaderu“ na stránce 381. Například dejme tomu, že shader definuje parametr s názvem
brightness a že je tento shader zastoupen objektem Shader s názvem myShader. V takovém případě se dostanete k
objektu ShaderParameter odpovídajícímu parametru brightness pomocí následujícího identifikátoru:
myShader.data.brightness
Chcete-li zadat hodnotu (nebo hodnoty) pro parametr, vytvořte pole ActionScript obsahující hodnotu nebo hodnoty
a přiřaďte jej k vlastnosti value objektu ShaderParameter. Vlastnost value je definována jako instance Array, protože
je možné, že jeden parametr shaderu vyžaduje více hodnot. I kdyby parametr shaderu očekával jen jednu hodnotu,
musíte tuto hodnotu zabalit do objektu Array, abyste ji mohli přiřadit k vlastnosti ShaderParameter.value.
Následující přehled předvádí nastavení jedné hodnoty jako vlastnosti value:
myShader.data.brightness.value = [75];
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 383
Práce s shadery Pixel Bender
Jestliže zdrojový kód Pixel Bender pro shader definuje výchozí hodnotu pro parametr, bude při vytváření objektu
Shader vytvořeno pole obsahující výchozí hodnotu nebo hodnoty a přiřazeno k vlastnosti value objektu
ShaderParameter. Jakmile bylo pole přiřazeno k vlastnosti value (i v případě, že se jedná o výchozí hodnotu), můžete
změnou hodnoty elementu pole změnit hodnotu parametru. Nemusíte vytvářet nové pole a přiřazovat je vlastnosti
value.
Následující příklad ukazuje nastavení hodnoty parametru shaderu v jazyce ActionScript. V tomto příkladu shader
definuje parametr s názvem color. Parametr color je deklarován jako proměnnáfloat4 ve zdrojovém kódu Pixel
Bender, což znamená, že to je pole se čtyřmi čísly s pohyblivou desetinnou čárkou. V tomto příkladu se hodnota
parametru color nepřetržitě mění a při každé změně se pomocí shaderu nakreslí na obrazovce barevný obdélník.
Výsledkem je animovaná změna barvy.
Poznámka: Kód pro tento příklad napsal Ryan Taylor. Děkujeme Ryanovi za tento příklad. Ryanovo portfolio a jeho
zápis si můžete prohlédnout na webové adrese www.boostworthy.com.
Kód ActionScript se soustředí kolem tří metod:
•
init(): v metodě init() načte kód soubor bajtového kódu Pixel Bender obsahující shader. Při načtení souboru je
volána metoda onLoadComplete().
•
onLoadComplete(): v metodě onLoadComplete() vytvoří kód objekt Shader pojmenovaný shader. Vytvoří také
instanci Sprite pojmenovanou texture. V metodě renderShader() nakreslí kód výsledek shaderu dotexture
jednou za snímek.
•
onEnterFrame(): Metoda onEnterFrame() je vyvolána jedenkrát za snímek, což vytvoří efekt animace. V této
metodě kód nastaví hodnotu parametru shaderu na novou barvu, dále vyvolá metodu renderShader() k
nakreslení výsledku shaderu v podobě obdélníku.
•
renderShader(): v metodě renderShader()kód vyvolá metodu Graphics.beginShaderFill() k určení
výplně shaderu. Poté nakreslí obdélník, jehož výplň je definována výstupem shaderu (generovaná barva). Další
informace o používání shaderu za tímto účelem naleznete v části „Použití shaderu jako výplně kresby“ na
stránce 386.
Následuje kód ActionScript pro tento příklad. Tuto třídu použijte jako hlavní třídu aplikace pro projekt pouze s
jazykem ActionScript v programu Flex, nebo jako třídu dokumentu pro soubor FLA ve vývojovém nástroji Flash:
package
{
import
import
import
import
import
import
flash.display.Shader;
flash.display.Sprite;
flash.events.Event;
flash.net.URLLoader;
flash.net.URLLoaderDataFormat;
flash.net.URLRequest;
public class ColorFilterExample extends Sprite
{
private const DELTA_OFFSET:Number = Math.PI * 0.5;
private var loader:URLLoader;
private var shader:Shader;
private var texture:Sprite;
private var delta:Number = 0;
public function ColorFilterExample()
{
init();
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 384
Práce s shadery Pixel Bender
private function init():void
{
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("ColorFilter.pbj"));
}
private function onLoadComplete(event:Event):void
{
shader = new Shader(loader.data);
shader.data.point1.value = [topMiddle.x, topMiddle,y];
shader.data.point2.value = [bottomLeft.x, bottomLeft.y];
shader.data.point3.value = [bottomRight.x, bottomRight.y];
texture = new Sprite();
addChild(texture);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
shader.data.color.value[0] = 0.5 + Math.cos(delta - DELTA_OFFSET) * 0.5;
shader.data.color.value[1] = 0.5 + Math.cos(delta) * 0.5;
shader.data.color.value[2] = 0.5 + Math.cos(delta + DELTA_OFFSET) * 0.5;
// The alpha channel value (index 3) is set to 1 by the kernel's default
// value. This value doesn't need to change.
delta += 0.1;
renderShader();
}
private function renderShader():void
{
texture:graphics.clear();
texture.graphics.beginShaderFill(shader);
texture.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
texture.graphics.endFill();
}
}
}
Následuje zdrojový kód pro jádro shaderu ColorFilter, použitý k vytvoření souboru bytového kódu Pixel Bender
„ColorFilter.pbj“:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 385
Práce s shadery Pixel Bender
<languageVersion : 1.0;>
kernel ColorFilter
<
namespace : "boostworthy::Example";
vendor : "Ryan Taylor";
version : 1;
description : "Creates an image where every pixel has the specified color value.";
>
{
output pixel4 result;
parameter float4 color
<
minValue:float4(0, 0, 0, 0);
maxValue:float4(1, 1, 1, 1);
defaultValue:float4(0, 0, 0, 1);
>;
void evaluatePixel()
{
result = color;
}
}
Používáte-li shader, jehož parametry nejsou zdokumentovány, můžete zjistit, kolik elementů a jakého typu musí být
obsaženo v poli tak, že zkontrolujete vlastnost type objektu ShaderParameter. Vlastnost type udává typ dat
parametru, jak je definován v samotném shaderu. Seznam počtu a typů elementů očekávaných jednotlivými typy
parametrů je uveden v přehledu vlastnosti ShaderParameter.value v referenční příručce jazyka.
Každý objekt ShaderParameter má také vlastnost index, která udává, kam daný parametr patří v pořadí parametrů
shaderu. Kromě těchto vlastností může mít objekt ShaderParameter ještě další vlastnosti obsahující hodnoty metadat
poskytnuté autorem shaderu. Autor může určit například hodnoty metadat jako minimální, maximální a výchozí
hodnoty pro parametr. Všechny hodnoty metadat, které autor určil, jsou přidány do objektu ShaderParameter jako
dynamické vlastnosti. Chcete-li tyto vlastnosti prověřit, použijte smyčku for..in k cyklickému procházení
dynamických vlastností objektu ShaderParameter pro určení jeho metadat. Následující příklad ukazuje použití smyčky
for..in k určení metadat objektu ShaderParameter. Každá hodnota metadat bude přidána do instance Vector s
názvem metadata. Všimněte si, že v tomto příkladu se předpokládá, že instance Shader s názvem myShader je již
vytvořená a že je známo, že má parametr s názvem brightness:
var brightness:ShaderParameter = myShader.data.brightness;
var metadata:Vector.<String> = new Vector.<String>();
for (var prop:String in brightness)
{
if (brightness[prop] is String)
{
metadata[metadata.length] = brightness[prop];
}
}
// do something with the metadata
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 386
Práce s shadery Pixel Bender
Používání shaderu
Jakmile je shader dostupný v kódu ActionScript jako objekt Shader, můžete jej použít několika způsoby:
• Výplň kresby shaderu: shader definuje část výplně ve tvaru nakresleném pomocí kreslicího rozhraní api
• Režim prolnutí: shader definuje prolnutí mezi dvěma překrývajícími se objekty zobrazení
• Filtr: shader definuje filtr, který upraví vzhled vizuálního obsahu
• Nezávislé zpracování shaderu: zpracování shaderu běží bez určení zamýšleného použití jeho výstupu. Shader může
volitelně běžet na pozadí, přičemž výsledek bude k dispozici při dokončení zpracování. Tuto techniku můžete
použít ke generování bitmapových dat a také ke zpracování nevizuálních dat.
Použití shaderu jako výplně kresby
Používáte-li shader k vytvoření výplně kresby, používáte k vytvoření tvaru vektoru metody kreslicího rozhraní api.
Výstup shaderu je použit k vyplnění tvaru stejným způsobem, kterým lze použít jakýkoliv obraz bitmapy použitý jako
výplň bitmapy pomocí kreslicího rozhraní api. K vytvoření výplně shaderu v bodě svého kódu, ve kterém si přejete
zahájit kreslení tvaru, volejte metodu objektu Graphics beginShaderFill(). Předejte objekt Shader jako první
argument k metodě beginShaderFill(), viz následující výpis:
var canvas:Sprite = new Sprite();
canvas.graphics.beginShaderFill(myShader);
canvas.graphics.drawRect(10, 10, 150, 150);
canvas.graphics.endFill();
// add canvas to the display list to see the result
Používáte-li shader jako výplně kresby, nastavte jakékoliv vstupní hodnoty obrazu a hodnoty parametru, které shader
vyžaduje.
Následující příklad ukazuje použití shaderu jako výplně kresby. V tomto příkladě vytvoří shader tříbodový přechod.
Tento přechod má tři barvy, každá v bodě trojúhelníku, s prolínáním přechodu mezi těmito body. Mimo to tyto obsahy
rotují k vytvoření animovaného efektu otáčející se barvy.
Poznámka: Kód pro tento příklad napsal Petri Leskinen. Děkujeme Petrimu za tento příklad. Více jeho příkladů a
výukových programů naleznete na webové adrese http://pixelero.wordpress.com.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 387
Práce s shadery Pixel Bender
Kód jazyka ActionScript je ve třech metodách:
•
init(): Metoda init() je volána při načtení aplikace. V této metodě kód nastaví počáteční hodnoty objektů Point
představující body trojúhelníku. Kód také vytvoří instanci Sprite pojmenovanou canvas. Později v metodě
updateShaderFill() nakreslí kód výsledek shaderu docanvas jednou za snímek. Nakonec soubor načte soubor
bajtového kódu shaderu.
•
onLoadComplete(): v metodě onLoadComplete() vytvoří kód objekt Shader pojmenovaný shader. Nastaví také
počáteční hodnoty parametru. Nakonec kód přidá metodu updateShaderFill() jako posluchač události
enterFrame, což znamená, že je volána jednou za snímek k vytvoření efektu animace.
•
updateShaderFill(): metoda updateShaderFill() je vyvolána jedenkrát za snímek, což vytvoří efekt animace.
V této metodě kód vypočte a nastaví hodnoty parametru shaderu. Kód poté volá metodu beginShaderFill() k
vytvoření výplně shaderu a volá jiné metody kreslicích rozhraní api k nakreslení výsledku shaderu v trojúhelníku.
Následuje kód ActionScript pro tento příklad. Tuto třídu použijte jako hlavní třídu aplikace pro projekt pouze s
jazykem ActionScript v programu Flex, nebo jako třídu dokumentu pro soubor FLA ve vývojovém nástroji Flash:
package
{
import
import
import
import
import
import
import
flash.display.Shader;
flash.display.Sprite;
flash.events.Event;
flash.geom.Point;
flash.net.URLLoader;
flash.net.URLLoaderDataFormat;
flash.net.URLRequest;
public class ThreePointGradient extends Sprite
{
private var canvas:Sprite;
private var shader:Shader;
private var loader:URLLoader;
private var topMiddle:Point;
private var bottomLeft:Point;
private var bottomRight:Point;
private var colorAngle:Number = 0.0;
private const d120:Number = 120 / 180 * Math.PI; // 120 degrees in radians
public function ThreePointGradient()
{
init();
}
private function init():void
{
canvas = new Sprite();
addChild(canvas);
var size:int = 400;
topMiddle = new Point(size / 2, 10);
bottomLeft = new Point(0, size - 10);
bottomRight = new Point(size, size - 10);
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 388
Práce s shadery Pixel Bender
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("ThreePointGradient.pbj"));
}
private function onLoadComplete(event:Event):void
{
shader = new Shader(loader.data);
shader.data.point1.value = [topMiddle.x, topMiddle,y];
shader.data.point2.value = [bottomLeft.x, bottomLeft.y];
shader.data.point3.value = [bottomRight.x, bottomRight.y];
addEventListener.Event.ENTER_FRAME, updateShaderFill);
}
private function updateShaderFill(event:Event):void
{
colorAngle += .06;
var c1:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle);
var c2:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle + d120);
var c3:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle - d120;
shader.data.color1.value = [c1, c2, c3, 1.0];
shader.data.color2.value = [c3, c1, c2, 1.0];
shader.data.color3.value = [c2, c3, c1, 1.0];
canvas.graphics.clear();
canvas.graphics.beginShaderFill(shader);
canvas.graphics.moveTo(topMiddle.x, topMiddle.y);
canvas.graphics.lineTo(bottomLeft.x, bottomLeft.y);
canvas.graphics.lineTo(bottomRight.x, bottomLeft.y);
canvas.graphics.endFill();
}
}
}
Následuje zdrojový kód pro jádro shaderu ThreePointGradient, použitý k vytvoření souboru bytového kódu Pixel
Bender „ThreePointGradient.pbj“:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 389
Práce s shadery Pixel Bender
<languageVersion : 1.0;>
kernel ThreePointGradient
<
namespace : "Petri Leskinen::Example";
vendor : "Petri Leskinen";
version : 1;
description : "Creates a gradient fill using three specified points and colors.";
>
{
parameter float2 point1 // coordinates of the first point
<
minValue:float2(0, 0);
maxValue:float2(4000, 4000);
defaultValue:float2(0, 0);
>;
parameter float4 color1 // color at the first point, opaque red by default
<
defaultValue:float4(1.0, 0.0, 0.0, 1.0);
>;
parameter float2 point2 // coordinates of the second point
<
minValue:float2(0, 0);
maxValue:float2(4000, 4000);
defaultValue:float2(0, 500);
>;
parameter float4 color2 // color at the second point, opaque green by default
<
defaultValue:float4(0.0, 1.0, 0.0, 1.0);
>;
parameter float2 point3 // coordinates of the third point
<
minValue:float2(0, 0);
maxValue:float2(4000, 4000);
defaultValue:float2(0, 500);
>;
parameter float4 color3 // color at the third point, opaque blue by default
<
defaultValue:float4(0.0, 0.0, 1.0, 1.0);
>;
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 390
Práce s shadery Pixel Bender
output pixel4 dst;
void evaluatePixel()
{
float2 d2 = point2 - point1;
float2 d3 = point3 - point1;
// transformation to a new coordinate system
// transforms point 1 to origin, point2 to (1, 0), and point3 to (0, 1)
float2x2 mtrx = float2x2(d3.y, -d2.y, -d3.x, d2.x) / (d2.x * d3.y - d3.x * d2.y);
float2 pNew = mtrx * (outCoord() - point1);
// repeat the edge colors on the outside
pNew.xy = clamp(pNew.xy, 0.0, 1.0); // set the range to 0.0 ... 1.0
// interpolating the output color or alpha value
dst = mix(mix(color1, color2, pNew.x), color3, pNew.y);
}
}
Pro více informací o kreslení tvarů pomocí kreslicího rozhraní api viz „Používání kreslicího rozhraní API“ na
stránce 314.
Použití shaderu jako režimu prolnutí
Používání shaderu jako režimu prolnutí je podobné používání jiných režimů prolnutí. Shader definuje vzhled, který je
výsledkem vizuálního prolnutí dvou objektů zobrazení. K použití shaderu jako režimu prolnutí přiřaďte objekt Shader
k vlastnosti blendShader objektu zobrazení v popředí. Přiřazení hodnoty jiné nežnull k vlastnosti blendShader
automaticky nastaví vlastnost objektu zobrazení blendMode na BlendMode.SHADER. Následující výpis ukazuje použití
shaderu jako režimu prolnutí. Tento příklad předpokládá, že existuje objekt zobrazení pojmenovaný foreground
obsažený ve stejném nadřazeném objektu na seznamu zobrazení jako další obsah zobrazení, kde foreground překrývá
další obsah:
foreground.blendShader = myShader;
Jestliže používáte shader jako režim prolnutí, musí být shader definován minimálně pomocí dvou vstupů. Jak ukazuje
příklad, nemusíte ve svém kódu nastavit vstupní hodnoty. Namísto toho se dané dva prolnuté obrazy automaticky
použijí jako vstupy shaderu. Obraz v popředí je nastaven jako druhý obraz. (Toto je objekt zobrazení, na který je režim
prolnutí použit.) Obraz pozadí je vytvořen přetažením složení všech obrazových bodů za ohraničovací rámeček obrazu
popředí. Tento obraz pozadí je nastaven jako první vstupní obraz. Jestliže používáte shader, který očekává více než
pouze dva vstupy, zadejte hodnotu pro jakýkoliv vstup mimo první dva vstupy.
Následující výpis ukazuje použití shaderu jako režimu prolnutí. Tento příklad používá režim zesvětleného prolnutí na
základě světlosti. Výsledek prolnutí je, že se hodnota nejsvětlejšího obrazového bodu z některého z prolnutých objektů
stane obrazovým bodem, který je zobrazen.
Poznámka: Kód pro tento příklad napsal Mario Klingemann. Děkujeme Mariovi za tento příklad. Více práce Maria a
jeho zápisy naleznete na webové adrese www.quasimondo.com.
Důležitý kód jazyka ActionScript je v následujících dvou metodách:
•
init(): metoda init() je volána při načtení aplikace. V této metodě načte kód soubor bajtového kódu shaderu.
•
onLoadComplete(): v metodě onLoadComplete() vytvoří kód objekt Shader pojmenovaný shader. Poté nakreslí
tři objekty. První, backdrop, je tmavě šedé pozadí za prolnutými objekty. Druhý, backgroundShape, je zelená
přechodová elipsa. Třetí objekt, foregroundShape, je oranžová přechodová elipsa.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 391
Práce s shadery Pixel Bender
Elipsa foregroundShape je objekt popředí prolnutí. Obraz pozadí prolnutí je tvořen částí backdrop a části
backgroundShape, které jsou překryty ohraničujícím rámečkem objektu foregroundShape. Objekt
foregroundShape je objekt nejvíce v popředí seznamu zobrazení. Tento objekt částečně překrývá
backgroundShape a zcela překrývábackdrop. Z důvodu tohoto překrytí bez použití režimu prolnutí je oranžová
elipsa foregroundShape) zobrazena kompletně a zakrývá část zelené elipsy (backgroundShape).
Nicméně použijete-li režim prolnutí, jasnější část zelené elipsy bude prosvítat, protože je jasnější než část
foregroundShape, kterou překrývá.
Následuje kód ActionScript pro tento příklad. Tuto třídu použijte jako hlavní třídu aplikace pro projekt pouze s
jazykem ActionScript v programu Flex, nebo jako třídu dokumentu pro soubor FLA ve vývojovém nástroji Flash:
package
{
import
import
import
import
import
import
import
import
import
import
import
flash.display.BlendMode;
flash.display.GradientType;
flash.display.Graphics;
flash.display.Shader;
flash.display.Shape;
flash.display.Sprite;
flash.events.Event;
flash.geom.Matrix;
flash.net.URLLoader;
flash.net.URLLoaderDataFormat;
flash.net.URLRequest;
public class LumaLighten extends Sprite
{
private var shader:Shader;
private var loader:URLLoader;
public function LumaLighten()
{
init();
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 392
Práce s shadery Pixel Bender
private function init():void
{
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("LumaLighten.pbj"));
}
private function onLoadComplete(event:Event):void
{
shader = new Shader(loader.data);
var backdrop:Shape = new Shape();
var g0:Graphics = backdrop.graphics;
g0.beginFill(0x303030);
g0.drawRect(0, 0, 400, 200);
g0.endFill();
addChild(backdrop);
var backgroundShape:Shape = new Shape();
var g1:Graphics = backgroundShape.graphics;
var c1:Array = [0x336600, 0x80ff00];
var a1:Array = [255, 255];
var r1:Array = [100, 255];
var m1:Matrix = new Matrix();
m1.createGradientBox(300, 200);
g1.beginGradientFill(GradientType.LINEAR, c1, a1, r1, m1);
g1.drawEllipse(0, 0, 300, 200);
g1.endFill();
addChild(backgroundShape);
var foregroundShape:Shape = new Shape();
var g2:Graphics = foregroundShape.graphics;
var c2:Array = [0xff8000, 0x663300];
var a2:Array = [255, 255];
var r2:Array = [100, 255];
var m2:Matrix = new Matrix();
m2.createGradientBox(300, 200);
g2.beginGradientFill(GradientType.LINEAR, c2, a2, r2, m2);
g2.drawEllipse(100, 0, 300, 200);
g2.endFill();
addChild(foregroundShape);
foregroundShape.blendShader = shader;
foregroundShape.blendMode = BlendMode.SHADER;
}
}
}
Následuje zdrojový kód pro jádro shaderu LumaLighten, použitý k vytvoření souboru bytového kódu Pixel Bender
„LumaLighten.pbj“:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 393
Práce s shadery Pixel Bender
<languageVersion : 1.0;>
kernel LumaLighten
<
namespace : "com.quasimondo.blendModes";
vendor : "Quasimondo.com";
version : 1;
description : "Luminance based lighten blend mode";
>
{
input image4 background;
input image4 foreground;
output pixel4 dst;
const float3 LUMA = float3(0.212671, 0.715160, 0.072169);
void evaluatePixel()
{
float4 a = sampleNearest(foreground, outCoord());
float4 b = sampleNearest(background, outCoord());
float luma_a = a.r * LUMA.r + a.g * LUMA.g + a.b * LUMA.b;
float luma_b = b.r * LUMA.r + b.g * LUMA.g + b.b * LUMA.b;
dst = luma_a > luma_b ? a : b;
}
}
Pro více informací o používání režimů prolnutí viz „Použití režimů prolnutí“ na stránce 297.
Použití shaderu jako filtru
Použití shaderu jako filtru se podobá použití jakéhokoliv jiného filtru jazyka ActionScript. Když používáte shader jako
filtr, je filtrovaný obraz (objekt zobrazení nebo objekt BitmapData) předán k shaderu. Shader používá vstupní obraz k
vytvoření vstupu filtru, který je obvykle upravenou verzí původního obrazu. Jestliže je filtrovaný objekt objektem
zobrazení, je výstup shaderu zobrazen na obrazovce namísto filtrovaného objektu zobrazení. Jestliže je filtrovaný
objekt objekt BitmapData, stane se výstup shaderu obsahem objektu BitmapData, jehož metoda applyFilter() je
volána.
K použití shaderu jako filtru použijte objekt Shader dle popisu v „Načtení nebo vložení shaderu“ na stránce 378. Poté
vytvořte objekt ShaderFilter propojený s objektem Shader. Objekt ShaderFilter je filtr, který lze použít na daný
filtrovaný objekt. Filtr použijete na objekt stejným způsobem jako jakýkoliv jiný filtr. Filtr předáte vlastnosti filters
objektu zobrazení nebo voláte metodu applyFilter() na objektu BitmapData. Například následující kód vytvoří
objekt ShaderFilter a použije daný filtr na objekt zobrazení pojmenovaný homeButton.
var myFilter:ShaderFilter = new ShaderFilter(myShader);
homeButton.filters = [myFilter];
Jestliže používáte shader jako filtr, musí být shader definován minimálně pomocí jednoho vstupu. Jak ukazuje příklad,
nemusíte ve svém kódu nastavit vstupní hodnotu. Namísto toho je filtrovaný objekt zobrazení nebo objekt
BitmapData nastaven jako vstupní obraz. Jestliže používáte shader, který očekává více než pouze jen vstup, zadejte
hodnotu pro jakýkoliv vstup mimo první vstup.
V některých případech změní filtr rozměry původního obrazu. Například typický efekt vrženého stínu přidá navíc
obrazové body obsahující stín, který je přidán k obrazu. Jestliže používáte shader, který změní rozměry obrazu,
nastavte vlastnosti leftExtension, rightExtension, topExtension a bottomExtension k určení rozsahu změny
velikosti obrazu.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 394
Práce s shadery Pixel Bender
Následující výpis ukazuje použití shaderu jako filtru. Filtr v tomto příkladě obrátí hodnoty červeného, zeleného a
modrého kanálu obrazu. Výsledkem je „záporná“ verze obrazu.
Poznámka: Shader použitý v tomto příkladu je jádro invertRGB.pbk Pixel Bender, které je součástí sady nástrojů Pixel
Bender. Zdrojový kód pro jádro můžete načíst z instalačního adresáře sady nástrojů Pixel Bender. Kompilujte zdrojový
kód a uložte soubor bajtového kódu ve stejném adresáři jako zdrojový kód.
Důležitý kód jazyka ActionScript je v následujících dvou metodách:
•
init(): metoda init() je volána při načtení aplikace. V této metodě načte kód soubor bajtového kódu shaderu.
•
onLoadComplete(): v metodě onLoadComplete() vytvoří kód objekt Shader pojmenovaný shader. Poté vytvoří
a nakreslí obsah objektu pojmenovaného target. Objekt target je obdélník vyplněný barvou lineárního
přechodu, který je červený nalevo, žlutozelený ve středu a světle modrý napravo. Nefiltrovaný objekt vypadá
následovně:
Pomocí použitého filtru jsou barvy obráceny a obdélník bude vypadat následovně:
Shader použitý v tomto příkladu je ukázkové jádro „invertRGB.pbk“ Pixel Bender, které je součástí sady nástrojů Pixel
Bender. Zdrojový kód je k dispozici v souboru „invertRGB.pbk“ v instalačním adresáři sady nástrojů Pixel Bender.
Kompilujte zdrojový kód a poté uložte soubor bajtového kódu pojmenovaný „invertRGB.pbj“ do stejného adresáře
jako zdrojový kód jazyka ActionScript.
Následuje kód ActionScript pro tento příklad. Tuto třídu použijte jako hlavní třídu aplikace pro projekt pouze s
jazykem ActionScript v programu Flex, nebo jako třídu dokumentu pro soubor FLA ve vývojovém nástroji Flash:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 395
Práce s shadery Pixel Bender
package
{
import
import
import
import
import
import
import
import
import
import
import
flash.display.GradientType;
flash.display.Graphics;
flash.display.Shader;
flash.display.Shape;
flash.display.Sprite;
flash.filters.ShaderFilter;
flash.events.Event;
flash.geom.Matrix;
flash.net.URLLoader;
flash.net.URLLoaderDataFormat;
flash.net.URLRequest;
public class InvertRGB extends Sprite
{
private var shader:Shader;
private var loader:URLLoader;
public function InvertRGB()
{
init();
}
private function init():void
{
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("invertRGB.pbj"));
}
private function onLoadComplete(event:Event):void
{
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 396
Práce s shadery Pixel Bender
shader = new Shader(loader.data);
var target:Shape = new Shape();
addChild(target);
var g:Graphics = target.graphics;
var c:Array = [0x990000, 0x445500, 0x007799];
var a:Array = [255, 255, 255];
var r:Array = [0, 127, 255];
var m:Matrix = new Matrix();
m.createGradientBox(w, h);
g.beginGradientFill(GradientType.LINEAR, c, a, r, m);
g.drawRect(10, 10, w, h);
g.endFill();
var invertFilter:ShaderFilter = new ShaderFilter(shader);
target.filters = [invertFilter];
}
}
}
Pro více informací o používání filtrů viz „Vytváření a používání filtrů“ na stránce 347.
Použití shaderu v nezávislém režimu
Jestliže používáte shader v nezávislém režimu, zpracování shaderu běží nezávisle na zamýšleném způsobu použití
výstupu. Určete shader, který má být proveden, nastavte vstupní hodnoty a hodnoty parametru a určete objekt, do
kterého budou výsledná data umístěna. Shader můžete v nezávislém režimu použít za dvěma účely:
• Zpracování neobrazových dat: v nezávislém režimu můžete předat libovolná binární nebo numerická data k
shaderu namísto obrazových dat bitmapy. Vedle obrazových dat bitmapy můžete nastavit, aby byl výsledek shaderu
vrácen jako binární data nebo numerická data.
• Zpracovávání na pozadí: spustíte-li shader v nezávislém režimu, provedení bude implicitně asynchronní. To
znamená, že daný shader běží na pozadí, zatímco vaše aplikace pokračuje a váš kód je uvědomen o ukončení
zpracovávání shaderu. Můžete použít shader, jehož spuštění trvá dlouho a během běhu nedojde k zamrznutí
uživatelského rozhraní aplikace nebo jiného zpracovávání.
Objekt ShaderJob můžete použít k provedení shaderu v nezávislém režimu. Nejprve vytvořte objekt ShaderJob a poté
jej propojte s objektem Shader představujícím shader, který má být proveden:
var job:ShaderJob = new ShaderJob(myShader);
Dále nastavte libovolné hodnoty výstupu nebo parametru, které shader očekává. Jestliže shader provádíte na pozadí,
zaregistrujte také posluchač události objektu ShaderJob complete. Váš posluchač je volán, když shader dokončí svou
práci:
function completeHandler(event:ShaderEvent):void
{
// do something with the shader result
}
job.addEventListener(ShaderEvent.COMPLETE, completeHandler);
Dále vytvořte objekt, do kterého bude po ukončení operace shaderu zapsán její výsledek. Daný objekt přiřadíte k
vlastnosti objektu ShaderJob target:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 397
Práce s shadery Pixel Bender
var jobResult:BitmapData = new BitmapData(100, 75);
job.target = jobResult;
Jestliže používáte ShaderJob ke zpracovávání obrazů, přiřaďte instanci BitmapData vlastnosti target. Jestliže
zpracováváte binární nebo numerická data, přiřaďte objekt ByteArray nebo instanci Vector.<Number> instance k
vlastnosti target. V daném případě musíte nastavit vlastnosti objektu ShaderJob width a height k určení množství
dat pro výstup do objektu target.
Poznámka: Vlastnosti objektu ShaderJob shader, target,width a height můžete nastavit v jediném kroku, a to
předáním argumentů ke konstruktoru ShaderJob(), např.:var job:ShaderJob = new ShaderJob(myShader,
myTarget, myWidth, myHeight);
Jste-li připraveni shader provést, volejte metodu objektu ShaderJob start():
job.start();
Volání start() implicitně vyvolá asynchronní provedení ShaderJob. V daném případě provádění programu
pokračuje ihned s dalším řádkem a nečeká na dokončení shaderu. Po dokončení operace shaderu objekt ShaderJob
volá posluchače své vlastnosti complete a uvědomí je o dokončení. V daném okamžiku (tj. v těle posluchače
událosticomplete) objekt target obsahuje výsledek operace shaderu.
Poznámka: Namísto použití objektu vlastnosti target můžete načíst výsledek shaderu přímo z objektu události, který
je předán metodě vašeho posluchače. Objekt události je instance ShaderEvent. Objekt ShaderEvent má tři vlastnosti, které
lze použít k získání přístupu k výsledku, v závislosti na datovém typu objektu, který nastavíte jako vlastnost target:
ShaderEvent.bitmapData, ShaderEvent.byteArray a ShaderEvent.vector.
Můžete také předat argument true metodě start(). V daném případě je operace shaderu provedena synchronně. Při
provádění shaderu je celý kód zastaven (včetně interakce s uživatelským rozhraním a jiných událostí). Po dokončení
shaderu objekt target obsahuje výsledek shaderu a program pokračuje s dalším řádkem kódu.
job.start(true);
398
Kapitola 18: Práce s filmovými klipy
Třída MovieClip je základní třídou pro symboly animací a filmových klipů vytvořené v aplikaci Adobe® Flash® CS4
Professional. Tato třída má chování a funkce objektů zobrazení, ale s dodatečnými vlastnostmi a metodami pro
ovládání časové osy filmových klipů. V této kapitole se dozvíte jak pomocí jazyka ActionScript ovládat přehrávání
filmových klipů a dynamicky vytvářet filmové klipy.
Základy filmových klipů
Úvod k práci s filmovými klipy
Filmové klipy jsou klíčovým prvkem pro lidi tvořící animovaný obsah pomocí vývojového nástroje Flash a chtějí
ovládat tento obsah pomocí jazyka ActionScript. Vždy, když vytvoříte filmový klip v programu Flash, přidá se symbol
do knihovny dokumentu Flash. Při výchozím nastavení se tento symbol stane instancí třída MovieClip, a jako taková
má vlastnosti a metody třídy MovieClip.
Jakmile umístíte instanci filmového klipu do vymezené plochy, filmový klip se začne automaticky odvíjet po své časové
ose (pokud má více než jeden snímek), dokud nebude přehrávání zrušeno kódem ActionScript. Právě tato časová osa
rozlišuje třídu MovieClip a umožňuje tak vytvořit animaci prostřednictvím doplnění pohybu nebo tvaru ve vývojovém
nástroji Flash. Naproti tomu u objektu zobrazení, který je instancí třídy Sprite, vytvoříte animaci pouze
naprogramováním změny hodnot daného objektu.
V předchozích verzích jazyka ActionScript byla třída MovieClip základní třídou všech instancí ve vymezené ploše. V
jazyku ActionScript 3.0 je filmový klip pouze jedním z mnoha objektů zobrazení, které se mohou objevit na obrazovce.
Není-li časová osa pro funkci objektu zobrazení nutná, může použití třídy Shape nebo třídy Sprite místo třídy
MovieClip zlepšit výkon vykreslování. Další informace o výběru vhodného objektu zobrazení viz „Výběr podtřídy
DisplayObject“ na stránce 284.
Běžné úlohy filmového klipu
V této kapitole jsou popsány následující běžné úlohy filmového klipu:
• Spouštění a zastavování filmových klipů
• Přehrávání filmových klipů pozpátku
• Přesun přehrávací hlavy na určité místo na časové ose filmového klipu
• Práce s popisy snímků v jazyku ActionScript
• Přístup k informacím o scéně v jazyku ActionScript
• Vytváření instancí symbolů filmových klipů z knihovny pomocí jazyka ActionScript
• Načítání a ovládání externích souborů SWF, včetně souborů vytvořených pro předchozí verze programu Flash
Player
• Vytvoření systému ActionScript pro tvorbu grafických datových zdrojů pro načtení a používání při běhu
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 399
Práce s filmovými klipy
Důležité pojmy a termíny
Následující referenční seznam obsahuje důležité termíny používané v této kapitole:
• AVM1 SWF: soubor SWF vytvořený pomocí kódu ActionScript 1.0 nebo ActionScript 2.0, obvykle se zaměřením
na verzi Flash Player 8 nebo dřívější.
• AVM2 SWF: Soubor SWF vytvořený pomocí kódu ActionScript 3.0 pro verzi Flash Player 9 nebo pozdější či
aplikaci Adobe AIR.
• Externí SWF: soubor SWF, který je vytvořený zvlášť ze souboru SWF projektu a určený k načtení do souboru SWF
projektu a přehrávaný v tomto souboru SWF.
• Snímek: nejmenší dílek času na časové ose. Podobně jako u filmového pásu filmu má každý snímek podobu
fotografického snímku animace v čase a když jsou snímky přehrávány rychle za sebou, vzniká efekt animace.
• Časová osa: metaforické vyjádření série snímků, které tvoří animační sekvenci filmového klipu. časová osa objektu
MovieClip je obdobou časové osy ve vývojovém nástroji Flash.
• Přehrávací hlava: ukazatel udávající umístění (snímek) na časové ose, který je v daném okamžiku zobrazen.
Procházení příkladů v kapitole
Jak budete procházet tuto kapitolu, možná si budete chtít sami vyzkoušet některé z uvedených příkladů kódů. Protože
tato kapitola pojednává o práci s filmovými klipy v jazyku ActionScript, tak v podstatě všechny kódy uvedené v této
kapitole jsou napsány za účelem manipulace se symbolem filmového klipu, který byl vytvořen a umístěn do vymezené
plochy. Při zkoušení ukázky budete potřebovat zobrazit výsledek v přehrávači Flash Player nebo AIR, abyste viděli
účinky kódu na symbol. Návod na vyzkoušení kódů uvedených v této kapitole:
1 Vytvořte prázdný dokument Flash.
2 Vyberte klíčový snímek na časové ose.
3 Otevřete panel Akce a zkopírujte uvedený kód do dílčího panelu Script.
4 Vytvořte ve vymezené ploše instanci symbolu filmového klipu. Například nakreslete tvar, vyberte jej, zvolte příkaz
Změnit > Převést na symbol... a pojmenujte symbol.
5 V Inspektoru vlastností vyberte filmový klip a dejte mu název instance. Název by se měl shodovat s názvem
používaným pro daný filmový klip v kódu z příkladu – např. jestliže kód manipuluje s filmovým klipem s názvem
myMovieClip, měli byste instanci svého filmového klipu pojmenovat také myMovieClip.
6 Spusťte program pomocí příkazu Ovládání > Testovat film.
Na obrazovce uvidíte výsledky kódu manipulujícího s filmovým klipem, jak je uveden v příkladu v kapitole.
Další techniky vyzkoušení ukázek kódů jsou podrobněji vysvětleny v části „Testování příkladů kódu v této kapitole“
na stránce 34.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 400
Práce s filmovými klipy
Práce s objekty MovieClip
Při publikování souboru SWF program Flash převede všechny instance symbolů filmových klipů ve vymezené ploše
na objekty MovieClip. Symbol filmového klipu můžete zpřístupnit pro jazyk ActionScript tak, že mu dáte název
instance v poli Název instance v Inspektoru vlastností. Jakmile je vytvořen soubor SWF, program Flash vygeneruje
kód, který vytvoří instanci MovieClip ve vymezené ploše a deklaruje proměnnou pomocí uvedeného názvu instance.
Máte-li pojmenované filmové klipy vnořené v jiných pojmenovaných filmových klipech, bude s těmito podřízenými
filmovými klipy zacházeno jako s vlastnostmi nadřízeného filmového klipu – k podřízenému filmovému klipu se
můžete dostat pomocí tečkové syntaxe. Například, je-li filmový klip s názvem instance childClip vnořen do jiného
klipu s názvem instance parentClip, můžete přehrávání animace časové osy podřízeného klipu spustit vyvoláním
následujícího kódu:
parentClip.childClip.play();
Poznámka: : K podřízeným instancím umístěným na vymezenou plochu ve zdrojovém nástroji Flash nemůže být
přistupováno z kódu zevnitř konstruktoru nadřazené instance, protože nebyly v tomto bodu vytvořeny vykonáním kódu.
Před přístupem k potomkovi musí rodič buď kódem vytvořit dceřinou instanci nebo pozdržet přístup do funkce callback,
která čeká než potomek vyšle událost Event.ADDED_TO_STAGE.
Zatímco některé starší metody a vlastnosti třídy MovieClip jazyka ActionScript 2.0 zůstávají stejné, jiné se změnily.
Všechny vlastnosti s předponou v podobě podtržítka byly přejmenovány. Například k vlastnostem _width a _height
se nyní dostanete přes názvy width a height, zatímco vlastnosti _xscale a _yscale mají nyní názvy scaleX a
scaleY. Kompletní seznam vlastností a metod třídy MovieClip najdete v Referenční příručce jazyka ActionScript 3.0
a jeho součástí.
Ovládání přehrávání filmových klipů
Program Flash používá metaforu časové osy k zajištění animace nebo změny stavu. Každý vizuální objekt, který
používá časovou osu, musí být buď objekt MovieClip nebo rozšíření třídy MovieClip. Zatímco jazyk ActionScript
může filmový klip zastavit, přehrát nebo přejít na jiné místo na časové ose, nelze ho použít k dynamickému vytvoření
časové osy nebo přidání obsahu na určité snímky. Toto je možné pouze pomocí vývojového nástroje Flash.
Když se objekt MovieClip přehrává, postupuje podél své časové osy rychlostí předepsanou rychlostí snímků souboru
SWF. Toto nastavení můžete potlačit nastavením vlastnosti Stage.frameRate v jazyku ActionScript.
Spouštění a zastavování přehrávání filmových klipů
Metody play() a stop() umožňují základní ovládání filmového klipu napříč jeho časovou osou. Například
předpokládejme, že máte ve vymezené ploše symbol filmového klipu, který obsahuje animaci bicyklu pohybujícího se
po obrazovce, s názvem instance nastaveným na bicycle. Přidáte-li k některému klíčovému snímku na hlavní časové
ose následující kód,
bicycle.stop();
bicykl se nebude pohybovat (jeho animace se nebude přehrávat). Pohyb bicyklu by mohl začít na základě nějaké jiné
interakce s uživatelem. Kdybyste například měli tlačítko s názvem startButton, následující kód na klíčovém snímku
na hlavní časové ose by to obstaral tak, že po klepnutí na toto tlačítko by se animace začala přehrávat:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 401
Práce s filmovými klipy
// This function will be called when the button is clicked. It causes the
// bicycle animation to play.
function playAnimation(event:MouseEvent):void
{
bicycle.play();
}
// Register the function as a listener with the button.
startButton.addEventListener(MouseEvent.CLICK, playAnimation);
Rychlý posun dopředu a přetáčení
Metody play() a stop() nepředstavují jediný způsob ovládání přehrávání ve filmovém klipu. Přehrávací hlavu
můžete posouvat po časové ose dopředu nebo přetáčet také ručně, pomocí metod nextFrame() a prevFrame().
Vyvoláním jedné z těchto metod zastavíte přehrávání a posunete přehrávací hlavu o jeden snímek dopředu, resp. zpět.
Použití metody play() je odpovídá vyvolání metody nextFrame() při každém spuštění události enterFrame objektu
filmového klipu. Na základě toho byste mohli zajistit zpětné přehrávání filmového klipu bicycle tak, že byste vytvořili
posluchač události pro událost enterFrame a sdělili klipu bicycle, aby se vrátil k předcházejícímu snímku ve funkci
posluchače následujícím způsobem:
// This function is called when the enterFrame event is triggered, meaning
// it's called once per frame.
function everyFrame(event:Event):void
{
if (bicycle.currentFrame == 1)
{
bicycle.gotoAndStop(bicycle.totalFrames);
}
else
{
bicycle.prevFrame();
}
}
bicycle.addEventListener(Event.ENTER_FRAME, everyFrame);
Jestliže v běžném přehrávání filmový klip obsahuje více než jeden snímek, vytvoří při přehrávání nekonečnou smyčku.
To znamená, že jakmile přejde přes poslední snímek, vrátí se zpět ke Snímku 1. Při použití metod prevFrame() nebo
nextFrame() k tomuto nedojde automaticky (vyvolání metody prevFrame(), když je přehrávací hlava na Snímku 1
neposune přehrávací hlavu na poslední snímek). Podmínka if ve výše uvedeném příkladu kontroluje, zda se již
přehrávací hlava dostala zpět k prvnímu snímku, a nastaví ji dopředu na poslední snímek, čímž efektivně vytvoří
nekonečnou smyčku filmového klipu přehrávaného pozpátku.
Skok na jiný snímek a používání popisů snímků
Poslání filmového klipu na nový snímek je jednoduchá záležitost. Vyvolání metody gotoAndPlay() nebo
gotoAndStop() způsobí skok filmového snímku na číslo snímku uvedené v parametru. Můžete také předat řetězec,
který se shoduje s názvem popisu snímku. Popis můžete přiřadit libovolnému snímku na časové ose. Provedete to tak,
že vyberete určitý snímek na časové ose a v Inspektoru vlastností zadáte do pole Popis snímku jeho název.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 402
Práce s filmovými klipy
Výhody používání popisů snímků místo čísel jsou zřejmé zejména při vytváření složitých filmových klipů. Když máte
v animaci příliš velký počet snímků, hodně vrstev a doplnění, zvažte popsání důležitých snímků vysvětlujícími popisy,
které budou představovat posuny v chování filmového klipu (např. „vypnuto“, „chůze“ nebo „běh“). Tím se zlepší
srozumitelnost kódu a také se tím zajistí pružnost, protože volání kódu ActionScript pro přechod na pojmenovaný
snímek jsou spíše ukazatelem na jediný odkaz – popis – než na konkrétní číslo snímku. Když se potom později
rozhodnete přesunout určitý segment animace na jiný snímek, nebudete muset měnit kód ActionScript, pokud
zachováte stejný popis pro snímky i na novém místě.
Jazyk ActionScript 3.0 obsahuje třídu FrameLabel, která umožňuje zastoupení popisů snímků v kódu. Každá instance
této třídy představuje jeden popis snímku a má vlastnost name představující název popisu snímku, jak je uveden v
Inspektoru vlastností, a vlastnost frame představující číslo snímku, na kterém je popis umístěn na časové ose.
Třída MovieClip obsahuje dvě vlastnosti, které vrací přímo objekty FrameLabel, aby byl umožněn přístup k instancím
FrameLabel souvisejícím s instancí filmového klipu. Vlastnost currentLabels vrací pole tvořené všemi objekty
FrameLabel na celé časové ose filmového klipu. Vlastnost currentLabel vrací řetězec obsahující název popisu
snímku, na který přehrávač na časové ose naposled narazil.
Dejme tomu, že jste vytvořili filmový klip s názvem robot a popsali jste různé stavy jeho animace. Mohli byste nastavit
podmínku, která by kontrolovala vlastnost currentLabel za účelem přístupu k aktuálnímu stavu klipu robot, jako v
následujícím kódu:
if (robot.currentLabel == "walking")
{
// do something
}
Práce se scénami
Ve vývojovém prostředí Flash můžete používat scény k vymezení série časových os, jimiž bude soubor SWF procházet.
Pomocí parametru metod gotoAndPlay() nebo gotoAndStop() můžete určit scénu, na kterou se má poslat
přehrávací hlava. Všechny soubory FLA začínají pouze počáteční scénou, můžete však vytvořit nové scény.
Používání scén není vždy nejlepším přístupem, protože scény mají několik nevýhod. Dokument Flash, který obsahuje
více scén, může být obtížné spravovat, zvláště v prostředích s více autory. Více scén může být také neefektivních v šířce
pásma, protože během publikování se všechny scény sloučí do jedné časové osy. To způsobí postupné stahování všech
scén, i kdyby nebyly vůbec přehrávány. Z těchto důvodů se od používání scén často odrazuje, kromě případů
uspořádání více delších animací na bázi časové osy.
Vlastnost scenes třídy MovieClip vrací pole objektů Scene představujících všechny scény v souboru SWF. Vlastnost
currentScene vrací objekt Scene, který představuje aktuálně přehrávanou scénu.
Třída Scene má několik vlastností poskytujících informace o dané scéně. Vlastnost labels vrací pole objektů
FrameLabel představujících popisy snímků v dané scéně. Vlastnost name vrací název dané scény v podobě řetězce.
Vlastnost numFrames vrací číslo typu int představující celkový počet snímků ve scéně.
Vytváření objektů MovieClip pomocí kódu ActionScript
Jedním způsobem, jak v programu Flash přidat obsah na obrazovku, je přetažením datových zdrojů z knihovny do
vymezené plochy, není to však jediný pracovní postup. U komplexních projektů dávají zkušení vývojoví pracovníci
většinou přednost vytváření filmových klipů programováním. Tento přístup přináší několik výhod: snadnější
opakované používání kódu, kratší dobu kompilace a propracovanější úpravy, které jsou dostupné pouze v jazyku
ActionScript.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 403
Práce s filmovými klipy
API se seznamem zobrazení jazyka ActionScript 3.0 redukuje proces dynamického vytváření objektů MovieClip.
Schopnost přímé konkretizace instance MovieClip, odděleně od procesu jejího přidání do seznamu zobrazení,
zajišťuje pružnost a jednoduchost bez nutnosti vzdát se kontroly.
Když v jazyku ActionScript 3.0 programově vytváříte instanci filmového klipu (nebo jakéhokoli jiného objektu
zobrazení), nebude na obrazovce viditelná, dokud ji nepřidáte do seznamu zobrazení vyvoláním metody addChild()
nebo addChildAt() na kontejneru objektu zobrazení. To umožňuje vytvořit filmový klip, nastavit jeho vlastnosti,
dokonce i vyvolat metody ještě před vykreslením na obrazovku. Další informace o práci se seznamem zobrazení viz
„Práce s kontejnery objektů zobrazení“ na stránce 273.
Exportování symbolů knihovny pro kód ActionScript
Při výchozím nastavení nelze instance symbolů filmových klipů v knihovně dokumentu Flash vytvářet dynamicky (tj.
vytvářet pouze pomocí kódu ActionScript). Důvodem je, že každý symbol, který je exportován pro použití v jazyku
ActionScript, zvětší velikost souboru SWF a připouštíme, že některé symboly nemusí být určeny pro použití ve
vymezené ploše. Z toho důvodu je třeba určit, že by měl být symbol exportován pro jazyk ActionScript, aby byl v jazyku
ActionScript dostupný.
Postup exportování symbolu pro jazyk ActionScript:
1 Vyberte symbol na panelu Knihovna a otevřete jeho dialogové okno Vlastnosti symbolu.
2 V případě potřeby aktivujte nastavení Pokročilé.
3 V části Navázání aktivujte zaškrtávací pole Exportovat pro ActionScript.
Tím se aktivují pole Třída a Základní třída.
Při výchozím nastavení je pole Třída zaplněno názvy symbolů s odstraněnými přebytečnými mezerami (např.
symbol s názvem „Tree House“ bude mít podobu „TreeHouse“). Chcete-li určit, že by měl symbol pro své chování
používat vlastní třídu, zadejte do pole celý název této třídy, včetně jejího balíčku. Chcete-li mít možnost vytvářet
instance symbolu v jazyku ActionScript, ale nepotřebujete přidávat žádné dodatečné chování, můžete tento název
třídy ponechat tak, jak je.
Pole Základní třída bude nastaveno na výchozí hodnotu flash.display.MovieClip. Chcete-li, aby váš symbol
rozšiřoval funkce jiné vlastní třídy, můžete zde určit název dané třídy, pokud tato třída rozšiřuje třídu Sprite (nebo
MovieClip).
4 Chcete-li uložit změny, stiskněte tlačítko OK.
Jestliže v této chvíli nemůže program Flash najít externí soubor ActionScript s definicí pro určenou třídu (např.
pokud jste nepotřebovali přidávat dodatečné chování pro symbol), zobrazí se upozornění:
V cestě tříd (classpath) nelze nalézt definici pro tuto třídu, proto se bude při exportu automaticky generovat v souboru SWF.
Pokud váš symbol knihovny nevyžaduje jedinečné funkce přesahující funkce třídy MovieClip, můžete toto
upozornění ignorovat.
Jestliže neposkytnete pro svůj symbol třídu, vytvoří program Flash pro váš symbol třídu ekvivalentní k následující
třídě:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 404
Práce s filmovými klipy
package
{
import flash.display.MovieClip;
public class ExampleMovieClip extends MovieClip
{
public function ExampleMovieClip()
{
}
}
}
Jestliže chcete k vašemu symbolu přidat další funkce jazyka ActionScript, přidejte příslušné vlastnosti a metody ke
kódu s následující strukturou. Předpokládejme například, že máte symbol filmového klipu obsahující kruh o šířce 50
obr. bodů a výšce 50 obr. bodů a tento symbol je určen pro export pro jazyk ActionScript s třídou s názvem Circle.
Vložíte-li následující kód do souboru Circle.as, rozšíří třídu MovieClip a poskytne symbol s dodatečnými metodami
getArea() a getCircumference():
package
{
import flash.display.MovieClip;
public class Circle extends MovieClip
{
public function Circle()
{
}
public function getArea():Number
{
// The formula is Pi times the radius squared.
return Math.PI * Math.pow((width / 2), 2);
}
public function getCircumference():Number
{
// The formula is Pi times the diameter.
return Math.PI * width;
}
}
}
Následující kód, umístěný na klíčový snímek na Snímku 1 dokumentu Flash, vytvoří instanci symbolu a zobrazí ji na
obrazovce:
var c:Circle = new Circle();
addChild(c);
trace(c.width);
trace(c.height);
trace(c.getArea());
trace(c.getCircumference());
Tento kód ukazuje konkretizaci na bázi kódu ActionScript jako alternativu k přetahování jednotlivých datových
zdrojů do vymezené plochy. Vytvoří kruh se všemi vlastnostmi filmového klipu i s metodami definovanými v třídě
Circle. Toto je velmi základní příklad – váš symbol knihovny může ve své třídě určovat libovolný počet vlastností a
metod.
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 405
Práce s filmovými klipy
Konkretizace na bázi kódu ActionScript je výkonná, protože umožňuje dynamicky vytvářet velká množství instancí,
které by byly příliš obtížné uspořádat ručně. Je také flexibilní, protože si můžete přizpůsobit jednotlivé vlastnosti
instance během jejího vytváření. Obě tyto výhody můžete pochopit při použití smyčky k dynamickému vytvoření
několika instancí třídy Circle. Na základě předchozího popisu symbolu a třídy Circle ve vaší knihovně dokumentu
Flash umístěte na klíčový snímek na Snímku 1 následující kód:
import flash.geom.ColorTransform;
var totalCircles:uint = 10;
var i:uint;
for (i = 0; i < totalCircles; i++)
{
// Create a new Circle instance.
var c:Circle = new Circle();
// Place the new Circle at an x coordinate that will space the circles
// evenly across the Stage.
c.x = (stage.stageWidth / totalCircles) * i;
// Place the Circle instance at the vertical center of the Stage.
c.y = stage.stageHeight / 2;
// Change the Circle instance to a random color
c.transform.colorTransform = getRandomColor();
// Add the Circle instance to the current timeline.
addChild(c);
}
function getRandomColor():ColorTransform
{
// Generate random values for the red, green, and blue color channels.
var red:Number = (Math.random() * 512) - 255;
var green:Number = (Math.random() * 512) - 255;
var blue:Number = (Math.random() * 512) - 255;
// Create and return a ColorTransform object with the random colors.
return new ColorTransform(1, 1, 1, 1, red, green, blue, 0);
}
Tento příklad ukazuje, jak můžete pomocí kódu rychle vytvořit a přizpůsobit si více instancí symbolu. Každá instance
je umístěna na základě aktuálního počtu v rámci smyčky a každé instanci je přidělena náhodná barva nastavením
vlastnosti transform (kterou třída Circle zdědí rozšířením třídy MovieClip).
Načítání externích souborů SWF
V jazyku ActionScript 3.0 jsou soubory SWF načítány pomocí třídy Loader. Chcete-li načíst externí soubor SWF, musí
váš kód ActionScript provést čtyři věci:
1 Vytvořte nový objekt URLRequest s URL souboru.
2 Vytvořte nový objekt Loader.
3 Vyvolejte metodu load() objektu Loader tak, že předáte instanci URLRequest jako parametr.
4 Vyvolejte metodu addChild() na kontejneru objektu zobrazení (např. hlavní časová osa dokumentu Flash) a
instance Loader bude přidána do seznamu zobrazení.
Nakonec bude kód vypadat takto:
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 406
Práce s filmovými klipy
var request:URLRequest = new URLRequest("http://www.[yourdomain].com/externalSwf.swf");
var loader:Loader = new Loader()
loader.load(request);
addChild(loader);
Tento stejný kód lze použít k načtení externího souboru obrazu, např. ve formátu JPEG, GIF nebo PNG, určením URL
souboru obrazu namísto určení URL souboru SWF. Soubor SWF může narozdíl od souboru obrazu obsahovat kód
ActionScript. I když tedy proces načítání souboru SWF může být totožný s načítáním obrázku, tak při načítání
externího souboru SWF musí být soubor SWF, který načítání provádí, i načítaný soubor SWF umístěny ve stejné
karanténě zabezpečení, jestliže přehrávač Flash Player nebo AIR provádí přehrávání SWF a vy plánujete k jakékoli
komunikaci s externím souborem SWF použít kód ActionScript. Navíc, obsahuje-li externí soubor SWF třídy, které
sdílejí stejný jmenný prostor jako třídy v načítajícím souboru SWF, budete možná muset vytvořit pro načtený soubor
SWF novou aplikační doménu, abyste se vyhnuli konfliktům jmenného prostoru. Další informace o posouzení
zabezpečení a aplikační domény viz „Použití třídy ApplicationDomain“ na stránce 641 a „Načítání souborů SWF a
obrazů“ na stránce 702.
Jakmile je externí soubor SWF úspěšně načten, můžete se k němu dostat prostřednictvím vlastnosti Loader.content.
Je-li externí soubor SWF publikován pro jazyk ActionScript 3.0, bude to buď filmový klip nebo pohyblivý symbol,
podle toho, kterou třídu rozšiřuje.
Posouzení načtení staršího souboru SWF
Jestliže byl soubor SWF publikován pomocí starší verze jazyka ActionScript, je třeba vzít v úvahu důležitá omezení.
Narozdíl od souboru SWF ActionScript 3.0, který běží v AVM2 (ActionScript Virtual Machine 2), soubor SWF
publikovaný pro ActionScript 1.0 nebo 2.0 běží v AVM1 (ActionScript Virtual Machine 1).
Jakmile je soubor SWF AVM1 úspěšně načten, načtený objekt (vlastnost Loader.content) bude objekt AVM1Movie.
Instance třídy AVM1Movie není stejná jako instance třídy MovieClip. Je to objekt zobrazení, ale narozdíl od filmového
klipu nezahrnuje metody ani vlastnosti na bázi časové osy. Nadřízený soubor SWF AVM2 nebude mít přístup k
vlastnostem, metodám ani objektům načteného objektu AVM1Movie.
Existují další omezení k otevření souboru SWF AVM1 načteného souborem SWF AVM2. Podrobnosti viz přehled
třídy AVM1Movie v Referenční příručce jazyka ActionScript 3.0 a jeho součástí.
Příklad: RuntimeAssetsExplorer
Export pro ActionScript může být výhodný zejména pro knihovny, které mohou být užitečné pro více projektů
současně. Jestliže přehrávač Flash Player nebo AIR provede soubor SWF, symboly, které byly exportovány do jazyka
ActionScript, budou dostupné pro libovolný soubor SWF ve stejné karanténě zabezpečení jako soubor SWF, který jej
načítá. Tímto způsobem může jeden dokument Flash vygenerovat soubor SWF, který má jediný účel – uchovávat
grafické datové zdroje. Tato technika je zvláště užitečná pro větší projekty, kde návrháři pracující na vizuálních
datových zdrojích mohou pracovat souběžně s vývojovými pracovníky, kteří vytvářejí „zabalovací“ soubor SWF, který
pak načte soubor SWF grafických datových zdrojů při běhu. Tuto metodu můžete používat ke správě série souborů
pro konkrétní verzi, kde grafické datové zdroje nejsou závislé na průběhu vývoje programování.
Aplikace RuntimeAssetsExplorer načte každý soubor SWF, který je podtřídou třídy RuntimeAsset a umožní procházet
dostupné datové zdroje tohoto souboru SWF. Příklad ukazuje následující:
• Načítání externích souborů SWF pomocí metody Loader.load()
• Dynamické vytvoření symbolu knihovny exportovaného pro ActionScript
• Ovládání přehrávání objektů MovieClip pomocí kódu ActionScript
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 407
Práce s filmovými klipy
Než začnete, zajistěte, aby každý soubor SWF, který chcete spustit v přehrávači Flash Player, byl umístěn ve stejné
karanténě zabezpečení. Další informace viz „Karantény zabezpečení“ na stránce 690
Aplikační soubory pro tuto ukázku najdete na adrese www.adobe.com/go/learn_programmingAS3samples_flash_cz.
Soubory aplikace RuntimeAssetsExplorer jsou umístěny ve složce Samples/RuntimeAssetsExplorer. Aplikace sestává
z následujících souborů:
Soubor
Popis
RuntimeAssetsExample.mxml
Uživatelské rozhraní pro aplikaci pro Flex (MXML)
nebo Flash (FLA).
nebo
RuntimeAssetsExample.fla
RuntimeAssetsExample.as
Třída dokumentu pro aplikaci Flash (FLA).
GeometricAssets.as
Ukázková třída, která implementuje rozhraní
RuntimeAsset.
GeometricAssets.fla
Soubor FLA připojený k třídě GeometricAssets (třída
dokumentu souboru FLA) obsahující symboly, které
jsou exportovány pro ActionScript.
com/example/programmingas3/runtimeassetexplorer/RuntimeLibrary.as
Rozhraní, které definuje vyžadované metody
očekávané od všech souborů SWF s datovými zdroji
za běhu, které budou načteny do kontejneru
průzkumníku.
com/example/programmingas3/runtimeassetexplorer/AnimatingBox.as
Třída symbolu knihovny ve tvaru rotujícího
čtverečku.
com/example/programmingas3/runtimeassetexplorer/AnimatingStar.as
Třída symbolu knihovny ve tvaru rotující hvězdy.
Zavedení rozhraní knihovny za běhu
Struktura knihoven datových zdrojů za běhu musí být formalizována, aby byla interakce průzkumníku s knihovnou
SWF správná. Toho dosáhnete vytvořením rozhraní, které je podobné třídě v tom, že je to plán metod, které vymezují
očekávanou strukturu, ale narozdíl od třídy nezahrnuje hlavní části metod. Toto rozhraní poskytuje způsob vzájemné
komunikace mezi knihovnou za běhu a průzkumníkem. Každý soubor SWF datových zdrojů za běhu, který je načtený
do prohlížeče, bude implementovat toto rozhraní. Další informace o rozhraních a způsobu jejich využití viz
„Rozhraní“ na stránce 104.
Rozhraní RuntimeLibrary bude velmi jednoduché – vyžaduje pouze funkci, která může dodat průzkumníku pole cest
pro třídy pro symboly, které budou exportovány a dostupné v knihovně za běhu. Pro tento účel má rozhraní jen jednu
metodu: getAssets().
package com.example.programmingas3.runtimeassetexplorer
{
public interface RuntimeLibrary
{
function getAssets():Array;
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 408
Práce s filmovými klipy
Vytváření souborů SWF knihovny datových zdrojů
Když definujete rozhraní RuntimeLibrary, můžete vytvářet více souborů SWF knihovny datových zdrojů, které je
možné načíst do jiného souboru SWF. Vytvoření individuální knihovny SWF datových zdrojů obnáší čtyři úlohy:
• Vytvoření třídy pro soubor SWF knihovny datových zdrojů
• Vytváření tříd pro jednotlivé datové zdroje obsažené v knihovně
• Vytváření aktuálních grafických datových zdrojů
• Přiřazování grafických elementů k třídám a publikování souborů SWF knihovny
Vytvoření třídy pro implementaci rozhraní RuntimeLibrary
Dále vytvoříme třídu GeometricAssets, která implementuje rozhraní runtimeLibrary. To bude třída dokumentu
souboru FLA. Kód pro tuto třídu je velmi podobný rozhraní RuntimeLibrary – rozdíl mezi nimi je v tom, že v definici
třídy má metoda getAssets() hlavní část metody.
package
{
import flash.display.Sprite;
import com.example.programmingas3.runtimeassetexplorer.RuntimeLibrary;
public class GeometricAssets extends Sprite implements RuntimeLibrary
{
public function GeometricAssets() {
}
public function getAssets():Array {
return [ "com.example.programmingas3.runtimeassetexplorer.AnimatingBox",
"com.example.programmingas3.runtimeassetexplorer.AnimatingStar" ];
}
}
}
Kdybychom měli vytvořit druhou knihovnu za běhu, mohli bychom vytvořit jiný soubor FLA na bázi jiné třídy (např.
AnimationAssets), která poskytuje svou vlastní implementaci metody getAssests().
Vytváření tříd pro jednotlivé datové zdroje MovieClip
Pro tento příklad pouze rozšíříme třídu MovieClip, aniž bychom k vlastním datovým zdrojům přidávali nějaké funkce.
Následující kód pro třídu AnimatingStar je obdobný jako pro třídu AnimatingBox:
package com.example.programmingas3.runtimeassetexplorer
{
import flash.display.MovieClip;
public class AnimatingStar extends MovieClip
{
public function AnimatingStar() {
}
}
}
PROGRAMOVÁNÍ V JAZYCE ACTIONSCRIPT 3.0 PRO APLIKACI FLASH 409
Práce s filmovými klipy
Publikování knihovny
Nyní připojíme datové zdroje na bázi třídy MovieClip k nové třídě tak, že vytvoříme nový soubor FLA a do pole Třída
dokumentu v Inspektoru vlastností zadáme GeometricAssets. Pro účely tohoto příkladu vytvoříme dva velmi základní
tvary, které pomocí doplnění časové osy provedou jedno natočení po směru hodinových ručiček v délce 360 snímků.
Symboly animatingBox i animatingStar jsou nastaveny na Export pro ActionScript a mají pole Třída nastavené na
příslušné cesty pro třídy určené v implementaci metody getAssets(). Výchozí základní třída balíčku
flash.display.MovieClip zůstává, neboť chceme vytvořit podtřídu se standardními metodami třídy MovieClip.
Po nastavení exportních voleb symbolu publikujte soubor FLA. Právě jste vytvořil svou první knihovnu za běhu. Tento
soubor SWF by mohl být načten do jiného souboru SWF AVM2 a pro tento nový soubor SWF by byly dostupné
symboly AnimatingBox a AnimatingStar.
Načtení knihovny do jiného souboru SWF
Nakonec se ještě musíme vypořádat s uživatelským rozhraním pro průzkumník datových zdrojů. V tomto příkladu je
cesta ke knihovně za chodu napevno zakódována jako proměnná s názvem ASSETS_PATH. Také byste mohli použít
např. třídu FileReference – k vytvoření rozhraní pro procházení konkrétního souboru SWF na vašem pevném disku.
Jakmile je knihovna za chodu úspěšně načtena, přehrávač Flash Player vyvolá metodu
runtimeAssetsLoadComplete():
private function runtimeAssetsLoadComplete(event:Event):void
{
var rl:* = event.target.content;
var assetList:Array = rl.getAssets();
populateDropdown(assetList);
stage.frameRate = 60;
}
Proměnná rl v této metodě představuje načtený soubor SWF. Kód vyvolá metodu getAssets() načteného souboru
SWF, obsahující seznam dostupných datových zdrojů, a jimi zaplní komponentu ComboBox vyvoláním metody
populateDropDown(). Tato metoda dále uloží celou cestu pro třídy každého datového zdroje. Klepnutí na tlačítko
Přidat na uživatelském rozhraní spustí metodu addAsset():
private
{
var
var
var
...
}
function addAsset():void
className:String = assetNameCbo.selectedItem.data;
AssetClass:Class = getDefinitionByName(className) as Class;
mc:MovieClip = new AssetClass();
která získá cestu pro třídy každého právě vybraného datového zdroje v komponentě ComboBox
(assetNameCbo.selectedItem.data) a pomocí funkce getDefinitionByName() (z balíčku flash.utils.package)
získá aktuální odkaz na třídu datového zdroje za účelem vytvoření nové instance daného zdroje.
410
Kapitola 19: Práce s doplněními pohyby
„Animace objektů“ na stránce 303 popisuje způsob implementace skriptované animace v jazyce ActionScrip

Podobné dokumenty

(zveřejněna 8. 9. 2011) PDF

(zveřejněna 8. 9. 2011) PDF složka s technickými metadaty – obsahuje pro každou naskenovanou stránku čísla časopisu 1 METS soubor (AMD_METS.xml). Záměrně nejsou tato metadata v hlavním METS záznamu (hlavni_METS.xml), protože ...

Více

Diplomový projekt

Diplomový projekt běžet jak v prostředí Microsoft Windows, Mac OS X, GNU/Linux, SGI IRIX nebo na jiných platformách UNIXu. Potřebuje pouze překladač C++ jazyka a knihovnu OpenGl (nebo jinou knihovnu, která implement...

Více

Ročníkový projekt

Ročníkový projekt Microsoft Windows, Mac OS X, GNU/Linux, SGI IRIX nebo na jiných platformách UNIXu. Potřebuje pouze překladač C++ jazyka a knihovnu OpenGl (nebo jinou knihovnu, která implementuje OpenGl API, jako j...

Více

ActionScript

ActionScript  Používání předdefinovaných objektů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55  Použití speciálních objektů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....

Více

Zobrazit nápovědu v souboru

Zobrazit nápovědu v souboru Některá zlepšení výkonu neznamenají znatelné zlepšení pro uživatele. Je důležité zaměřit optimalizaci výkonu do oblastí, které jsou problematické z pohledu vaší specifické aplikace. Některé způsoby...

Více

Zobrazit nápovědu v souboru

Zobrazit nápovědu v souboru Právní upozornění viz http://help.adobe.com/cs_CZ/legalnotices/index.html.

Více

Základy Adobe FLASH CS4 []

Základy Adobe FLASH CS4 [] jak vypadá tlačítko normálně,  jak vypadá při najeti myší,  při stisku tlačítka na myši,   oblast reakce myši. 

Více