Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
IDZ DO
IDZ DO
KATALOG KSI¥¯EK
KATALOG KSI¥¯EK
TWÓJ KOSZYK
TWÓJ KOSZYK
CENNIK I INFORMACJE
CENNIK I INFORMACJE
CZYTELNIA
CZYTELNIA
ActionScript. Przewodnik
encyklopedyczny
Autor: Colin Moock
T³umaczenie: Marek Binkowski, Ryszard Glego³a,
Bohdan G³êbocki, Rafa³ Joñca, Joanna Pasek,
Wojciech Pazdur
ISBN: 83-7197-903-7
Tytu³ orygina³u:
ActionScript The Definitive Guide
Format: B5, stron: 760
Flash jest ju¿ standardem dla sieciowych multimediów, dostêpnych dla ponad 250
milionów u¿ytkowników na ca³ym wiecie. Ksi¹¿ka „ActionScript. Przewodnik
encyklopedyczny” to pe³na dokumentacja jêzyka ActionScript — zorientowanego
obiektowo jêzyka programowania, bêd¹cego podstawowym narzêdziem tworzenia
zaawansowanych witryn internetowych dla programistów Flasha. Jest kierowana zarówno
do projektantów i grafików, którzy dopiero ucz¹ siê programowania, jak i do programistów
JavaScript, którzy chc¹ przenieæ swoje umiejêtnoci na jêzyk ActionScript (oba te jêzyki
opieraj¹ siê na tym samym standardzie ECMAScript).
Colin Moock nieraz ju¿ dowiód³ umiejêtnoci przekazywania swojej szerokiej wiedzy
w praktyczny i przystêpny sposób. W pe³ni zas³u¿y³ sobie na uznanie, jakim darz¹ go
u¿ytkownicy Flasha.
W pierwszej czêci ksi¹¿ki opisano podstawowe zagadnienia programistyczne (zmienne,
typy danych, operatory, wyra¿enia, funkcje, zdarzenia, tablice i obiekty), powiêcaj¹c du¿o
uwagi ich wykorzystaniu, szczególnie w obróbce klipów filmowych. Druga czêæ jest
powiêcona typowym zastosowaniom ActionScriptu, takim jak przetwarzanie formularzy
sieciowych. Trzecia czêæ, stanowi¹ca leksykon jêzyka, zawiera opis zmiennych
globalnych, w³aciwoci, metod, detektorów zdarzeñ i obiektów wraz z przyk³adami ich
u¿ycia.
Korzystaj¹c z tej ksi¹¿ki szybko opanujesz jêzyk ActionScript. Prócz teorii znajdziesz tu
praktyczne wskazówki i przyk³ady prezentuj¹ce tworzenie pól tekstowych, przycisków
menu, quizów, witryn opartych o dokumenty XML, gier, w których obowi¹zuj¹ zasady
praw fizyki, rodowisk dla wielu u¿ytkowników dzia³aj¹cych w czasie rzeczywistym i wielu
innych. Skrupulatne opisy poruszaj¹ wiele nieudokumentowanych lub niezbadanych
dotychczas tematów.
„
Najlepsza ksi¹¿ka o jêzyku ActionScript, jak¹ widzia³em. Trudno znaleæ gdzie indziej
wiêcej informacji na temat tego jêzyka”.
— Slavik Lozben, g³ówny in¿ynier Flasha w firmie Macromedia
Spis treści
Słowo wstępne.................................................................................................. 13
Wstęp ................................................................................................................ 17
Część I Podstawy ActionScript.........................................................23
Rozdział 1. Jeżeli nie jesteś programistą... ..................................................... 25
Kilka podstawowych zwrotów ............................................................................................. 27
Następne pojęcia ActionScript............................................................................................... 36
Budujemy quiz ...................................................................................................................... 44
Naprzód! ............................................................................................................................... 58
Rozdział 2. Zmienne......................................................................................... 59
Tworzenie zmiennych (deklaracja)........................................................................................ 60
Przypisywanie zmiennym wartości ...................................................................................... 62
Zmienianie i używanie wartości zmiennych ......................................................................... 63
Typy wartości........................................................................................................................ 65
Zakres zmiennej .................................................................................................................... 67
Kilka praktycznych przykładów ........................................................................................... 78
Naprzód! ............................................................................................................................... 79
Rozdział 3. Dane i typy danych ...................................................................... 81
Dane kontra informacje ......................................................................................................... 81
Znaczenie zależne od typu danych ....................................................................................... 82
4
Spis treści
Tworzenie i kategoryzacja danych ........................................................................................ 83
Konwersja typów danych...................................................................................................... 85
Dane proste i dane złożone ................................................................................................... 94
Naprzód! ............................................................................................................................... 95
Rozdział 4. Proste typy danych....................................................................... 97
Typ liczbowy ......................................................................................................................... 97
Liczby całkowite i liczby zmiennoprzecinkowe .................................................................... 97
Liczbowe wyrażenia proste................................................................................................... 98
Korzystanie z liczb w skryptach ActionScript..................................................................... 102
Typ łańcuchowy .................................................................................................................. 103
Korzystanie z łańcuchów w skryptach ActionScript........................................................... 108
Typ logiczny ........................................................................................................................ 126
Typ niezdefiniowany........................................................................................................... 129
Typ pusty, czyli null............................................................................................................ 130
Naprzód! ............................................................................................................................. 130
Rozdział 5. Operatory.................................................................................... 131
Ogólne cechy operatorów ................................................................................................... 131
Operator przypisania .......................................................................................................... 135
Operatory arytmetyczne ..................................................................................................... 136
Operatory równości i nierówności ...................................................................................... 140
Operatory porównania ........................................................................................................ 145
Operatory działające na łańcuchach .................................................................................... 149
Operatory logiczne .............................................................................................................. 149
Operator grupowania.......................................................................................................... 155
Przecinek jako operator....................................................................................................... 156
Operator void ...................................................................................................................... 156
Inne operatory ..................................................................................................................... 157
Naprzód! ............................................................................................................................. 160
Rozdział 6. Polecenia ..................................................................................... 161
Typy poleceń ....................................................................................................................... 162
Składnia poleceń.................................................................................................................. 162
Polecenia ActionScript......................................................................................................... 164
Polecenia i akcje................................................................................................................... 172
Naprzód! ............................................................................................................................. 172
Spis treści
5
Rozdział 7. Konstrukcje warunkowe............................................................. 173
Konstrukcja if ...................................................................................................................... 174
Konstrukcja else .................................................................................................................. 176
Konstrukcja else if ............................................................................................................... 177
Symulacja konstrukcji switch .............................................................................................. 178
Składnia krótkich konstrukcji warunkowych...................................................................... 180
Naprzód! ............................................................................................................................. 180
Rozdział 8. Pętle ............................................................................................ 181
Pętla while ........................................................................................................................... 181
Terminologia pętli ............................................................................................................... 184
Pętla do-while...................................................................................................................... 186
Pętla for ............................................................................................................................... 187
Pętla for-in ........................................................................................................................... 188
Przedwczesne zatrzymanie pętli ......................................................................................... 189
Pętle na listwie czasowej i pętle przypisane do zdarzeń klipów filmowych ...................... 192
Naprzód! ............................................................................................................................. 199
Rozdział 9. Funkcje ........................................................................................ 201
Tworzenie funkcji ................................................................................................................ 202
Uruchamianie funkcji .......................................................................................................... 202
Przekazywanie informacji funkcjom ................................................................................... 203
Opuszczanie funkcji i zwracane przez funkcje wartości ..................................................... 207
Funkcje jako wyrażenia proste ............................................................................................ 209
Dostępność funkcji i jej trwałość ......................................................................................... 210
Zakres funkcji ...................................................................................................................... 211
Jeszcze kilka słów o argumentach funkcji ........................................................................... 215
Funkcje rekurencyjne........................................................................................................... 219
Funkcje standardowe .......................................................................................................... 221
Funkcje jako obiekty............................................................................................................ 222
Wszystkie skrypty w jednym miejscu................................................................................. 223
Stary quiz po nowemu ........................................................................................................ 224
Naprzód! ............................................................................................................................. 227
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń ....................................... 229
Synchroniczne wykonanie kodu......................................................................................... 229
Asynchroniczne wykonanie kodu oparte na zdarzeniach................................................... 230
Rodzaje zdarzeń .................................................................................................................. 230
Procedury obsługi zdarzeń ................................................................................................. 231
6
Spis treści
Składnia procedur obsługi zdarzeń..................................................................................... 231
Tworzenie procedur obsługi zdarzeń ................................................................................. 232
Zasięg procedur obsługi zdarzeń ........................................................................................ 235
Zdarzenia dla przycisków ................................................................................................... 239
Przegląd zdarzeń klipów filmowych................................................................................... 243
Zdarzenia klipowe związane z odtwarzaniem filmu.......................................................... 244
Klipowe zdarzenia generowane przez użytkownika .......................................................... 250
Kolejność wykonywania...................................................................................................... 255
Kopiowanie procedur obsługi zdarzeń klipowych ............................................................. 257
Odświeżanie ekranu przy użyciu updateAferEvent........................................................... 258
Dynamiczne procedury obsługi zdarzeń klipów filmowych .............................................. 259
Zastosowanie procedur obsługi zdarzeń ............................................................................ 260
Naprzód! ............................................................................................................................. 262
Rozdział 11. Tablice ....................................................................................... 263
Czym jest tablica?................................................................................................................ 263
Anatomia tablicy ................................................................................................................. 264
Jak tworzymy tablice? ......................................................................................................... 265
Odwołujemy się do elementów tablicy ............................................................................... 268
Rozmiar tablicy.................................................................................................................... 270
Elementy indeksowane nazwami........................................................................................ 272
Dodajemy elementy do tablicy............................................................................................ 273
Usuwamy elementy z tablicy .............................................................................................. 278
Przetwarzanie zawartości tablic .......................................................................................... 282
Tablice wielowymiarowe .................................................................................................... 287
Quiz z pytaniami do wyboru, ujęcie 3. ............................................................................... 288
Naprzód! ............................................................................................................................. 289
Rozdział 12. Obiekty i klasy ......................................................................... 291
Anatomia obiektu................................................................................................................ 294
Tworzymy instancje obiektów ............................................................................................ 295
Właściwości obiektów ......................................................................................................... 296
Metody ................................................................................................................................ 297
Klasy i programowanie zorientowane obiektowo .............................................................. 301
Standardowe obiekty i klasy języka ActionScript ............................................................... 316
Naprzód! ............................................................................................................................. 318
Spis treści
7
Rozdział 13. Klipy filmowe ........................................................................... 319
„Obiektowość” klipów filmowych ...................................................................................... 320
Typy klipów filmowych ...................................................................................................... 321
Tworzymy klipy filmowe.................................................................................................... 324
Kolejność filmów i klonów w stosie.................................................................................... 331
Odwołania do klonów oraz filmów głównych.................................................................... 338
Usuwamy klony klipów i całe filmy ................................................................................... 351
Standardowe właściwości klipów filmowych ..................................................................... 354
Metody klipów filmowych .................................................................................................. 355
Praktyczne zastosowania klipów filmowych ...................................................................... 360
Quiz: ostatnia odsłona......................................................................................................... 364
Naprzód! ............................................................................................................................. 367
Rozdział 14. Struktura leksykalna ................................................................ 369
Białe spacje .......................................................................................................................... 369
Zakończenia instrukcji (średniki) ........................................................................................ 370
Komentarze ......................................................................................................................... 372
Słowa kluczowe................................................................................................................... 373
Identyfikatory...................................................................................................................... 374
Rozróżnianie wielkości liter ................................................................................................ 375
Naprzód! ............................................................................................................................. 376
Rozdział 15. Tematy zaawansowane ............................................................ 377
Kopiowanie, porównywanie i przekazywanie danych ....................................................... 377
Wykorzystywanie operacji na bitach................................................................................... 380
Zagadnienia związane z zakresem funkcji.......................................................................... 390
Typ danych „klip filmowy” ................................................................................................ 392
Naprzód! ............................................................................................................................. 392
Część II ActionScript w praktyce ................................................... 393
Rozdział 16. ActionScript; środowisko pracy............................................... 395
Panel Actions....................................................................................................................... 395
Umieszczanie skryptów w klatkach.................................................................................... 398
Umieszczanie skryptów w przyciskach .............................................................................. 399
Umieszczanie skryptów w klipach filmowych.................................................................... 400
Gdzie jest kod? .................................................................................................................... 401
Efektywność pracy .............................................................................................................. 402
8
Spis treści
Korzystanie z zewnętrznych skryptów ............................................................................... 403
Klipy filmowe typu Smart Clip ........................................................................................... 405
Naprzód! ............................................................................................................................. 413
Rozdział 17. Interaktywne formularze.......................................................... 415
Obieg danych w formularzu Flasha .................................................................................... 415
Tworzenie interaktywnego formularza............................................................................... 418
Naprzód! ............................................................................................................................. 424
Rozdział 18. Pola tekstowe ........................................................................... 425
Dynamiczne pola tekstowe ................................................................................................. 425
Wejściowe pola tekstowe .................................................................................................... 427
Opcje pól tekstowych .......................................................................................................... 428
Właściwości pól tekstowych ............................................................................................... 432
Obsługa języka HTML ........................................................................................................ 434
Zaznaczanie fragmentów tekstów w polach tekstowych.................................................... 442
Puste pola tekstowe i pętla for-in........................................................................................ 442
Naprzód! ............................................................................................................................. 443
Rozdział 19. Usuwanie błędów...................................................................... 445
Narzędzia do wyszukiwania błędów.................................................................................. 446
Zasady testowania programów........................................................................................... 451
Naprzód! ............................................................................................................................. 455
Część III Leksykon ........................................................................... 457
Dodatki ............................................................................................. 713
Dodatek A Flash w Internecie ....................................................................... 715
Dodatek B Zakres i kody znaków kodowania Latin 1................................ 719
Dodatek C Zgodność z poprzednimi wersjami ............................................. 731
Dodatek D Różnice między ActionScript a ECMA-262 i JavaScript .......... 737
Skorowidz ....................................................................................................... 741
10
Zdarzenia i moduły
obsługi zdarzeń
Dowiedzieliśmy się sporo o pisaniu instrukcji wykonywanych przez interpreter Action-
Script. Potrafimy już prawidłowo powiedzieć interpreterowi co chcemy zrobić, ale jak
przekazać mu, kiedy wykonać te operacje? Kod ActionScript nie wywołuje się tak po
prostu sam z siebie — coś zawsze powoduje jego wykonanie.
Tym „czymś” może być zarówno synchroniczne odtwarzanie filmu, jak również prede-
finiowane asynchroniczne zdarzenia.
Synchroniczne wykonanie kodu
Podczas odtwarzania filmu wskaźnik odtwarzania przemieszcza się od klatki do klatki.
Za każdym razem gdy dociera do nowej klatki, interpreter wykonuje kod dołączony do
niej. Po wykonaniu kodu następuje odświeżenie ekranu oraz odtworzenie dźwięku.
Później wskaźnik przechodzi do następnej klatki.
Na przykład jeśli umieścimy kod w klatce 1., zostanie on wykonany, zanim klatka będzie
wyświetlona. Jeśli kolejny blok kodu umieścimy w klatce 5. (będącej klatką kluczową)
w tym samym filmie, to najpierw zostaną wyświetlone klatki od 1. do 4., następnie będzie
wykonany kod zawarty w klatce 5., po czym zostanie ona wyświetlona. Kolejność wy-
konywania kodu w klatkach 1. oraz 5. nazywamy synchroniczną, ponieważ następuje
w sposób liniowy, wynikający z kolejności klatek na listwie czasu.
Cały kod przypisany do klatek w filmie jest wykonywany synchronicznie. Nawet jeśli
niektóre klatki nie są odtwarzane w kolejności z powodu instrukcji gotoAndPlay( ) lub
gotoAndStop( ), kod związany z każdą klatką jest wykonywany w przewidywalnym po-
rządku związanym z ruchem wskaźnika odtwarzania.
230
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
Asynchroniczne wykonanie kodu
oparte na zdarzeniach
Niektóre części kodu nie są wykonywane w przewidywalnej kolejności. Ich wykonanie
następuje, kiedy interpreter ActionScript wykryje, że miało miejsce jedno z predefinio-
wanych zdarzeń. Wiele zdarzeń jest związanych z określonymi działaniami użytkownika
(jak kliknięcie myszą czy naciśnięcie klawisza na klawiaturze). Tak jak głowica odtwa-
rzająca, docierając do klatki, wywołuje kod z nią związany, tak samo wystąpienie zda-
rzeń powoduje wykonanie kodu związanego ze zdarzeniami. Kod oparty na zdarzeniach
(czyli taki, który jest wykonywany po wystąpieniu zdarzenia) jest określany jako wyko-
nywany asynchronicznie, ponieważ jego uruchomienie nie następuje w określonym mo-
mencie filmu, a raczej w momencie, w którym wystąpi określone zdarzenie.
Programowanie synchroniczne wymaga na początek ustalenia czasu wykonywania kodu.
Natomiast programowanie asynchroniczne pozwala dynamicznie reagować na zachodzące
zdarzenia. Asynchroniczne wykonywanie kodu ma kluczowe znaczenie dla ActionScript
i dla tworzenia interaktywności.
W rozdziale tym znajdziesz wiadomości na temat tworzenia kodu opartego na zdarzeniach
oraz zestawienie różnych predefiniowanych zdarzeń, obsługiwanych przez ActionScript.
Rodzaje zdarzeń
Teoretycznie zdarzenia możemy podzielić na dwa rodzaje:
zdarzenia użytkownika
wywoływane przez działania użytkownika (kliknięcie myszą lub naciśnięcie klawisza),
zdarzenia systemowe
będące wynikiem odtwarzania filmu (pojawienie się klipu filmowego na scenie lub
załadowanie z zewnętrznego pliku serii zmiennych).
W ActionScript nie ma różnic syntaktycznych między zdarzeniami użytkownika a zda-
rzeniami systemowymi. Zdarzenia systemowe są mniej ewidentne niż klinięcie myszą
przez użytkownika. Chociaż moglibyśmy nie traktować na przykład usunięcia klipu fil-
mowego ze sceny jako pełnoprawnego zdarzenia, to jednak możliwość reagowania na
zdarzenia systemowe daje poważne narzędzie kontroli odtwarzania filmu.
Zdarzenia w ActionScript mogą być również podzielone bardziej praktycznie ze względu
na obiekty, do których są przypisane. Wszystkie zdarzenia występują w powiązaniu
z określonymi obiektami w środowisku Flasha. Interpreter nie uważa, że „użytkownik
kliknął”, lecz „użytkownik kliknął ten przycisk” lub „użytkownik kliknął, kiedy ten klip
filmowy znajdował się na scenie”. I podobnie interpreter nie stwierdza: „otrzymano dane”,
lecz „ten klip filmowy otrzymał jakieś dane”. Tak więc opisujemy kod odpowiadający na
zdarzenia za pomocą obiektów, do których te zdarzenia są przypisane.
Składnia procedur obsługi zdarzeń
231
Obiekty ActionScript, które mogą odbierać zdarzenia to:
• klipy filmowe,
• przyciski,
• obiekty klas XML oraz XMLSocket.
W tym rozdziale dowiemy się, że ActionScript w rzeczywistości posiada dwie różne imple-
mentacje obsługi zdarzeń: jedną dla zdarzeń związanych z klipami filmowymi i przyci-
skami oraz drugą skojarzoną ze wszystkimi pozostałymi rodzajami obiektów.
Procedury obsługi zdarzeń
Nie każde zdarzenie powoduje wykonanie kodu. Zdarzenia często mają miejsce bez jakie-
gokolwiek wpływu na odtwarzanie filmu. Przykładowo użytkownik może generować
dziesiątki zdarzeń, klikając raz za razem przycisk, ale te kliknięcia będą ignorowane.
Dlaczego? Ponieważ zdarzenia same nie mogą tworzyć kodu — to my musimy napisać
najpierw kod odpowiadający na zdarzenie. Aby powiadomić interpreter, by wykonał kod
w odpowiedzi na zdarzenie, musimy dodać do niego procedurę obsługi zdarzenia (event
handler) opisującą akcję, która ma zostać podjęta.
Procedura obsługi zdarzenia jest czymś w rodzaju specjalnie nazwanej funkcji, która jest
wykonywana automatycznie, kiedy dane zdarzenie ma miejsce. W związku z tym two-
rzenie procedur obsługi zdarzeń jest bardzo podobne do tworzenia funkcji, jednak z kil-
koma różnicami.
• Procedury obsługi zdarzeń mają predefiniowane nazwy, takie jak na przykład keyDown.
Nie można nazwać procedury obsługi zdarzenia dowolnie, należy użyć jednej z tych
predefiniowanych nazw. Pełna lista nazw procedur obsługi zdarzeń znajduje się
w tabeli 10.1 oraz 10.2.
• Procedury obsługi zdarzeń nie są deklarowane za pomocą słowa kluczowego function.
• Procedury obsługi zdarzeń muszą być przypisane do przycisków, klipów filmowych
lub innych obiektów, a nie do klatek.
Większość zdarzeń została po raz pierwszy wprowadzona we Flashu 5. Jeżeli
eksportujemy film do formatu Flash 4, korzystajmy tylko z procedur obsługi zdarzeń
związanych z przyciskami (bo tylko one są obsługiwane przez Flash 4) i testujmy
dokładnie nasz film w odtwarzaczu Flash Player 4.
Składnia procedur obsługi zdarzeń
Nazwy zdarzeń (a co za tym idzie, odpowiadających im procedur) są predefiniowane
w ActionScript. Procedury obsługi zdarzeń przyciskowych są definiowane przy użyciu
wyrażenia on (nazwaZdarzenia), zaś procedury obsługi zdarzeń klipowych za pomocą
232
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
wyrażenia onClipEvent (nazwaZdarzenia) — gdzie nazwaZdarzenia jest określeniem
zdarzenia, które ma być obsługiwane.
Z tego względu wszystkie procedury obsługi zdarzeń związanych z przyciskami (oprócz
procedury obsługi zdarzenia keyPress wymagającego dodatkowo parametru w postaci
nazwy klawisza) mają następującą postać:
on (
nazwaZdarzenia) {
polecenia
}
Jedna procedura obsługi przypisana do przycisku może odpowiadać na kilka zdarzeń,
które muszą być rozdzielone przecinkami, na przykład:
on (rollOver, rollOut) {
// wywołuje wbudowaną funkcję w odpowiedzi na zdarzenie
rollOver oraz na
// zdarzenie
rollOut
playRandomSound( );
}
Wszystkie procedury obsługi zdarzeń klipowych mają następującą postać:
onClipEvent (
nazwaZdarzenia) {
polecenia
}
W przeciwieństwie do procedur obsługi zdarzeń przyciskowych procedury obsługi zdarzeń
przypisywane klipom mogą odpowiadać tylko na jedno zdarzenie.
Tworzenie procedur obsługi zdarzeń
Aby utworzyć procedurę obsługi zdarzenia, musimy napisać skrypt i dołączyć go do
odpowiedniego obiektu. Zaczniemy od procedur najczęściej spotykanych, czyli związa-
nych z przyciskami i klipami filmowymi.
Dodawanie procedur obsługi zdarzeń do przycisków i klipów filmowych
Aby dołączyć procedurę obsługi zdarzenia do przycisku lub klipu filmowego, musimy
fizycznie umieścić jego kod w wybranym przycisku lub klipie filmowym. Możemy zrobić
to tylko w środowisku Flasha, wybierając obiekt na scenie i wprowadzając kod w panelu
Actions (patrz rysunek 10.1).
Spróbujmy napisać prostą procedurę obsługi zdarzenia, która będzie odpowiednia zarówno
dla przycisku, jak i dla klipu.
1.
Tworzymy nowy film we Flashu.
2.
Tworzymy przycisk i przeciągamy jego klon na główną scenę.
3.
Po wybraniu przycisku na scenie wprowadzamy następujący kod w panelu Actions:
Tworzenie procedur obsługi zdarzeń
233
Rysunek 10.1. Przyłączanie procedury obsługi zdarzenia do przycisku
on (release) {
trace("Kliknales przycisk");
}
4.
Wybieramy polecenie Test Movie z menu Control.
5.
Klikamy utworzony wcześniej przycisk. W okienku Output pojawi się napis Kliknales
przycisk.
Tak długo, jak film jest odtwarzany, a my klikamy przycisk, interpreter rejestruje zda-
rzenie release i uruchamia kod przypisany do procedury obsługi zdarzenia on (release).
Za każdym razem kiedy naciśniemy i puścimy klawisz myszy nad przyciskiem, w okienku
Output ukaże się komunikat „Kliknales przycisk”.
Teraz spróbujemy napisać bardziej interesujący skrypt, który dołączymy do klipu fil-
mowego.
1.
Tworzymy nowy film we Flashu.
2.
Rysujemy prostokąt na głównej scenie.
3.
Wybieramy polecenie Convert to Symbol z menu Insert.
4.
W okienku dialogowym Symbol Properties wpisujemy nazwę nowego symbolu
rectangle
i wybieramy Movie Clip z grupy opcji Behavior.
5.
Klikamy OK, aby zakończyć tworzenie klipu rectangle.
6.
Wybieramy klip rectangle na scenie i wpisujemy następujący kod w panelu Actions:
onClipEvent (keyDown) {
_visible=0;
}
onClipEvent (keyUp) {
_visible=1;
}
234
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
7.
Wybieramy polecenie Test Movie z menu Control.
8.
Klikamy okno z filmem, by mieć pewność, że jest aktywne, a później naciskamy
i przytrzymujemy dowolny klawisz na klawiaturze. Za każdym razem gdy naciskamy
i przytrzymujemy klawisz, klip rectangle znika. Za każdym razem gdy puszczamy
wciśnięty klawisz, klip rectangle pojawia się znowu.
Warto zauważyć, że nie ustawialiśmy ręcznie żadnego wyrażenia wywołującego procedurę
— interpreter sam wywołuje ją, kiedy zachodzi odpowiadające jej zdarzenie.
Flash nie pozwala na dodawanie lub usuwanie procedur obsługi zdarzeń za pomocą
ActionScript podczas odtwarzania filmu. Procedury obsługi zdarzeń muszą zostać przy-
pisane do przycisków lub klipów filmowych wcześniej w środowisku Flasha. Z tego
powodu następujące wyrażenie nie jest poprawne:
myClip.onKeyDown = function ( ) { _visible = 0; };
W podrozdziale „Dynamiczne uchwyty zdarzeń klipów filmowych” dowiemy się, jak
sobie radzić w podobnych sytuacjach.
Dołączanie procedur obsługi zdarzeń do innych obiektów
Procedury obsługi zdarzeń można przyłączać poza przyciskami i klipami filmowymi rów-
nież do obiektów z dwóch wbudowanych klas XML oraz XMLSocket. Dla tych obiektów
procedury obsługi zdarzeń są podłączane jako metody do klonu (instancji) obiektu.
W obiektach klas XML oraz XMLSocket ActionScript wykorzystuje predefiniowane wła-
ściwości, by przechowywać w nich nazwy procedur obsługi zdarzeń. Na przykład wła-
ściwość onLoad przechowuje nazwę procedury, która ma być wykonana, kiedy zostaną
wczytane zewnętrzne dane XML.
Aby ustawić właściwość onLoad dla obiektu XML, piszemy następujący kod:
myDoc = new XML( );
myDoc.onLoad = function ( ) {trace("Wszystkie dane załadowane!"); };
Możemy również zrobić to w inny sposób. Najpierw napiszemy procedurę obsługi zda-
rzenia, a później przypiszemy ją do właściwości onLoad naszego obiektu:
function doneMsg ( ) {
trace("Wszystkie dane załadowane!");
}
myDoc.onLoad = doneMsg;
Ta składnia jest bardzo podobna do składni JavaScript, gdzie funkcje mogą być przypi-
sywane do właściwości procedury obsługi zdarzenia, co pokazano w listingu 10.1.
Listing 10.1. Przypisywanie procedury obsługi zdarzeń w JavaScript
// Przypisanie ciała funkcji do procedury obsługi zdarzenia
onLoad w JavaScript
window.onload = function ( ) { alert("Ladowanie zakonczone"); };
// Inne rozwiązanie, polegające na zdefiniowaniu funkcji, a następnie
// przypisaniu jej do właściwości
onLoad:
Zasięg procedur obsługi zdarzeń
235
function doneMsg ( ) {
alert ("Wszystkie dane zaladowane!");
}
window.onload = doneMsg;
W przyszłości do większej liczby obiektów ActionScript będzie można przypisywać proce-
dury obsługi zdarzeń za pomocą właściwości obiektu, dlatego warto przyzwyczajać się
już teraz do takiego sposobu podłączania funkcji. Jeżeli nie korzystamy z obiektów XML
i XMLSocket, możemy ćwiczyć ten sposób tworzenia procedur obsługi zdarzeń w JavaScript.
Zaletą tego podejścia jest elastyczność; każda procedura obsługi zdarzenia może być
łatwo przypisana do innego obiektu czy nawet usunięta podczas odtwarzania filmu.
W rozdziale 12., „Obiekty i klasy”, napiszemy więcej o przypisywaniu funkcji do obiek-
tów. Informacje o zdarzeniach obsługiwanych przez obiekty klas XML oraz XMLSocket
znajdują się w części III.
Długość życia procedur obsługi zdarzeń jest związana z istnieniem obiektów, do
których są przypisane. Kiedy klip lub przycisk usuniemy ze sceny bądź obiekt XML
zostanie zlikwidowany, wszystkie procedury obsługi zdarzeń znikają razem z nim.
Obiekt musi znajdować się na scenie lub na listwie czasu, aby jego procedury obsługi
zdarzeń były aktywne.
Zasięg procedur obsługi zdarzeń
Podobnie jak każda funkcja, procedury obsługi zdarzeń są wykonywane w predefiniowa-
nym zasięgu. Zasięg określa, skąd interpreter pobiera zmienne, podfunkcje, obiekty i wła-
ściwości, do których odwołuje się ciało funkcji. Rozpatrzymy zasięg procedur obsługi zda-
rzeń w odniesieniu do zdarzeń klipowych, przyciskowych oraz zdarzeń innych obiektów.
Zasięg procedur obsługi zdarzeń klipów filmowych
W przeciwieństwie do normalnych funkcji procedura obsługi zdarzenia klipowego nie
definiuje lokalnego zasięgu. Dla procedur przyłączonych do klipu zasięgiem jest cały
klip, a nie procedura. Oznacza to, że wszystkie zmienne ze skryptów na listwie czasowej
klipu są dostępne dla procedur obsługi zdarzeń. Jeśli na przykład dołączymy do klipu
nazwanego navigation procedurę obsługi zdarzenia enterFrame i wpiszemy w niej
trace(x);
, interpreter będzie szukał wartości zmiennej x w skryptach listwy czasowej
klipu navigation.
onClipEvent (enterFrame) {
trace(x); // Wyświetla wartość zmiennej navigation.x
}
Interpreter nie zaczyna od sprawdzenia w zasięgu lokalnym, gdyż takiego nie ma. Jeśli
w naszej procedurze wpiszemy var y = 10;, y zostanie zdefiniowane w listwie cza-
sowej navigation, mimo że słowo kluczowe var użyte w zwykłej funkcji definiuje
zmienną lokalną.
236
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
Najłatwiejszym sposobem zapamiętania zasad rządzących zasięgiem procedury obsługi
zdarzenia w klipie jest traktowanie wyrażeń procedury, tak jakby były dołączone do klatki
w klipie. Załóżmy, że mamy klip o nazwie ball, a w nim zmienną xVelocity. Aby
odwołać się do tej zmiennej z procedury obsługi zdarzenia klipowego (w klipie
ball),
wystarczy, że wpiszemy wprost jej nazwę:
onClipEvent (mouseDown) {
xVelocity += 10;
}
Nie musimy wpisywać całej ścieżki tej zmiennej, czyli w tym przypadku _root.ball.
xVelocity
, ponieważ interpreter zakłada, że chodzi o zmienną xVelocity z klipu ball.
To samo dotyczy właściwości i metod. Zamiast wpisywać ball._x, wystarczy, jak napi-
szemy _x. Zamiast ball.gotoAndStop(5) wystarczy gotoAndStop(5) na przykład:
onClipEvent (enterFrame) {
_x += xVelocity; // Przesuń piłkę
gotoAndPlay(_currentframe - 1) // Wykonaj małą pętlę
}
Możemy także zdefiniować funkcję w klipie ball, używając wyrażenia deklaracji we-
wnątrz procedury obsługi zdarzenia w sposób następujący:
onClipEvent (load) {
function hideMe ( ) {
_visibility = 0;
}
}
Można łatwo zapomnieć, że wszystkie wyrażenia w procedurach obsługi zdarzeń klipu
mają zasięg ograniczony do listwy czasowej klipu, a nie do lokalnego zasięgu procedury czy
do listwy czasowej elementu nadrzędnego klipu (czyli listwy, w której klip się znajduje).
Załóżmy, że umieściliśmy nasz klip ball w głównej listwie czasowej filmu oraz że w tej
listwie (a nie w listwie czasowej klipu ball) znajduje się definicja funkcji moveBall( ).
Możemy przez nieuwagę dokonać próby wywołania funkcji moveBall( ) z procedury obsługi
zdarzenia w klipie ball w sposób następujący:
onClipEvent (enterFrame) {
moveBall ( ); // Nie zadziała! W klipie
ball nie ma funkcji moveBall( ).
// Jest ona zdefiniowana na poziomie _root.
}
Musimy użyć nazwy _root, by odwołać się do funkcji moveBall( ) z głównej listwy czasu:
onClipEvent (enterFrame) {
_root.moveBall ( ); // Teraz działa!
}
Czasami może się zdarzyć, że będziemy chcieli odwołać się z wnętrza procedury obsługi
zdarzenia wprost do bieżącego klipu. Możemy to zrobić, korzystając ze słowa kluczowego
this
, które użyte z wnętrza procedury obsługi zdarzenia odnosi się do bieżącego klipu.
Z tego powodu poniższe odwołania z wnętrza procedury obsługi zdarzenia klipowego
są równoznaczne:
Zasięg procedur obsługi zdarzeń
237
this._x // Jest tym samym co następna linia
_x
this.gotoAndStop(12); // Jest tym samym co następna linia
gotoAndStop(12);
Użycie this jest wymagane, kiedy dynamicznie generujemy nazwę jednej właściwości
bieżącego klipu (a także nazwę zmiennej lub zagnieżdżonego klipu). Poniżej sprawimy,
że zagnieżdżone klipy z serii ball.stripe1, ball.stripe2... będą uruchamiać się
po kolei, w zależności od bieżącej klatki w klipie ball:
onClipEvent (enterFrame) {
this["stripe" + _currentframe].play( );
}
Słowo kluczowe this jest również często wykorzystywane z metodami klipu wymaga-
jącymi podania wprost odwołania do obiektu typu Movie Clip podczas wywołania. Każ-
da metoda klipu filmowego o takiej samej nazwie co globalna funkcja ActionScript musi
być używana z jednoznacznym odwołaniem do klipu. Z tego względu słowo kluczowe
this
jest niezbędne, kiedy jako metody wewnątrz procedury obsługi zdarzenia wywo-
łujemy następujące funkcje:
duplicateMovieClip( ),
loadMovie( ),
loadVariables( ),
print( ),
printAsBitmap( ),
removeMovieClip( ),
startDrag( ),
unloadMovie( ).
Oto przykład:
this.duplicateMovieClip("ball2", 1);
this.loadVariables("vars.txt");
this.startDrag(true);
this.unloadMovie( );
O podwójnej naturze tych funkcji powiemy więcej w podrozdziale „Przeciążanie metod
i funkcji globalnych” rozdziału 13., „Klipy filmowe”.
Trzeba zauważyć, że słowo kluczowe this umożliwia odwoływanie się do bieżącego
klipu, nawet jeśli nie ma on określonej nazwy klonu nadanej w środowisku Flash lub po
prostu nie znamy nazwy klipu. Gdy nie znamy nazwy klipu, ale posłużymy się słowem
kluczowym this, możemy wręcz podawać bieżący klip jako odnośnik. Poniżej prezen-
tujemy dość poprawny (i elegancki ) przykład kodu, który to zobrazuje:
238
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
// KOD NA GŁÓWNEJ LISTWIE CZASOWEJ
// Ogólna funkcja przesuwająca dowolny klip
function move (clip, x, y) {
clip._x += x;
clip._y += y;
}
// KOD W KLIPIE
// Wywołuje funkcję z głównej listwy czasowej i nakazuje jej przesunąć
// bieżący klip, odwołując się do niego za pomocą słowa kluczowego
this
onClipEvent (enterFrame) {
root.move(this, 10, 15);
}
W wersji 30 odtwarzacza Flash 5 Player występował błąd powodujący
nieprawidłowe działanie instrukcji gotoAndStop( ) oraz gotoAndPlay( ),
jeśli były wywoływane w klipie z etykietami klatek jako parametrami. Na przykład
taki kod nie będzie działał:
onClipEvent(load) {
gotoAndStop("intro"); // Nie działa we Flash Player 5 r30
}
Aby ominąć ten błąd, wystarczy użyć odwołania do samego siebie, na przykład:
onClipEvent(load) {
this.gotoAndStop("intro");
}
Zakres procedur obsługi zdarzeń dla przycisków
Dla przycisków zakresem procedur obsługi zdarzeń jest listwa czasowa, na której się znaj-
dują. Jeśli na przykład umieścimy przycisk w głównej listwie czasowej, a w procedurze
obsługi zdarzenia dla tego przycisku zadeklarujemy zmienną speed, to zakresem zmiennej
speed
będzie główna listwa czasowa (_root):
// KOD PROCEDURY OBSŁUGI ZDARZEŃ DLA PRZYCISKU
on (release) {
var speed = 10; // Definiuje zmienną speed na poziomie _root
}
Jeśli w głównej listwie czasu umieścimy klip ball, a wewnątrz niego w procedurze obsługi
zdarzenia zadeklarujemy zmienną speed, to zakres tej zmiennej będzie ograniczony do
klipu ball:
// KOD PROCEDURY OBSŁUGI ZDARZENIA DLA KLIPU ball
onClipEvent (load) {
var speed = 10; // Definiuje _root.ball.speed, a nie _root.speed
}
W skrypcie procedury obsługi zdarzeń dla przycisku słowo kluczowe this odnosi się
do listwy czasowej, w której znajduje się przycisk:
Zdarzenia dla przycisków
239
on (release) {
// Klip, w którym znajduje się przycisk staje się w 50% przezroczysty
this._alpha = 50;
// Przesuwa klip, w którym znajduje się przycisk, o 10 pikseli w prawo
this._x += 10;
}
Zakres procedur obsługi zdarzeń innych obiektów
W przeciwieństwie do procedur obsługi zdarzeń klipów filmowych i przycisków proce-
dury obsługi zdarzeń dołączone do obiektów wbudowanych klas, takich jak XML i XML-
Socket, mają zakres dokładnie taki jak funkcje. Procedury obsługi zdarzeń obiektów XML
oraz XMLSocket mają zakres określany podczas definiowania funkcji. Co więcej, procedury
obsługi zdarzeń obiektów XML oraz XMLSocket mają zakres lokalny. Wszystkie zasady
dotyczące zakresu funkcji i opisane w podrozdziale „Zakres funkcji” rozdziału 9.,
„Funkcje”, odnoszą się także do procedur obsługi zdarzeń obiektów, które nie są przyci-
skami ani klipami filmowymi.
Zdarzenia dla przycisków
Tabela 10.1 wprowadza w problematykę różnych zdarzeń dostępnych dla przycisków.
Korzystając ze zdarzeń dla przycisków, możemy łatwo napisać kod dla nawigacji, for-
mularzy, gier, a także innych elementów interfejsu. Przyjrzymy się po kolei wszystkim
zdarzeniom dla przycisków i nauczymy się, w jaki sposób przycisk powinien być opro-
gramowany, by reagować na zdarzenia generowane przez mysz i klawiaturę.
Każde ze zdarzeń przedstawionych w tabeli 10.1 jest obsługiwane przez odpowiadającą
mu procedurę obsługi zdarzenia w postaci on (nazwaZdarzenia). Na przykład zdarzenie
press jest obsługiwane przez procedurę zaczynającą się od on (press). Wyjątkiem jest
procedura obsługi zdarzenia mająca postać on (keypress klawisz), gdzie klawisz jest nazwą
klawisza do sprawdzania. Zdarzenia dla przycisków są wysyłane tylko do przycisku,
nad którym znajduje się mysz. Jeśli kilka przycisków zachodzi na siebie, znajdujący się
najwyżej otrzyma informację o wszystkich zdarzeniach; pozostałe przyciski nie będą
mogły odpowiedzieć na zdarzenia, nawet jeśli przycisk znajdujący się najwyżej nie ma
zdefiniowanych procedur obsługi zdarzeń. W poniższych opisach pojęcie obszar aktywny
odnosi się do obszaru przycisku, który musi znajdować się pod kursorem myszy, aby
zdarzenie zostało wygenerowane (obszar aktywny jest definiowany graficznie podczas
tworzenia przycisku w środowisku Flash).
press
Technicznie rzecz biorąc, kliknięcie myszą jest dwustopniowym procesem: najpierw kla-
wisz myszy jest wciskany — press, a następnie zwalniany — release. Zdarzenie press ma
miejsce, gdy wskaźnik myszy znajduje się nad obszarem aktywnym przycisku, a główny
(lewy dla PC) klawisz myszy jest wciśnięty. Pozostałe klawisze myszy są ignorowane.
240
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
Tabela 10.1. Zdarzenia dla przycisków
Nazwa zdarzenia
Zdarzenie zachodzi gdy...
Press
Główny klawisz myszy (dla PC lewy) został wciśnięty, kiedy wskaźnik
myszy znajdował się nad obszarem aktywnym przycisku. Pozostałe klawisze
myszy są pomijane
Release
Główny klawisz myszy (dla PC lewy) został naciśnięty, a następnie
zwolniony, kiedy wskaźnik myszy znajdował się nad obszarem aktywnym
przycisku
ReleaseOutside
Główny klawisz myszy (dla PC lewy) został wciśnięty, kiedy wskaźnik
myszy znajdował się nad obszarem aktywnym przycisku, a następnie
zwolniony, kiedy kursor znajdował się poza tym obszarem
RollOver
Wskaźnik myszy znalazł się nad obszarem aktywnym, przy niewciśniętym
głównym klawiszu myszy
RollOut
Wskaźnik myszy opuścił obszar aktywny przycisku, żaden klawisz myszy
nie został wciśnięty
DragOut
Główny klawisz myszy (dla PC lewy) został wciśnięty, kiedy wskaźnik
myszy znajdował się nad obszarem aktywnym przycisku, następnie przy
wciąż wciśniętym klawiszu wskaźnik został usunięty poza obszar aktywny
DragOver
Główny klawisz myszy (dla PC lewy) został wciśnięty, kiedy wskaźnik
myszy znajdował się nad obszarem aktywnym przycisku, następnie przy
wciąż wciśniętym klawiszu wskaźnik został usunięty poza obszar aktywny,
by na koniec wrócić nad obszar aktywny
KeyPress
Wybrany (jako parametr) klawisz został naciśnięty. Zazwyczaj zamiast tego
zdarzenia stosuje się zdarzenie klipu keyDown
Przyciskowe zdarzenie press można wykorzystać do przycisków opcji czy strzelania
w grach. Jednak aby dać użytkownikowi możliwość zmiany zdania przed zwolnieniem
klawisza myszy, lepiej stosować zdarzenie release.
release
Zdarzenie release ma miejsce, kiedy zostanie wykryta następująca sekwencja działań
użytkownika.
1.
Wskaźnik myszy znajduje się nad obszarem aktywnym przycisku.
2.
Główny klawisz myszy został wciśnięty, kiedy wskaźnik myszy wciąż znajdował się
nad obszarem aktywnym przycisku (w tym momencie następuje zdarzenie press).
3.
Główny klawisz myszy został zwolniony, podczas gdy wskaźnik wciąż znajdował się
nad obszarem aktywnym przycisku (w tym momencie następuje zdarzenie release).
Używając zdarzenia release zamiast press, dajemy użytkownikowi szansę na przesunięcie
wskaźnika poza obszar aktywny przycisku nawet po kliknięciu (a dokładnie po wciśnięciu
i przytrzymaniu klawisza myszy), a co za tym idzie, na cofnięcie decyzji.
Zdarzenia dla przycisków
241
releaseOutside
Zdarzenie releaseOutside zazwyczaj wskazuje, że użytkownik zmienił zdanie. Po kliknię-
ciu nad przyciskiem zjechał wskaźnikiem myszy z obszaru aktywnego i dopiero poza
nim puścił klawisz myszy. Aby to zdarzenie miało miejsce, musi zaistnieć następująca
sekwencja działań użytkownika.
1.
Wskaźnik myszy znajduje się nad obszarem aktywnym przycisku.
2.
Główny klawisz myszy zostaje wciśnięty, kiedy wskaźnik myszy wciąż znajduje się
nad obszarem aktywnym przycisku (w tym momencie następuje zdarzenie press).
3.
Wskaźnik myszy zostaje przesunięty poza obszar aktywny przycisku (w tym momencie
następuje zdarzenie dragOut).
4.
Główny przycisk myszy zostaje zwolniony poza obszarem aktywnym przycisku
(w tym momencie następuje zdarzenie releaseOutside).
Ze zdarzenia releaseOutside będziemy rzadko korzystać, gdyż oznacza ono, że użytkownik
zrezygnował z akcji.
rollOver
Zdarzenie rollOver zachodzi, kiedy wskaźnik myszy nasuwa się na obszar aktywny przy-
cisku, ale klawisz myszy pozostaje niewciśnięty. Zdarzenie rollOver jest rzadko używane
w ActionScript, ponieważ graficzną podmianę stanów przycisku przygotowuje się w śro-
dowisku Flasha bez pisania skryptów. W tym celu możemy skorzystać z ustawionych
domyślnie klatek w przycisku (up,. over i down), wprowadzając w nich różne stany gra-
ficzne przycisku.
Zdarzenie rollOver we Flash 5 dostarcza poręcznego narzędzia do wydobywania zazna-
czonego tekstu z pola tekstowego. Więcej szczegółów na ten temat znajdziesz w „Wybie-
ranie obiektów” w części III.
rollOut
Zdarzenie rollOut jest uzupełnieniem rollOver i ma miejsce, kiedy wskaźnik myszy prze-
suwa się poza obszar aktywny przycisku, przy czym klawisz myszy nie jest wciśnięty.
Podobnie jak w przypadku rollOver, rollOut jest rzadko wykorzystywane, ponieważ różne
stany graficzne przycisku są ustawiane w środowisku Flasha i nie trzeba podmieniać ich
za pomocą skryptów.
dragOut
Zdarzenie dragOut jest podobne do rollOut, tyle że jest generowane, kiedy klawisz myszy
został wciśnięty podczas opuszczania obszaru aktywnego przycisku przez wskaźnik
myszy. Po zdarzeniu dragOut może nastąpić zarówno zdarzenie releaseOutside (jeśli
242
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
użytkownik puści klawisz myszy), jak i zdarzenie dragOver (jeśli użytkownik przesunie
wskaźnik myszy z powrotem nad obszar aktywny przycisku, nie puszczając klawisza
myszy).
dragOver
Zdarzenie dragOver można spotykać równie rzadko jak Yeti. Jest wyczarowywane po
następującej sekwencji działań użytkownika.
1.
Wskaźnik myszy przesuwa się nad obszar aktywny przycisku (następuje zdarzenie
rollOver).
2.
Główny przycisk myszy zostaje wciśnięty i przytrzymany (zdarzenie press).
3.
Wskaźnik myszy zostaje przesunięty poza obszar aktywny przycisku (zdarzenie
dragOut).
4.
Wskaźnik myszy wraca nad obszar aktywny przycisku (zdarzenie dragOver).
Tak więc zdarzenie dragOver oznacza, że użytkownik przesunął wskaźnik myszy z obszaru
aktywnego, a później z powrotem nad obszar aktywny przy wciśniętym cały czas przy-
cisku myszy. Trzeba zwrócić uwagę, że w przeciwieństwie do rollOver zdarzenie dragOver
ma miejsce, kiedy klawisz myszy jest wciąż wciśnięty podczas powrotu nad obszar
aktywny przycisku.
keyPress
Zdarzenie keyPress, niezwiązane ze zdarzeniami myszy, w przeciwieństwie do nich
jest wywoływane przez naciśnięcie określonego klawisza na klawiaturze. Umieściliśmy je
tutaj, ponieważ jego procedura obsługi ma składnię typu on (nazwaZdarzenia), podobnie
jak inne procedury obsługi zdarzeń przycisków. Wymaga ona podania jako parametru
nazwy klawisza wywołującego zdarzenie:
on (keyPress
klawisz) {
wyrazenia
}
gdzie klawisz to nazwa klawisza wywołującego zdarzenie. Nazwą może być zarówno
litera określająca klawisz (na przykład s lub S), jak i słowo kluczowe reprezentujące
klawisz w następującej formie „<słowoKluczowe>”. Z jedną procedurą może być
związany tylko jeden klawisz. Aby przy użyciu zdarzenia keyPress obsługiwać większą
liczbę klawiszy, należy napisać kilka procedur obsługi zdarzeń, na przykład:
// Wykrywa wciśnięcie klawisza "a"
on (keyPress "a") {
trace("Wciśnięto klawisz 'a'");
}
// Wykrywa wciśnięcie Enter
on (keyPress "<Enter>") {
trace("Wciśnięto klawisz Enter");
}
Przegląd zdarzeń klipów filmowych
243
// Wykrywa wciśnięcie strzałki w dół
on (keyPress "<Down>") {
trace("Wciśnięto strzałkę w dół");
}
Niżej przedstawiamy dozwolone wartości słowa kluczowego jako parametru w procedurze
obsługi zdarzenia keyPress (warto zauważyć, że nie ma pośród nich klawiszy funkcyj-
nych F1, – , F12 — czyli nie są one wykrywane przez zdarzenie keyPress; ich wciśnięcie
wykrywa natomiast obiekt Key):
<Backspace>
,
<Delete>
,
<Down>
,
<End>
,
<Enter>
,
<Home>
,
<Insert>
,
<Left>
,
<PgDn>
,
<PgUp>
,
<Right>
,
<Space>
,
<Tab>
,
<Up>
.
We Flash 4 zdarzenie keyPress było jedynym sposobem obsługi przez użytkownika klawia-
tury. We Flash 5 i następnych wersjach obiekt Key w połączeniu ze zdarzeniami klipów
filmowych keyDown oraz keyUp (opisanymi dalej) daje dużo większą kontrolę nad ob-
sługą klawiatury. Zdarzenie keyPress wykrywa w jednym momencie tylko wciśnięcie
pojedynczego klawisza, podczas gdy obiekt Key potrafi wykryć równoczesne wciśnięcie
kilku klawiszy.
Przegląd zdarzeń klipów filmowych
Zdarzenia klipów są wywoływane przez wiele czynników, poczynając od kliknięć myszą na
pobieraniu danych kończąc. Zdarzenia klipowe możemy podzielić na dwie kategorie: zda-
rzenia wywoływane przez użytkownika oraz zdarzenia związane z odtwarzaniem filmu.
Zdarzenia wywoływane przez użytkownika są związane z klawiaturą i myszą, a zdarzenia
powstające podczas odtwarzania filmu – z wyświetlaniem klatek przez odtwarzacz Flash
Player, z tworzeniem i usuwaniem klipów oraz z wczytywaniem danych.
244
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
Trzeba zauważyć, że zdarzenia klipowe wywoływane przez użytkownika pokrywają się
częściowo z funkcjonalnością zdarzeń przyciskowych opisanych wcześniej. Na przykład
zdarzenie klipowe mouseDown może tak samo wykryć wciśnięcie klawisza myszy jak
zdarzenie przyciskowe press. Jednak zdarzenia klipowe w przeciwieństwie do przyci-
skowych nie są związane z obszarami aktywnymi i położeniem względem nich wskaź-
nika myszy.
Zajmijmy się przez chwilę zdarzeniami klipów filmowych w ActionScript zebranymi
w tabeli 10.2. Najpierw przyjrzymy się zdarzeniom wywoływanym podczas odtwarzania
filmu (enterFrame, load, unload oraz data), a później zdarzeniom użytkownika (mouseDown,
mouseUp, mouseMove, keyDown i keyUp). Każde zdarzenie jest obsługiwane przez odpowiada-
jącą mu procedurę w postaci onClipEvent (nazwaZdarzenia). Na przykład zdarzenie enter-
Frame jest obsługiwane przez procedurę rozpoczynającą się tak: onClipEvent (enterFrame).
Z wyjątkiem zdarzeń load, unload oraz data zdarzenia klipowe są wysyłane do wszystkich
klipów znajdujących się na scenie, nawet jeśli wskaźnik myszy znajduje się nad innym
klipem lub w zupełnie innym miejscu sceny.
Tabela 10.2. Zdarzenia klipów filmowych
Nazwa zdarzenia
Zdarzenie klipowe ma miejsce gdy...
EnterFrame
Wskaźnik odtwarzania doszedł do kolejnej klatki (przed wyświetleniem
klatki we Flash Player)
Load
Klip po raz pierwszy pojawił się na scenie
Unload
Klip został usunięty ze sceny
Data
Zakończono wczytywanie zmiennych do klipu lub część wczytywanego
filmu załadowała się do klipu
MouseDown
Główny klawisz myszy (lewy w PC) został wciśnięty, kiedy klip znajdował
się na scenie (pozostałe klawisze są ignorowane)
MouseUp
Główny klawisz myszy (lewy w PC) został zwolniony, kiedy klawisz
znajdował się na scenie
MouseMove
Wskaźnik myszy został przesunięty (nawet o piksel), kiedy klip znajdował
się na scenie. Wskaźnik nie musi znajdować się nad klipem
KeyDown
Klawisz na klawiaturze został wciśnięty, kiedy klip znajdował się na scenie
KeyUp
Wciśnięty klawisz z klawiatury został zwolniony, kiedy klip znajdował się
na scenie
Zdarzenia klipowe związane
z odtwarzaniem filmu
Następujące zdarzenia są generowane bez udziału użytkownika w czasie, gdy Flash
odtwarza i ładuje filmy.
Zdarzenia klipowe związane z odtwarzaniem filmu
245
enterFrame
Jeśli potrzebujemy pustego, zapętlonego klipu filmowego wywołującego skrypty, proce-
dura obsługi zdarzenia enterFrame jest najlepszym rozwiązaniem. Zdarzenie enterFrame
jest wywoływane dla każdej klatki wyświetlanej w filmie. Na przykład jeśli w klipie
umieścimy poniższy kod, będzie on powiększał się (klip oczywiście) o 10 pikseli wzdłuż
i wszerz na każdą klatkę wyświetloną w filmie:
onClipEvent (enterFrame) {
_height += 10;
_width += 10;
}
(Przypominamy, że właściwości _height oraz _width są wykorzystywane w zasięgu
klipu, do którego procedura obsługi zdarzenia enterFrame jest przypisana, nie ma więc
potrzeby umieszczania nazwy klonu klipu przed _width i _height).
Zdarzenie enterFrame jest generowane przed wyświetleniem każdej klatki, nawet jeżeli
wskaźnik odtwarzania klipu zawierającego procedurę obsługi zdarzenia enterFrame
jest zatrzymana. Z tego powodu zdarzenie enterFrame jest zawsze generowane.
Podczas odtwarzania we Flash Player wszystkie filmy są cały czas uruchomione, nawet
jeśli na ekranie nic się nie dzieje lub wskaźnik odtwarzania jest zatrzymany na jednej
klatce. Pojedyncza procedura obsługi zdarzenia enterFrame klipu będzie więc uruchamiana
raz za razem tak długo, jak ów klip znajduje się na scenie, bez względu na to, czy sam
klip jest uruchomiony, czy zatrzymany. Jeśli wskaźnik odtwarzania zostanie przesunięty
przez wywołanie funkcji gotoAndStop( ), procedura obsługi zdarzenia enterFrame będzie
wciąż wykonywana dla każdej wyświetlonej klatki. Jeśli wszystkie klipy w całym filmie
zostaną zatrzymane przez funkcję stop( ), wszystkie procedury enterFrame klipów (znaj-
dujących się aktualnie na scenie) będą nadal działać. Zazwyczaj zdarzenie enterFrame jest
wykorzystywane do odświeżania stanu klipu w sposób powtarzalny przez określony
czas. Procedura obsługi zdarzenia enterFrame nie musi być stosowana do zawierającego go
klipu — może być z powodzeniem wykorzystywana z jednoklatkowym pustym klipem
do powtarzalnego wykonywania skryptów. Ta technika nazywana pętlą zdarzeń klipowych
(lub bardziej luźno procesem) została szerzej omówiona w podrozdziale „Pętle na listwie
czasowej i pętle przypisane do zdarzeń klipów filmowych” rozdziału 8., „Pętle”.
Trzeba zauważyć, że procedura obsługi zdarzenia enterFrame jest wykonywana przed
każdym innym kodem z listwy czasowej klipu zawierającego tę procedurę.
Niewielkim nakładem sił możemy, wykorzystując zdarzenie enterFrame, uzyskać naprawdę
rozbudowaną kontrolę nad klipem. Przedstawiony dalej listing 10.7 rozwinie wcześniejszy
kod zmieniający rozmiary klipu, tak by klip na przemian zwiększał się i zmniejszał.
246
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
load
Zdarzenie load ma miejsce w momencie utworzenia klipu to znaczy, kiedy pojawia się
on na scenie po raz pierwszy. Pojawienie się klipu na scenie może odbyć się na jeden
z następujących sposobów.
• Wskaźnik odtwarzania dotarł do klatki kluczowej zawierającej wywołanie nowego
klonu klipu.
• Klip został powielony z innego klipu przez funkcję duplicateMovieClip( ).
• Klip został umieszczony na scenie przy użyciu funkcji attachMovie( ).
• Zewnętrzny plik .swf został załadowany do klipu przy użyciu funkcji loadMovie( ).
• Zawartość klipu została usunięta przez funkcję unloadMovie( ) (wywołano zdarzenie
load ponieważ do klipu, którego zawartość została usunięta, jest ładowany pusty klip
zastępczy).
Ciało procedury obsługi zdarzenia load jest wykonywane po wszystkich kodach zawar-
tych w listwie czasu w klatce, w której klip pojawił się po raz pierwszy.
Zazwyczaj procedura obsługi zdarzenia load jest wykorzystywana do inicjalizacji zmiennych
lub wykonania pewnych czynności wstępnych (na przykład ustalenie rozmiarów oraz
miejsca wyświetlania dynamicznie generowanego klipu). Zdarzenie load doskonale nadaje
się również do zatrzymania w elegancki sposób samoczynnego odtwarzania klipu:
onClipEvent (load) {
stop( );
}
Ponadto procedura obsługi zdarzenia load może być również wykorzystywana do wywo-
ływania funkcji istotnych dla prawidłowego funkcjonowania klipu.
Zdarzenie load jest szczególnie interesujące w połączeniu z funkcją duplicateMovieClip( )
tworzącą nowe klipy filmowe. W listingu 10.2 generujemy cały ekran klipów star, korzy-
stając z jednej procedury obsługi zdarzenia load w łańcuchu rekurencyjnym. Procedura
obsługi zdarzenia load jest wykonywana dla każdego powielonego klipu star, a jego
wykonanie powiela klip po raz kolejny. Proces kończy się, kiedy nastąpi powielenie 100
klipów. Plik źródłowy .fla dla listingu 10.2 jest dostępny w internetowej witrynie Code
Depot oraz na serwerze FTP Wydawnictwa Helion.
Listing 10.2. Tworzenie ekranu klipów star przy użyciu zdarzenia load
onClipEvent (load) {
// Umieszczenie bieżącego klipu w losowo wybranym miejscu
_x = Math.floor(Math.random( ) * 550);
_y = Math.floor(Math.random( ) * 400);
// Przypisanie standardowej wielkości bieżącemu klipowi, by nie odziedziczył
// rozmiarów poprzednika
_xscale = 100;
_yscale = 100;
Zdarzenia klipowe związane z odtwarzaniem filmu
247
// Losowe ustalenie wielkości bieżącego klipu miedzy 50% a 150%
randscale = Math.floor(Math.random( ) * 100) – 50;
_xscale += randScale;
_yscale += randScale;
// Powielenie klipu, chyba że to już setny egzemplarz
if (_name != "star100") {
nextStarNumber = number(_name.substring(4, _name.length)) + 1;
this.duplicateMovieClip("star" + nextStarNumber, nextStarNumber);
}
}
unload
Zdarzenie unload jest odwrotnością zdarzenia load i zachodzi, kiedy klip filmowy „kończy
życie”, to znaczy bezpośrednio po ostatniej klatce, w której klip znajduje się na scenie
(ale przed pierwszą klatką, w której już go nie ma).
Klipowe zdarzenie unload mogą powodować przyczyny, które wymieniamy poniżej.
• Wskaźnik odtwarzania dotarł do końca klatek zajmowanych przez klip.
• Klip został usunięty przez funkcję removeMovieClip( ) (usuwającą klipy generowane
przez funkcje attachMovie( ) oraz duplicateMovieClip ( )).
• Wcześniej załadowany zewnętrzny plik .swf został usunięty z klipu przez funkcję
unloadMovie( ).
• Zewnętrzny plik .swf został załadowany do klipu.
Ostatnia przyczyna może wydawać się nieco dziwna, lecz w rzeczywistości jest natural-
nym wynikiem sposobu, w jaki filmy są ładowane do Flasha. Za każdym razem gdy plik
.swf jest ładowany do klipu, jego poprzednia zawartość zostaje usunięta, powodując
zdarzenie unload. Poniższy przykład obrazuje zachowanie zdarzeń load oraz unload
w połączeniu z funkcją loadMovie( ).
1.
W nowym filmie Flasha umieszczamy na scenie pusty klip w klatce 1. głównej listwy
czasowej filmu. Nazwiemy go emptyClip.
2.
W klatce 5. głównej listwy czasowej ładujemy do klipu emptyClip film test.swf
za pomocą następującego kodu: emptyClip.loadMovie("test.swf").
3.
Uruchamiamy film, wybierając polecenie Play movie z menu Control.
Wyniki są następujące.
1.
W klatce 1. pojawia się emptyClip, powodując zdarzenie load.
2.
Wywołanie funkcji loadMovie( ) w klatce 5. ma dwojakie skutki:
a) zawartość klipu emptyClip zostaje usunięta, by zrobić miejsce dla pliku test.swf ,
oraz powoduje zdarzenie unLoad,
b) załadowanie test.swf powoduje zdarzenie load.
248
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
Zdarzenie unload jest zazwyczaj wykorzystywane do inicjalizacji kodów czyszczących,
porządkujących scenę lub zerujących w jakiś sposób środowisko programu. Innym zasto-
sowaniem tego zdarzenia jest wykonanie określonych działań (na przykład uruchomienie
innego filmu) po zakończeniu klipu.
data
Zdarzenie data ma miejsce, kiedy do klipu filmowego są wczytywane zewnętrzne dane.
Zdarzenie to, w zależności od rodzaju wczytywanych danych, może zostać wywołane
przez dwie całkiem różne przyczyny. Zajmiemy się obydwoma przyczynami osobno.
Korzystanie z procedury obsługi zdarzenia data w połączeniu z loadVariables( )
Jeśli pobieramy serię zmiennych z serwera za pomocą funkcji loadVariables( ), to aby z nich
skorzystać, musimy poczekać, aż załadują się w całości (patrz część III).
Kiedy klip otrzyma całą porcję pobieranych zmiennych, generowane jest zdarzenie data,
informujące, że można już wykonać kod odwołujący się do tych zmiennych.
Załóżmy, że mamy program zawierający księgę gości, w której odwiedzający mogą wpi-
sywać swoje komentarze. Komentarze te przechowujemy na serwerze. Kiedy użytkow-
nik chce przeczytać komentarz, musimy pobrać go z serwera, korzystając z loadVariables( ).
Nim jednak będziemy mogli pokazać komentarz, musimy wyświetlać ekran informujący
o pobieraniu danych. Wyświetlamy go do czasu, aż potrzebne dane zostaną pobrane
z serwera. Procedura obsługi zdarzenia data poinformuje, kiedy dane zostaną wczytane
i od kiedy możemy bezpiecznie wyświetlić komentarz użytkownikowi.
Listing 10.3 jest uproszczonym skrótem kodu księgi gości ukazującym działanie procedury
obsługi zdarzenia data w połączeniu z loadVariables( ). W naszym przykładzie przycisk
ładuje dwie zmienne zakodowane w formacie URL z pliku tekstowego do klipu. Klip
zawiera procedurę obsługi zdarzenia data wykonywaną, kiedy dane zostaną pobrane. Kod
procedury wyświetla wartość zmiennych. Wiemy, że dane mogą być bezpiecznie wy-
świetlone, gdyż procedura obsługi zdarzenia będzie wykonana po zdarzeniu data (czyli
kiedy dane zostaną w całości pobrane).
Listing 10.3. Oczekiwanie na zdarzenie data
// ZAWARTOŚĆ PLIKU guestbook.txt
name=judith&message=hello
// PRZYCISK WEWNĄTRZ KLIPU
on (release) {
this.loadVariables("guestbook.txt");
}
// PROCEDURA WEWNĄTRZ KLIPU
onClipEvent (data) {
trace(name);
trace(message);
}
Zdarzenia klipowe związane z odtwarzaniem filmu
249
Ze zdarzeń data będziemy jeszcze korzystać podczas budowaniu formularza w rozdziale 17.,
„Interaktywne formularze”.
Użycie procedury obsługi zdarzenia data w połączeniu z loadMovie( )
Drugi sposób użycia zdarzenia data jest związany z ładowaniem zewnętrznego pliku .swf
do klipu za pomocą funkcji loadMovie( ). Podczas ładowania do klipu nadrzędnego plik
domyślnie uruchamia się natychmiast, nawet gdy tylko jego część jest załadowana. Nie
zawsze jest to działanie pożądane, czasami chcemy mieć pewność, że cały plik lub okre-
ślona jego część została załadowana, nim zacznie się odtwarzanie. Pewność tę można
zyskać dzięki procedurze obsługi zdarzenia data oraz kilku linijkom kodu preloadera.
Zdarzenie data ma miejsce za każdym razem gdy klip nadrzędny otrzyma porcję danych
z zewnętrznego pliku .swf. Definicja „porcji” jest bardziej skomplikowana, niż można by
przypuszczać. Aby wywołać zdarzenie data, co najmniej jedna klatka musi zostać zała-
dowana w całości, od momentu, gdy miało miejsce poprzednie zdarzenie data lub od
rozpoczęcia ładowania pliku .swf. (W rzeczywistości w tym czasie może zostać załado-
wana więcej niż jedna klatka, ale
jedna klatka to minimum wymagane, by wywołać zda-
rzenie data). Wywoływanie zdarzeń data jest związane z wyświetlaniem klatek przez
Flash Player. Po wyświetleniu każdej klatki interpreter sprawdza, czy załadowano jakąś
część zewnętrznego pliku .swf do klipu zawierającego procedurę zdarzenia data. Jeśli
część zewnętrznego pliku .swf została załadowana i w części tej znajduje się co najmniej
jedna klatka, następuje zdarzenie data. To sprawdzenie ma miejsce raz i tylko raz na
każdą wyświetloną klatkę (nawet jeśli wskaźnik odczytu jest zatrzymany).
Warto zauważyć, że ze względu na to, iż zdarzenie data jest sprawdzane raz na klatkę,
filmy z wyższą szybkością odtwarzania mają płynniejsze preloadery, gdyż częstsze jest
w nich odświeżanie stanu wczytywania pliku .swf.
Dokładna liczba wywołań zdarzenia data podczas operacji loadMovie( ) zależy od budo-
wy wewnętrznej pliku .swf oraz szybkości łącza. Jednoklatkowy plik .swf, nieważne jak
duży, wywoła tylko jedno zdarzenie data. Z drugiej strony, plik .swf zawierający 100 klatek
może wywołać do 100 osobnych zdarzeń data, w zależności od prędkości odtwarzania
filmu, wielkości w bajtach każdej klatki i prędkości połączenia sieciowego. Jeśli klatki są
duże a połączenie wolne — zostanie wywołanych więcej zdarzeń data (jedno na klatkę).
Jeśli klatki są małe, a połączenie szybkie, zostanie wywołanych mniej zdarzeń data (całe
100 klatek można wczytać podczas wyświetlania dwóch klatek przez Flash Player, wywo-
łując tylko jedno zdarzenie data).
Jak w takim razie wykorzystać procedurę obsługi zdarzenia data podczas budowania
preloadera? Kiedy zdarzenie data ma miejsce w wyniku działania funkcji loadMovie( ),
wiemy, że nastąpił postęp we wczytywaniu pliku .swf. Dzięki temu z procedury obsługi
zdarzenia data możemy sprawdzić, czy została wczytana wystarczająca część pliku, by
zezwolić na odtwarzanie. Użyjemy do tego funkcji getBytesLoaded( ) oraz getBytesTotal( )
w sposób ukazany w listingu 10.4 (alternatywny sposób opiera się na wykorzystaniu
właściwości klipu _framesLoaded oraz _totalFrames). Listing ten zawiera również
pewne rozwiązanie wykorzystane podczas ładowania filmu.
250
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
I jeszcze jedno. Wczytywany plik .swf powinien mieć w pierwszej klatce wywołanie funkcji
stop( )
, która zapobiegnie samoczynnemu odtwarzaniu przed wczytaniem w całości.
Zmodyfikowana wersja listingu 10.4 dostępna jest w internetowej witrynie Code Depot
oraz na serwerze FTP Wydawnictwa Helion.
Listing 10.4. Preloader wykorzystujący zdarzenie data
onClipEvent (data) {
trace("Otrzymano dane"); // Właśnie się zaczyna
// Włączenie lampki transferu danych
_root.transferIndicator.gotoAndStop("on");
// Jeśli wczytywanie filmu zakończyło się – wyłączenie lampki transferu
// danych i uruchomienie filmu.
if (getBytesTotal( ) > 0 && getBytesLoaded( ) == getBytesTotal( )) {
_root.transferIndicator.gotoAndStop("off");
play( );
}
// Wyświetlenie odświeżonej informacji o ładowaniu w polach tekstowych
// w _root
_root.bytesLoaded = getBytesLoaded( );
_root.bytesTotal = getBytesTotal( );
_root.clipURL = _url.substring(_url.lastIndexOf("/") + 1, _url.length);
}
Klipowe zdarzenia
generowane przez użytkownika
Pozostałe zdarzenia klipowe są związane z działaniami użytkownika. Kiedy ma miejsce
któreś z klipowych zdarzeń użytkownika, wszystkie klipy znajdujące się na scenie (nie-
istotne, jak głęboko zagnieżdżone w innych klipach) otrzymują o tym informację. W ten
sposób wiele klipów może zareagować na jedno kliknięcie, ruch myszy czy wciśnięcie
klawisza na klawiaturze. Aby wykonać kod w oparciu o umiejscowienie kursora myszy
względem określonego klipu, uchwyt zdarzenia powinien sprawdzać położenie wskaź-
nika myszy wobec klipu. Wbudowana funkcja hitTest( ) pozwala na łatwe sprawdzenie,
czy kliknięcie nastąpiło w określonym rejonie, co zobaczymy w listingu 10.9.
mouseDown
Podobnie jak przyciskowe zdarzenie press, zdarzenie klipowe mouseDown wykrywa wci-
śnięcie klawisza myszy. Zdarzenie mouseDown zachodzi zawsze, kiedy główny klawisz
myszy zostanie wciśnięty niezależnie od tego, w którym miejscu sceny znajduje się
wskaźnik myszy.
W przeciwieństwie do przyciskowego zdarzenia press zdarzenie mouseDown nie jest
związane z żadnym obszarem aktywnym. W połączeniu ze zdarzeniami mouseUp, mouse-
Move, a także z metodą Mouse.hide( ), mouseDown może być wykorzystane do utworzenia
niestandardowego kursora — pokażemy to w listingu 10.8.
Klipowe zdarzenia generowane przez użytkownika
251
mouseUp
Zdarzenie mouseUp jest odpowiednikiem mouseDown. To zdarzenie ma miejsce, za każ-
dym razem kiedy główny klawisz myszy zostanie zwolniony nad dowolnym obszarem
sceny. Podobnie jak w przypadku mouseDown, klip musi znajdować się na scenie pod-
czas kliknięcia, by zdarzenie miało dla niego jakieś konsekwencje. Zdarzenia mouseUp,
mouseDown oraz mouseMove mogą być wykorzystane do zbudowania wielopoziomowej
obsługi myszy bez względu na położenie jej wskaźnika (jak ma to miejsce w przypadku
zdarzeń przyciskowych).
mouseMove
Zdarzenie mouseMove pozwala wychwytywać różnice w położeniu wskaźnika myszy.
Kiedy wskaźnik myszy przemieszcza się, wywoływane są raz za razem zdarzenia mouse-
Move, tak szybko jak tylko procesor jest w stanie je generować. Klip zawierający procedurę
obsługi zdarzenia mouseMove musi być obecny na scenie podczas ruchów myszy, by zda-
rzenie mouseMove odniosło skutek
Zdarzenie mouseMove jest wykorzystywane do aktywowania „wyłączonych” aplikacji, obli-
czania trasy ruchu myszy i tworzenia własnych kursorów, co zobaczymy w listingu 10.8.
keyDown
Zdarzenia keyDown i keyUp są tym samym dla klawiatury, co mouseDown i mouseUp dla
myszy. Razem są podstawowym narzędziem do budowania obsługi klawiatury. Zdarzenie
keyDown zachodzi, kiedy jakiś klawisz na klawiaturze zostanie wciśnięty. Jeśli klawisz
zostanie przytrzymany, zdarzenie keyDown będzie się powtarzać z częstotliwością zależną
od systemu operacyjnego i ustawień klawiatury. W przeciwieństwie do zdarzenia przy-
ciskowego keyPress klipowe zdarzenie keyDown ma miejsce po wciśnięciu dowolnego
klawisza — a nie ściśle określonego. Aby wyłapać (lub inaczej przechwycić bądź wykryć)
zdarzenie keyDown, klip z procedurą obsługi zdarzenia musi znajdować się na scenie
w momencie wciśnięcia klawisza. Następujący kod wyłapuje zdarzenie keyDown:
onClipEvent (keyDown) {
trace("Jakiś klawisz został wciśnięty");
}
Trzeba zauważyć, że nasz kod nie precyzuje, który klawisz został wciśnięty. Jeśli chce-
my, by użytkownik nacisnął dowolny klawisz, to taki kod wystarczy. Zazwyczaj jednak
chcemy związać z określonym klawiszem konkretne działania. Na przykład chcemy, by
różne klawisze kierowały statek kosmiczny w różne strony.
Aby dowiedzieć się, który klawisz spowodował zdarzenie keyDown, korzystamy z wbudo-
wanego obiektu Key, opisującego stan klawiatury. Rodzaj poszukiwanej przez nas informacji
zależy od rodzaju interaktywności, który zamierzamy osiągnąć. Gry za przykład wymagają
ciągle odświeżanej informacji o potencjalnie równoczesnych wciśnięciach klawiszy.
252
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
Z kolei interfejs nawigacyjny może jedynie potrzebować wykrycia pojedynczego wciśnięcia
klawisza (na przykład w prezentacji — pokazie slajdów — wciśnięcia spacji). Obiekt Key
może poinformować, który klawisz został wciśnięty jako ostatni i czy określony klawisz
jest wciąż wciśnięty. Do odczytywania stanu klawiatury korzystamy z czterech metod
obiektu Key:
Key.getCode( ) // dziesiętna wartość kodu ostatnio wciśniętego klawisza
Key.getAscii( ) // dziesiętna wartość w kodzie ASCII ostatnio wciśniętego
// klawisza
Key.isDown(
keycode) // zwraca true, jeśli klawisz podany jako parametr jest
// wciśnięty
Key.isToggled(
keycode) // ustala, czy Caps Lock lub Num Lock jest włączony
Listing 10.5 pokazuje procedurę obsługi zdarzenia keyDown wyświetlającą wartość kodu
ASCII ostatnio wciśniętego klawisza.
Listing 10.5. Sprawdzanie ostatnio wciśniętego klawisza
onClipEvent (keyDown) {
// Pobranie wartości ASCII ostatnio naciśniętego klawisza i przekształcenie
// jej w odpowiadający jej znak
lastKeyPressed = String.fromCharCode(Key.getAscii( ));
trace("Nacisnąłeś klawisz'" + lastKeyPressed + "' .");
}
Listing 10.6 pokazuje przykładową procedurę obsługi zdarzenia keyDown sprawdzającą,
czy ostatnim naciśniętym klawiszem była strzałka w górę.
Listing 10.6. Sprawdzanie wciśnięcia strzałki w górę
onClipEvent (keyDown) {
// Sprawdzenie, czy strzałka w górę była ostatnim naciśniętym klawiszem
// Strzałka w gore jest reprezentowana przez właściwość Key.UP
if (Key.getCode( ) == Key.UP) {
trace("Strzałka w górę jest ostatnim wciśniętym klawiszem.");
}
}
Istnieje kilka sposobów sprawdzania stanu klawiatury, wybór najlepiej pasującego do
aplikacji należy do użytkownika. Przykładowo metoda Key.getAscii( ) zwracająca wartość
ASCII znaku związanego z ostatnio naciśniętym klawiszem na klawiaturach różnych
języków może się różnić (w anglojęzycznych klawiaturach rozmieszczenie liter i znaków
jest jednolite).
Z drugiej strony, metoda Key.getCode( ) zwraca wartość kodu klawisza, a nie kodu ASCII
odpowiadającego mu znaku. Ta metoda może być bardziej przydatna w aplikacjach
z więcej niż jedną wersją językową, a także w aplikacjach hybrydowych działających na
różnych platformach. Możemy się nią posłużyć, jeśli chcemy na przykład użyć czterech
sąsiadujących klawiszy do nawigacji niezależnie od tego, jakim znakom odpowiadają. Wię-
cej informacji na ten temat znajduje się w części III, w rozdziale pod tytułem „Obiekt Key”.
Z internetowej witryny Code Depot oraz serwera FTP Wydawnictwa Helion można po-
brać przykładowe pliki źródłowe .fla z obsługą zdarzeń keyDown i keyUp.
Klipowe zdarzenia generowane przez użytkownika
253
Procedury obsługi zdarzeń reagujące na klawiaturę działają tylko wtedy, gdy okienko
Flash Player jest okienkiem aktywnym. Użytkownik musi kliknąć okno z filmem,
by procedury obsługujące zdarzenia klawiatury prawidłowo działały. Musimy wziąć
pod uwagę zmuszenie użytkownika do kliknięcia jakiegoś przycisku w prezentacji
przed wejściem do sekcji korzystającej z klawiatury.
Obsługa klawiszy specjalnych
Aby wyłączyć obsługę poleceń menu w odtwarzaczach — projektorach (plikach .exe wyge-
nerowanych z filmu Flash), dodajemy na początku filmu następującą linię kodu.
fscommand("trapallkeys", "true");
Ta linijka kodu zabezpiecza również przed wyjściem z trybu pełnoekranowego (Fullscreen)
w projektorze przy użyciu klawisza Escape. Aby przechwytywać wciśnięcia klawisza Esc
w projektorze, użyjemy następującego kodu:
onClipEvent (keyDown) {
if (Key.getCode( ) == Key.ESCAPE) {
// Odpowiedz na wciśnięcie klawisza Escape
}
}
Warto pamiętać, że klawisz Escape może nie być przechwytywany we wszystkich przeglą-
darkach. Co więcej, nie ma możliwości wyłączenia klawisza Alt lub w przypadku Win-
dows sekwencji Alt/Tab czy Ctrl/Alt/Delete.
Aby przechwytywać wciśnięcie klawisza Tab, utworzymy przycisk z następującym
uchwytem:
on (keyPress "<Tab>") {
// Odpowiedz na wciśnięcie klawisza Tab
}
W filmie odtwarzanym w samodzielnym projektorze klawisz Tab może być przechwy-
tywany również przez procedurę obsługi zdarzenia w klipie, na przykład:
onClipEvent (keyDown) {
if (key.getCode( ) == Key.TAB) {
// Odpowiedz na wciśnięcie klawisza Tab
}
}
W niektórych przeglądarkach wciśnięcie klawisza Tab może być wykryte wyłącznie przez
przyciskowe zdarzenie keyPress. Czasami może nawet być konieczne połączenie keyPress
z klipowym zdarzeniem keyUp. Poniższy kod najpierw przechwytuje wciśnięcie Tab za
pomocą keyPress, a następnie reaguje na nie w procedurze obsługi zdarzenia keyUp. Warto
zauważyć, że nie korzystamy ze zdarzenia keyDown. Metoda Key.getCode( ) w przeglą-
darce Internet Explorer działa wyłącznie podczas puszczania klawisza Tab.
// KOD DLA PRZYCISKU W GŁÓWNEJ LISTWIE CZASOWEJ
on (keyPress "<Tab>") {
// Ustawienie nieistotnej zmiennej
foo = 0;
}
254
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
// KOD DLA KLIPU W GŁÓWNEJ LISTWIE CZASOWEJ
onClipEvent (keyUp) {
if (Key.getCode( ) == Key.TAB) {
// ustawienie kursora w polu tekstowym
myTextField w _level0
Selection.setFocus("_level0.myTextField");
}
}
Zazwyczaj celem przechwytywania wciśnięcia klawisza Tab jest przesunięcie kursora
wprowadzania tekstu do określonego pola tekstowego w formularzu. Więcej szczegółów
na ten temat znajdziemy w rozdziale „Metoda Selection.SetFocus( )” w części III.
Aby przechwytywać skróty klawiszowe w rodzaju Ctrl/F, posłużymy się procedurą obsługi
zdarzenia klipowego enterFrame w połączeniu z metodą Key.isDown( ):
onClipEvent (enterFrame) {
if (Key.isDown(Key.CONTROL) && Key.isDown(70)) {
// Odpowiedz na wciśnięcie Ctrl-F
}
}
Aby przechwycić wciśnięcie klawisza Enter (Return), można skorzystać z procedury obsługi
zdarzenia przyciskowego:
on (keyPress "<Enter>") {
// Odpowiedz na wciśnięcie Enter (na przykład wysłanie formularza)
}
Można także użyć procedury obsługi zdarzenia keyDown:
onClipEvent (keyDown) {
if (Key.getCode( ) == Key.ENTER) {
// Odpowiedz na wciśnięcie Enter (na przykład wysłanie formularza)
}
}
Więcej informacji o przechwytywaniu specjalnych klawiszy (jak klawisze funkcyjne czy
klawisze z klawiatury numerycznej) znajdziemy w rozdziałach „Obiekt Key” oraz „Metoda
Key.getCode( )” w części III.
keyUp
Zdarzenie keyUp ma miejsce, kiedy wciśnięty klawisz zostanie puszczony. Zdarzenie keyUp
ma kluczowe znaczenie przy programowaniu gier — pozwala wyłączyć to, co zostało
wcześniej włączone przy użyciu keyDown; klasycznym przykładem jest hamowanie statku
kosmicznego. Następnym przykładem może być środowisko Flasha, gdzie wciśnięcie
i przytrzymanie spacji czasowo przełącza na narzędzie Hand, zaś puszczenie spacji przywra-
ca poprzednie narzędzie. Takie podejście może znaleźć zastosowanie w aplikacjach do
wywoływania i ukrywania pewnych elementów (na przykład menu).
Podobnie jak w przypadku keyDown, aby otrzymać od zdarzenia keyUp użyteczną infor-
mację, należy je stosować w połączeniu z obiektem Key:
Kolejność wykonywania
255
onClipEvent (keyUp) {
if (!Key.isDown(Key.LEFT)) {
trace("Strzałka w lewo nie jest wciśnięta");
}
}
Ponieważ metoda Key.isDown( ) pozwala sprawdzać stan dowolnego klawisza w dowolnej
chwili, możemy użyć pętli zdarzenia enterFrame by sprawdzać, czy określony klawisz
został puszczony. Niemniej jednak skanowanie klawiatury (czyli ciągłe sprawdzanie
stanu klawiatury) jest mniej efektywne niż czekanie na zdarzenie keyDown, które poin-
formuje nas, że klawisz został wciśnięty.
Podejście ostatecznie wybrane zależy od rodzaju aplikacji, którą tworzymy. W dyna-
micznej aplikacji, takiej jak gra, skanowanie może być jak najbardziej uzasadnione, ponie-
waż i tak każda klatka przechodzi przez główną pętlę gry. Tak więc podczas wykony-
wania normalnej pętli możemy dodatkowo sprawdzać obiekt Key. Na przykład tak:
// KOD W PUSTYM KLIPIE
// Pętla powodująca, ze gra działa
onClipEvent (enterFrame) {
_root.mainLoop( );
}
// GŁÓWNY KOD GRY W GŁÓWNEJ LISTWIE CZASOWEJ
// To jest wykonywane raz na każdą wyświetloną klatkę
function mainLoop ( ) {
if (Key.isDown(Key.LEFT)) {
trace("Strzałka w lewo jest wciśnięta");
// Obracanie statku kosmicznego w lewo
}
// Sprawdzanie pozostałych klawiszy, a później rozpoczęcie cyklu od nowa
}
W statycznej aplikacji z interfejsem nie musimy używać pętli enterFrame do sprawdzania
stanu klawiszy, chyba że chcemy wychwytywać specjalne kombinacje klawiszy (czyli
kilka klawiszy wciśniętych równocześnie). Zwykle powinniśmy stosować procedury obsługi
zdarzeń keyDown oraz keyUp, które są wywoływane dokładnie raz dla każdego naciśnięcia
i puszczenia klawisza. Używając uchwytów zdarzeń keyUp i keyDown, nie musimy zasta-
nawiać się w każdej chwili, czy klawisz jest wciąż wciśnięty. Ta metoda pozwala precyzyjnie
wykrywać wciskanie klawiszy, nawet jeśli użytkownik puści klawisz między klatkami;
jak również zabezpiecza przed sprawdzaniem dwa razy tego samego klawisza, jeśli był on
wciśnięty tylko raz. Zazwyczaj będziemy korzystać z metod Key.getCode( ) oraz Key.getAscii( )
wraz z procedurami obsługi zdarzeń keyDown i keyUp, by sprawdzić, który klawisz został
wciśnięty jako ostatni.
Kolejność wykonywania
Niektóre aplikacje mają kod podzielony na wiele listew czasowych oraz klipowych pro-
cedur obsługi zdarzeń. Nie jest więc niczym niezwykłym, że w pojedynczej klatce będzie
wykonywany kod podzielony na liczne bloki znajdujące się w procedurach obsługi zda-
rzeń, listwach czasowych klipów oraz głównej listwie czasowej. W takich sytuacjach ko-
lejność, w jakiej różne części kodu są wykonywane, może stać się złożona i mieć poważny
256
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
wpływ na działanie programu. Zapoznanie się z kolejnością, w jakiej procedury obsługi
zdarzeń są wykonywane w stosunku do różnych listew czasowych w filmie, pozwoli
uniknąć przykrych niespodzianek i zagwarantować, że nasz kod będzie zachowywał się,
tak jak chcemy.
Asynchroniczne procedury obsługi zdarzeń są wykonywane niezależnie od kodu znaj-
dującego się na listwach czasowych. Przykładowo przyciskowe procedury obsługi zdarzeń,
podobnie jak procedury obsługi zdarzeń mouseDown, mouseUp, mouseMove, keyDown oraz
keyUp, są wykonywane bezpośrednio po wystąpieniu zdarzenia.
Z kolei procedury obsługi zdarzeń związanych z odtwarzaniem filmu są wykonywane
w określonej kolejności związanej z odtwarzaniem filmu, co pokazuje tabela 10.3.
Tabela 10.3. Kolejność wykonywania procedur obsługi zdarzeń klipów filmowych
Procedura obsługi
zdarzenia
Czas wykonania
load
Jest wykonywana w pierwszej klatce, w której klip pojawia się na scenie,
po wykonaniu kodu z listwy czasowej wyższego poziomu, ale przed
wewnętrznym kodem klipu oraz przed wyświetleniem klatki
unload
Jest wykonywana w pierwszej klatce, w której klipu już nie ma na
scenie, przed wykonaniem kodu z listwy czasowej wyższego poziomu
enterFrame
Jest wykonywana w drugiej i każdej następnej klatce, w których klip
znajduje się na scenie. Jest wykonywana przed kodem z listwy czasowej
wyższego poziomu oraz przed wewnętrznym kodem klipu
data
Jest wykonywana w każdej klatce, w której klip otrzymuje dane. Jeśli
zostanie wywołana, jest wykonywana zarówno przed wewnętrznym
kodem klipu, jak i kodem procedury enterFrame
Zasady zawarte w tabeli 10.3 łatwiej przyswoić na konkretnym przykładzie. Załóżmy, że
mamy film zbudowany z jednej warstwy, z czterema klatkami kluczowymi na głównej
listwie czasowej. Do każdej z tych klatek dołączamy pewien kod. Następnie dodajemy
drugą warstwę, w której umieszczamy klip filmowy w klatkach od 1. do 3. (czyli w klat-
ce 4. klipu już nie ma). W naszym klipie wprowadzamy procedury obsługi zdarzeń load,
enterFrame oraz unload. W końcu wewnątrz klipu tworzymy trzy klatki kluczowe, z których
każda również zawiera fragment kodu. Rysunek 10.2 pokazuje, jak wygląda nasz film.
Kiedy odtwarzamy nasz film, kolejność wykonywania kodu jest następująca.
========KLATKA 1========
1. Wykonanie kodu z głównej listwy czasu
2. Wykonanie kodu procedury obsługi zdarzenia load
3. Wykonanie kodu z klatki 1. klipu
========KLATKA 2========
1. Wykonanie kodu procedury obsługi zdarzenia enterFrame
2. Wykonanie kodu z klatki 2. klipu
3. Wykonanie kodu z głównej listwy czasu
========KLATKA 3========
1. Wykonanie kodu procedury obsługi zdarzenia enterFrame
2. Wykonanie kodu z klatki 3. klipu
3. Wykonanie kodu z głównej listwy czasu
Kopiowanie procedur obsługi zdarzeń klipowych
257
Rysunek 10.2. Kolejność wykonywania kodu w przykładowym filmie
========KLATKA 4========
1. Wykonanie kodu procedury obsługi zdarzenia unload
2. Wykonanie kodu z głównej listwy czasu
Kolejność wykonywania kodu w naszym przykładowym filmie obrazuje kilka reguł, które
warto mieć w małym palcu podczas programowania przy wykorzystaniu procedur ob-
sługi zdarzeń.
• Kod procedury obsługi zdarzenia load jest wykonywany przed wewnętrznym kodem
klipu, może więc zostać użyty do inicjalizacji zmiennych, które zostaną wykorzystane
już w pierwszej klatce klipu.
• Kod znajdujący się w klatce, w której klip pojawia się na scenie, jest wykonywany
przed kodem procedury obsługi zdarzenia load. Z tego względu zmienne oraz funkcje
zdefiniowane przez użytkownika w klipie są dostępne dla listwy czasowej wyższego
poziomu dopiero od następnej klatki po klatce, w której klip pojawił się na scenie, nawet
jeśli te zmienne i funkcje zostały zadeklarowane w procedurze obsługi zdarzenia load.
• Procedura obsługi zdarzenia enterFrame nigdy nie jest wykonywana w tej samej klatce
co procedury obsługi zdarzeń load i unload. Zdarzenia load i unload zastępują enterFrame
w klatkach, w których klip pojawia się na scenie oraz z niej znika.
• W każdej klatce kod procedury obsługi zdarzenia enterFrame jest wykonywany przed
kodem w listwie czasu rodzica. Dzięki temu, korzystając z procedury obsługi zdarzenia
enterFrame, możemy zmieniać właściwości listwy czasowej elementu nadrzędnego
względem klipu i od razu wykorzystywać je w kodzie tej listwy czasowej, a wszystko
podczas odtwarzania jednej klatki.
Kopiowanie procedur obsługi zdarzeń klipowych
Na początek krótkie stwierdzenie mające poważne implikacje — procedury obsługi zdarzeń
są kopiowane razem z klipem podczas powielania za pomocą funkcji duplicateMovieClip( ).
Przypuśćmy, że mamy na scenie klip o nazwie square zawierający następującą procedurę
obsługi zdarzenia load:
258
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
onClipEvent (load) {
trace("Klip załadowany");
}
Co się stanie, jeśli skopiujemy square, tworząc square2?
square.duplicateMovieClip("square2", 0);
Ponieważ procedura obsługi zdarzenia load jest kopiowana razem z klipem square, utwo-
rzenie square2 powoduje wykonanie jego procedury obsługi zdarzenia load, wyświetlającej
w okienku Output napis „Klip załadowany”. Korzystając z tego automatycznego utrzymy-
wania procedur, możemy sprawnie utworzyć funkcje rekurencyjne dające spore korzyści.
Aby przekonać się, że to tylko czubek góry lodowej możliwości tkwiących w tym me-
chanizmie, przyjrzyjmy się listingowi 10.2.
Odświeżanie ekranu
przy użyciu updateAferEvent
Jak dowiedzieliśmy się wcześniej w podrozdziale „Kolejność wykonywania”, procedury
obsługi zdarzeń mouseDown, mouseUp, mouseMove, keyDown oraz keyUp są wykonywane
od razu po zajściu tych zdarzeń. Od razu znaczy natychmiast, nawet jeśli zdarzenie miało
miejsce między wyświetleniem kolejnych klatek.
Ta szybkość wykonania może dać filmowi możliwość równie szybkiego reagowania, lecz
możemy ją łatwo stracić. Domyślnie efekty wizualne działania procedur obsługi zdarzeń
mouseDown, mouseUp, mouseMove, keyDown oraz keyUp nie zostaną fizycznie wyświetlone
przez odtwarzacz Flash Player przed wyświetleniem kolejnej klatki. By przekonać się, że
tak to działa, utworzymy jednoklatkowy film o szybkości odtwarzania równej 1 fps
i umieścimy na scenie klip z następującym kodem.
onClipEvent (mouseDown) {
_x +=2;
}
Uruchomimy film i postaramy się klikać najszybciej jak tylko można. Zauważymy, że
wszystkie kliknięcia zostały zarejestrowane, lecz klip przesuwa się tylko raz w ciągu
sekundy. Jeśli więc klikniemy 6 razy między klatkami, klip przesunie się w prawo o 12
pikseli podczas wyświetlania kolejnej klatki. Jeśli klikniemy 3 razy, klip przesunie się o 6
pikseli. Każde wykonanie procedury obsługi zdarzenia mouseDown jest więc rejestrowane
między klatkami, ale efekty można zobaczyć dopiero po wyświetleniu klatki. Może mieć
to dramatyczne skutki dla niektórych form interaktywności.
Na szczęście możemy zmusić Flash do natychmiastowego odwzorowywania każdej wizual-
nej zmiany spowodowanej przez uchwyt zdarzenia bez potrzeby czekania na następną
klatkę. Zrobimy to, wywołując funkcję updateAfterEvent( ) z wnętrza naszej procedury
w sposób następujący:
Dynamiczne procedury obsługi zdarzeń klipów filmowych
259
onClipEvent (mouseDown) {
_x +=2;
updateAfterEvent( );
}
Funkcję updateAfterEvent( ) można wykorzystywać tylko ze zdarzeniami mouseDown, mouse-
Up, mouseMove, keyDown oraz keyUp. Ma to często kluczowe znaczenie dla płynnego oraz
szybko reagującego odtwarzania filmu w warstwie wizualnej podczas różnych działań
użytkownika. Dalej, w listingu 10.8, użyjemy funkcji updateAfterEvent( ) do płynnego
wyświetlania niestandardowego kursora. Trzeba zwrócić uwagę, że zdarzenia przyci-
skowe nie potrzebują bezpośredniego użycia funkcji updateAfterEvent( ), przyciski bowiem,
zgodnie ze swą naturą, są odświeżane między klatkami.
Wielokrotne użycie kodu
Korzystając ze zdarzeń przyciskowych czy klipowych, nie zapominajmy o zasadach
skupiania kodu poznanych w rozdziale 9. Zawsze starajmy się unikać niepotrzebnego
powielania oraz mieszania kodu między różnymi elementami filmu. Jeśli stwierdzimy,
że wpisujemy ten sam kod w kolejnej procedurze obsługi zdarzenia, może nie jest naj-
lepszym pomysłem dołączanie go bezpośrednio do obiektu.
Musimy starać się, aby kod był najbardziej ogólny, przenośmy go z obiektów do „prze-
chowalni kodu”. Jednym z takich miejsc jest główna listwa czasowa. W wielu przypad-
kach ukrywanie kodu w procedurach obsługi przycisków czy klipów nie jest najlepszym
rozwiązaniem. Pamiętajmy, że umieszczenie kodu w funkcji i wywoływanie jej w pro-
cedurach obsługi zdarzeń uczyni go łatwym do znalezienia i wprowadzania zmian. Jest
to szczególnie istotne w przypadku przycisków — sam rzadko umieszczam w przycisku
coś innego niż wywołanie funkcji. W przypadku klipów filmowych musimy kierować
się zdrowym rozsądkiem — umieszczenie kodu bezpośrednio w klipie może prowadzić
do uporządkowanej, zawierającej dobrze podzielone skrypty architektury kodu. Próbujmy
z różnymi podejściami, aż znajdziemy złoty środek między potrzebami a umiejętno-
ściami. Zawsze warto brać pod uwagę niepotrzebną nadmiarowość oraz łatwość wielo-
krotnego użycia.
By zobaczyć różnicę między umieszczeniem kodu bezpośrednio w przycisku a wywo-
ływaniem funkcji z przycisków, przyjrzymy się podrozdziałowi „Wszystkie skrypty
w jednym miejscu” w rozdziale 9.
Dynamiczne procedury
obsługi zdarzeń klipów filmowych
Na początku tego rozdziału omówiliśmy dwa rodzaje zdarzeń we Flashu — te, które są
powiązane z klipami i przyciskami oraz te, które są związane z obiektami danych, jak
XML czy XMLSocket. Aby utworzyć procedurę obsługi zdarzenia dla obiektu danych,
przypisujemy do niego funkcję nazwaną, tak jak właściwość obiektu. Przypominamy
składnię dynamicznego dołączania funkcji.
260
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
myXMLdoc.onload = function ( ) { trace("Wszystko załadowane");};
Dynamiczne przypisywanie funkcji pozwala na zmianę działania procedury obsługi
zdarzenia podczas odtwarzania filmu. Musimy tylko zmienić przypisanie właściwości
procedury:
myXMLdoc.onload = function ( ) { gotoAndPlay("displayData");};
Możemy nawet wyłączyć działanie procedury:
myXMLdoc.onload = function ( ) { return;};
Niestety procedury obsługi zdarzeń dla klipów i przycisków nie są tak elastyczne; nie
mogą być zmieniane lub usuwane podczas odtwarzania filmu. Procedury obsługi zdarzeń
także nie mogą być w żaden sposób dołączane do głównej listwy czasowej filmu! Nie
można bezpośrednio utworzyć uchwytu zdarzenia dla poziomu _root.
Aby obejść to ograniczenie — w przypadku enterFrame oraz zdarzeń użytkownika —
możemy wykorzystać pusty klip filmowy, by zasymulować dynamiczną podmianę lub
usuwanie procedur obsługi zdarzeń. Pusty klip umożliwia nawet symulowanie zdarzeń
na poziomie _root. Widzieliśmy już tę technikę w rozdziale 8., gdzie poznawaliśmy
tworzenie pętli zdarzenia.
1.
Tworzymy pusty klip filmowy o nazwie process.
2.
W jego wnętrzu umieszczamy kolejny pusty klip o nazwie eventClip.
3.
Do klipu eventClip dołączamy potrzebną procedurę obsługi zdarzenia. Kod zawarty
w tej procedurze powinien adresować listwę czasową klipu process w sposób
następujący:
on ClipEvent (mouseMove) {
_parent._parent.doSomeFunction( );
}
4.
Aby przygotować klip process do użycia z funkcją attachMovie( ), wybieramy go
w oknie Library, a następnie wybieramy polecenie Linkage z menu Options. Wybieramy
opcję Export This Symbol i przypisujemy mu odpowiedni identyfikator (na przykład
mouseMoveProcess
).
5.
Aby wykorzystać naszą procedurę obsługi zdarzenia, dołączamy klip process do
odpowiedniej listwy czasu, używając funkcji attachMovie( ).
6.
By odłączyć procedurę, usuwamy klip process za pomocą funkcji removeMovieClip( ).
Instrukcję tłumaczącą krok po kroku wykorzystanie tej techniki ze zdarzeniem enterFrame
znajdziemy w podrozdziale „Pętle sterowane zdarzeniami” w rozdziale 8.
Zastosowanie procedur obsługi zdarzeń
Nasze poznawanie zdarzeń ActionScript oraz procedur ich obsługi podsumujmy kilkoma
przykładami. Będą to proste aplikacje, które dadzą obraz tego, jak elastyczne może być
Zastosowanie procedur obsługi zdarzeń
261
programowanie oparte na zdarzeniach. Dwa ostatnie przykłady można pobrać z witryny
internetowej Code Depot oraz z serwera FTP Wydawnictwa Helion. Listing 10.7 powiększa
i pomniejsza klip filmowy.
Listing 10.7. Zmiana wielkości klipu filmowego
onClipEvent (load) {
var shrinking = false;
var maxHeight = 300;
var minHeight = 30;
}
onClipEvent (enterFrame) {
if (_height < maxHeight && shrinking == false) {
_height += 10;
_width += 10;
} else {
shrinking = true;
}
if (shrinking == true) {
if (_height > minHeight) {
_height -= 10;
_width -= 10;
} else {
shrinking = false;
_height += 10;
// Zwiększenie już tutaj
_width += 10;
// dzięki temu nie stracimy cyklu
}
}
}
Listing 10.8 symuluje niestandardowy wskaźnik myszy przez ukrycie kursora systemo-
wego i przesuwanie klipu po ekranie za ruchem niewidocznego wskaźnika. W przykła-
dzie procedury obsługi zdarzeń mouseDown i mouseUp delikatnie zmieniają rozmiary
myszy, by zasygnalizować kliknięcie.
Listing 10.8. Niestandardowy kursor myszy
onClipEvent (load) {
Mouse.hide( );
}
onClipEvent (mouseMove) {
_x = _root._xmouse;
_y = _root._ymouse;
updateAfterEvent( );
}
onClipEvent (mouseDown) {
_width *= .5;
_height *= .5;
updateAfterEvent( );
}
onClipEvent (mouseUp) {
_width *= 2;
_height *= 2;
updateAfterEvent( );
}
262
Rozdział 10. Zdarzenia i moduły obsługi zdarzeń
Na koniec, tylko by pokazać możliwości procedur obsługi zdarzeń klipowych w Action-
Script — listing 10.9 zamieniający klip w symulowany przycisk. Procedura obsługi zdarzenia
mouseMove sprawdza najechanie kursora na przycisk. Procedury mouseUp i mouseDown spra-
wdzają klikanie przycisku. Funkcja hitTest( ) sprawdza, czy kursor znajduje się w „obszarze
aktywnym”. Nasz przykład zakłada, że klip z procedurą składa się z trzech klatek kluczo-
wych nazwanych up, down i over (co odpowiada stanom normalnego przycisku).
Listing 10.9. Klipowy przycisk
onClipEvent (load) {
stop( );
}
onClipEvent (mouseMove) {
if (hitTest(_root._xmouse, _root._ymouse, true) && !buttonDown) {
this.gotoAndStop("over");
} else if (!hitTest(_root._xmouse, _root._ymouse, true) && !buttonDown) {
this.gotoAndStop("up");
}
updateAfterEvent( );
}
onClipEvent (mouseDown) {
if (hitTest(_root._xmouse, _root._ymouse, true)) {
buttonDown = true;
this.gotoAndStop("down");
}
updateAfterEvent( );
}
onClipEvent (mouseUp) {
buttonDown = false;
if (!hitTest(_root._xmouse, _root._ymouse, true)) {
this.gotoAndStop("up");
} else {
this.gotoAndStop("over");
}
updateAfterEvent( );
}
Naprzód!
Poznając wyrażenia, operatory i funkcje, a ostatnio zdarzenia i procedury ich obsługi,
nauczyliśmy się, jak działają wszystkie wewnętrzne narzędzia ActionScript. By pogłębić
naszą znajomość języka, w trzech kolejnych rozdziałach zajmiemy się trzema niezmiernie
ważnymi typami danych: tablicami, obiektami oraz klipami filmowymi.