I denne opplæringen skal jeg forklare ActionScript 3.0 Event Framework. Etter denne opplæringen bør du ha en klar forståelse av hvordan hendelser, hendelsesforhandlere og hendelseslyttere jobber.
Fordi AS3-arrangementet er stort, ser vi på alle de forskjellige tingene som komponerer hendelsesrammen. Vi lærer om følgende:
Jeg tror virkelig du vil ha en vanskelig tid å forstå begivenhetsrammen hvis vi hopper rett inn i det tekniske jargonget, så jeg vil først beskrive en situasjon i virkeligheten. Hele situasjonen er en metafor for arrangementet. Ok, så her går vi:
Jeg er en ivrig leser av Computer Arts og jeg venter hver eneste dag på det nye problemet. Når jeg mottar problemet, begynner jeg å lese det.
Ok, vi har flere ting på gang:
Jeg har nevnt flere ting:
En hendelse er et objekt som beskriver en forekomst, i Trinn 1 hendelsen er ankomsten av et nytt problem.
De fleste ganger ser du et arrangement som er skrevet i en struktur som ligner på dette:
MouseEvent.CLICK
Denne kodebiten består av to ting:
Hendeltypen er faktisk en statisk konstant streng. Det høres kanskje rart ut, men en hendelse er ingenting annet enn en streng. Prøv å kjøre denne koden.
spore (MouseEvent.MOUSE_MOVE);
Du får som utgang mousemove. Vi har nettopp sporet den konstante MOUSE_MOVE, som er inne i MouseEvent-klassen. En hendelse er en streng! Men denne strengen representerer forekomsten av (i dette eksempelet) musens bevegelse.
En hendelse skjer alltid et sted. Hvor hendelsen skjer er hvor det blir sparket (sendt). Røttene til å sende hendelser er i klassen EventDispatcher. Gjør innse at hvor arrangementet sendes er hvor det skjer. Så hvis filmklipp A sender en hendelse, og en hendelselytter (hendelseslyttere vil bli forklart i trinn 5) lagt til filmklipp B ville ikke motta denne hendelsen.
For å gjøre det enkelt, har alle skjermobjektene den innebygde funksjonen dispatchEvent (hendelse: Hendelse), akkurat som mange andre klasser.
var myMC: MovieClip = ny MovieClip (); myMC.dispatchEvent (nytt arrangement (MouseEvent.CLICK));
Men de fleste ganger vil du ikke sende hendelser manuelt, de fleste ganger sendes hendelser automatisk. Hvis jeg for eksempel klikker på filmklipp A, vil den automatisk sende hendelsen MouseEvent.CLICK.
Når en bestemt hendelse skjer, vil vi som Flash-utviklere gjerne gjøre noe for å svare på denne hendelsen. Eventlyttere er det du trenger. Eventlyttere har ikke sin egen klasse, nei de er litt annerledes. Eventlyttere legges til i et objekt. Eventlyttere er objekter som "lytter" til en bestemt hendelse. Når denne hendelsen skjer, blir en funksjon kalt a handler (funksjon).
Se på bildet nedenfor, og vis syntaxen bak funksjonen addEventListener (), som brukes til å legge til en hendelseslytter:
Egentlig er det ikke alle parametrene som addEventListener-metoden aksepterer, det er fortsatt tre som jeg ikke har nevnt. Du vil nesten aldri bruke dem, spesielt når du nettopp har begynt å bruke hendelseslyttere. La oss se igjen på strukturen i addEventListener-metoden.
addEventListener (type: String, lytter: Funksjon, useCapture: Boolean = false, prioritet: int = 0, useWeakReference: Boolean = false): void
Så la oss diskutere de siste 3 parametrene:
Å fjerne en hendelseslytter er like enkelt som å legge til en.
// dette legger til en hendelse lytter til scenen stage.addEventListener (MouseEvent.CLICK, clickHandler); // dette fjerner hendelseslytteren lagt til scenen stage.removeEventListener (MouseEvent.CLICK, clickHandler);
Når hendelsen oppstår som en hendelseslytter lytter etter, kalles det en funksjon. Denne funksjonen kalles behandleren eller lytterfunksjon. Se på bildet nedenfor, som viser handlerens syntaks:
Legg merke til argumentet i handleren, dette argumentet er obligatorisk. Lytterfunksjonen har bare ett argument og har ikke lov til å ha mer. Denne hendelsen inneholder informasjon om hendelsen, vi snakker om dette i trinn 9.
Nå ønsker vi at minMC skal svare på den sendte hendelsen, så vi legger til en hendelse og etterpå handlerfunksjonen. Vår kode vil se slik ut:
// lage vårt myMC-filmklipp var myMC: MovieClip = ny MovieClip (); // la minMC sende hendelsen MouseEvent.CLICK myMC.dispatchEvent (ny begivenhet (MouseEvent.CLICK)); // legge til en hendelse lytter til myMC, som lytter til hendelsen MouseEvent.CLICK, og vil ringe clickHandler myMC.addEventListener (MouseEvent.CLICK, clickHandler); // definer håndteringsfunksjonen clickHandler (event: Event) trace ("Jeg hørte hendelsen MouseEvent.CLICK");
Etterpå test filmen din (Windows: Ctrl + Enter, Mac: Cmd + Enter).
Fikk du noe output? Nei? Vel, det gjorde jeg heller ikke. Vi ser på hva som går galt i neste trinn.
Så hva går galt? Vel, det kan ikke være en syntaksfeil, i det minste Jeg er ikke får noe. Nei, dette er teknisk ikke engang en feil. Se på koden igjen, men denne gangen husker du at koden vil bli utført linje for linje:
// lage vårt myMC-filmklipp var myMC: MovieClip = ny MovieClip (); // la minMC sende hendelsen MouseEvent.CLICK myMC.dispatchEvent (ny begivenhet (MouseEvent.CLICK)); // legge til en hendelse lytter til myMC, som lytter til hendelsen MouseEvent.CLICK, og vil ringe clickHandler myMC.addEventListener (MouseEvent.CLICK, clickHandler); // definer håndteringsfunksjonen clickHandler (event: Event) trace ("Jeg hørte hendelsen MouseEvent.CLICK");
Jeg håper du har forstått hva som har gått galt: arrangementet blir sendt før en eventlytter har blitt lagt til i minMC. Så når hendelseslytteren er lagt til, er det for sent, hendelsen har skjedd. Heldigvis er det enkelt å løse, bare endre rekkefølgen og først legge til hendelseslytteren, og deretter sende hendelsen:
// lage vårt myMC-filmklipp var myMC: MovieClip = ny MovieClip (); // legge til en hendelse lytter til myMC, som lytter til hendelsen MouseEvent.CLICK, og vil ringe clickHandler myMC.addEventListener (MouseEvent.CLICK, clickHandler); // la minMC sende hendelsen MouseEvent.CLICK myMC.dispatchEvent (ny begivenhet (MouseEvent.CLICK)); // definer håndteringsfunksjonen clickHandler (event: Event) trace ("Jeg hørte hendelsen MouseEvent.CLICK");
Så hvorfor gjorde vi alt det? Vel, du vil trolig støte på dette problemet, og det kan ta litt tid å innse hva som skjer. Det er bedre å vise deg problemet og lære deg å løse det.
Hver håndteringsfunksjon har et argument; hendelsesargumentet. Dette argumentet inneholder data om hendelsen og hendelsesleverandøren. Parameteren inneholder egenskaper som vi ønsker å lese. Her er en liste over noen av de mest brukte:
Med dette kan vi bruke samme handler for ulike typer hendelser. Hvordan? Vel, vi diskuterer dette i neste trinn.
Ok, først, se på dette kodestykket:
stage.addEventListener (MouseEvent.MOUSE_DOWN, downHandler); stage.addEventListener (MouseEvent.MOUSE_UP, upHandler); funksjon downHandler (event: MouseEvent) trace ("Down"); funksjon upHandler (event: MouseEvent) trace ("Up");
Vi bruker to hendelser, nemlig MouseEvent.MOUSE_DOWN og MouseEvent.MOUSE_UP. Den første hendelsen er hendelsen når musen trykker på den primære museknappen og holder den ned. Når personen slipper denne knappen, skjer hendelsen MouseEvent.MOUSE_UP. Museknappen går opp etter å ha slettet den.
Nå kan vi bruke i stedet for to håndtere (nemlig downHandler og upHandler) bare en handler. Fjern koden vi har skrevet og skriv følgende:
stage.addEventListener (MouseEvent.MOUSE_DOWN, handler); stage.addEventListener (MouseEvent.MOUSE_UP, handler); funksjonshåndterer (event: MouseEvent) trace ("Noe har skjedd ...");
Ok, vi har satt opp vår handler og det fungerer, men vi vil at vår handler skal gjøre noe spesifikt, avhengig av hvilken hendelse som er overført til handleren. Heldigvis kan vi bruke event.type. La oss bruke den!
stage.addEventListener (MouseEvent.MOUSE_DOWN, handler); stage.addEventListener (MouseEvent.MOUSE_UP, handler); funksjonshåndterer (event: MouseEvent) if (event.type == "mouseDown") trace ("Down"); else trace ("Up");
La oss si at et klikk skjer på en filmklipp, la oss kalle det MCA. Arrangementet blir ikke bare sendt på mcA, nei, hendelsen beveger seg gjennom hele spilleren. Denne reisen kalles hendelsesflyt, bare tenk hvordan hendelsen flyter gjennom spilleren.
Arrangementet starter på toppnivå, på scene, etterpå vil det gå gjennom foreldre av MCA, til hendelsen når mcA. Etterpå vil arrangementet "boble" tilbake fra mcA, tilbake til scenen.
Ok, kult, men hva kan jeg bruke dette til? Fordi vi nå vet at et arrangement reiser gjennom alle foreldrene til forsendelsen, kan vi bare bruke en hendelseslytter, for å spore hendelsene i mer enn ett objekt.
Ok, så la oss lage flere filmklipp inni hverandre. Du kan gjøre dette selv, eller bare bruke trinn-11.fla-filen som er oppgitt.
Vi lager 3 filmklipp, og vi vil gi dem forekomstnavnene redMC, blueMC og greenMC. Etterpå plasserer alle disse inne i en større filmklipp, oppkalt container.
La oss nå begynne å skrive kode. Jeg har allerede opprettet et lag som heter handlinger, så skriv koden din på det laget. Først la vi legge til en hendelseslytter til container, lytter til arrangementet MouseEvent.CLICK, med håndterer oppkalt clickHandler.
container.addEventListener (MouseEvent.CLICK, clickHandler); funksjon clickHandler (event: MouseEvent) // funksjon body
Vi vil vite hvilken knapp som blir klikket, så hvorfor la vi en eventlytter til container? Vel, se på bildet nedenfor:
Som du ser, blir arrangementet sendt på RedMC, men det vil boble tilbake til beholderen. Da hendelseslytteren som legges til beholderen, hører hendelsen og vil ringe lytterfunksjonen clickHandler. Det samme skjer med blueMC og greenMC.
Nå skal vi bruke event.target, fordi event.target er hendelse-dispatcheren, og hendelse-senderen er redMC. Så hvordan kan vi bruke event.target? Vi kan sjekke event.target.name, som returnerer forekomstnavnet som en streng. Så vi kan bare bruke normal hvis uttalelser:
container.addEventListener (MouseEvent.CLICK, clickHandler); funksjon clickHandler (event: MouseEvent) if (event.target.name == "redMC") trace ("Red"); hvis (event.target.name == "blueMC") trace ("Blue"); hvis (event.target.name == "greenMC") trace ("Green");
Nå har du en god forståelse av hendelsesrammen, men for å oppnå noe, er det viktig å vite hvilken begivenhet som skal brukes. Et flott sted å sjekke hvilke hendelser som finnes, er referanse for ActionScript 3.0-språk og komponenter. Bare klikk på et arrangement som inneholder klasse, som MouseEvent, og se på hva hver hendelse er.
Denne hendelsen oppstår når brukeren beveger musen. Hvis du legger til en hendelselytter som lytter til denne hendelsen, la oss si en filmklip som heter myMC, da vil du vite når musen beveger seg over minMC.
myMC.addEventListener (MouseEvent.MOUSE_MOVE, mouseMoveHandler); funksjon mouseMoveHandler (event: MouseEvent) trace ("musen beveger seg over minMC");
Denne hendelsen oppstår når brukeren beveger seg over (svinger). Denne hendelsen oppstår bare når brukeren flytter markøren fra et annet sted over objektet. Flytter musen over objektet er ikke lenger hendelsen MouseEvent.MOUSE_OVER, men hendelsen MouseEvent.MOUSE_MOVE.
myMC.addEventListener (MouseEvent.MOUSE_OVER, overHandler); funksjon overHandler (event: MouseEvent) trace ("Du har bare flyttet musen på myMC");
Denne hendelsen er nettopp det motsatte av MouseEvent.MOUSE_OVER. Dette er når brukerens markør beveger seg fra objektet, eller som de (gutta som opprettet AS3) kalte det ut av objektet.
myMC.addEventListener (MouseEvent.MOUSE_OUT, outHandler); fungere outHandler (event: MouseEvent) trace ("Du har bare flyttet musen ut myMC");
Denne hendelsen oppstår når brukeren trykker på den primære musen, mens den holdes nede.
myMC.addEventListener (MouseEvent.MOUSE_DOWN, downHandler); funksjon downHandler (event: MouseEvent) trace ("Den primære museknappen er trykket ned på myMC");
Denne hendelsen er nettopp det motsatte av MouseEvent.MOUSE_DOWN. Når brukeren slipper den primære museknappen, oppstår hendelsen MouseEvent.MOUSE_UP.
myMC.addEventListener (MouseEvent.MOUSE_UP, upHandler); funksjon upHandler (event: MouseEvent) trace ("Den primære museknappen har blitt sluppet, mens den svømte over minMC");
Vel, navnet gjør det allerede ganske klart når denne hendelsen oppstår. Denne hendelsen skjer når brukeren klikker (med den primære museknappen).
myMC.addEventListener (MouseEvent.CLICK, clickHandler); funksjon clickHandler (event: MouseEvent) trace ("Du har nettopp klikket myMC");
Vel, dette skjer når brukeren klikker to ganger (med den primære museknappen). Legg merke til at når MouseEvent.DOUBLE_CLICK oppstår, skjer MouseEvent.CLICK for andre gang.
myMC.addEventListener (MouseEvent.DOUBLE_CLICK, doubleClickHandler); funksjon doubleClickHandler (event: MouseEvent) trace ("Du har bare dobbeltklikket myMC");
Hvis du nå tester filmen og dobbeltklikker, skjer ingenting. Hvorfor? Vel som standard filmklipp (og nesten alle visningsobjekter) har egenskapen doubleClickEnabled satt til false. Så MouseEvent.DOUBLE_CLICK vil ikke bli sendt. Bare sett den til sann, og alt vil fungere fint.
myMC.addEventListener (MouseEvent.DOUBLE_CLICK, doubleClickHandler); funksjon doubleClickHandler (event: MouseEvent) trace ("Du har bare dobbeltklikket myMC"); myMC.doubleClickEnabled = true;
Denne hendelsen skjer hver gang objektet kommer inn i en ny ramme (ja det høres litt rart). Vel i utgangspunktet skjer denne hendelsen med frekvensen av bildefrekvensen. Det betyr at hvis filmen din har en framerate på 30 fps, blir hendelsen kalt 30 ganger i sekundet. Hva ville du bruke denne hendelsen for? Du kan bruke denne hendelsen for å få ting til å skje gradvis. For eksempel kan du øke et objekts x-koordinat med 5, med frekvensen av bildefrekvensen.
myMC.addEventListener (Event.ENTER_FRAME, enterFrameHandler); funksjon enterFrameHandler (event: Event) myMC.x + = 5;
Denne hendelsen oppstår når objektet fullfører uansett hva det gjorde. De fleste ganger bruker du det for ting som trenger å laste noe, eller for ting som spiller noen form for media. En URLLoader laster en URLRequest, etter at URLLoader fullfører lasting, da laster vi inn disse dataene i en annen laster og deretter legger lasteren til scenen.
var myURLRequest: URLRequest = ny URLRequest ("http://farm3.static.flickr.com/2382/1616598266_bafebf0086_o.jpg"); var myURLLoader: URLLoader = ny URLLoader (myURLRequest); myURLLoader.dataFormat = URLLoaderDataFormat.BINARY; myURLLoader.addEventListener (Event.COMPLETE, completeHandler); funksjon completeHandler (event: Event) var loader: Loader = new Loader (); loader.loadBytes (myURLLoader.data); addChild (loader);
Denne hendelsen oppstår når flash-spilleren eller siden hvor blitsen er inneholdt, er endret. Du kan bruke denne hendelsen til å plassere objekter etter at størrelsen har skjedd.
stage.addEventListener (Event.RESIZE, resizeHandler); funksjon resizeHandler (event: Event) trace ("Dimensjonene på scenen er" + scene.stageWidth + "x" + stage.stageHeight);
Denne hendelsen oppstår når noen Tasten trykkes på tastaturet.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); funksjonstastDownHandler (event: KeyboardEvent) trace ("Du har bare trykket på en nøkkel!");
Denne hendelsen er nettopp det motsatte av KeyboardEvent.KEY_DOWN, denne hendelsen oppstår når noen nøkkelen slippes ut (nøkkelen går opp).
stage.addEventListener (KeyboardEvent.KEY_UP, keyUpHandler); funksjon keyUpHandler (event: KeyboardEvent) trace ("Du har nettopp gitt ut en nøkkel");
Selvfølgelig er det ganske ubrukelig å svare på hvilken som helst tast (unntatt en skjermsparer), så vi må hente informasjon om hvilken tast som er trykket. Heldigvis er noen av nøklene bygget inn i klassen KeyboardEvent, disse er boolesker og er satt til ekte når den trykkes ned. Disse bygget i booleans er:
Så nå kan vi bruke dette til å være mer spesifikk hvilken nøkkel som må trykkes før vi gjør noe.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); funksjon keyDownHandler (event: KeyboardEvent) if (event.shiftKey) trace ("Du har bare trykket på shift-tasten");
Du lurer kanskje på, hva med alle de andre nøklene? Vel, det er noe som heter nøkkelkode. Hver nøkkel har et visst tall; en nøkkelkode. Vi kan sjekke nøkkelkoden til nøkkelen som utløste hendelsen. Dette er gjort med event.keyCode, som returnerer et heltall. Klikk her for en liste over nøkkelkoder. Selv om det er for javascript, er de viktigste kodene de samme.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); funksjon keyDownHandler (event: KeyboardEvent) if (event.keyCode == 65) trace ("Du har bare trykket på A-tasten");
Nå er det enklere å lagre nøkkelkoder i en variabel (eller hvis du er hardcore, i en klasse) og bare bruk den variabelen, i stedet for nøkkelkoden.
var A: uint = 65; stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); funksjon keyDownHandler (event: KeyboardEvent) if (event.keyCode == A) trace ("Du har bare trykket på A-tasten");
Med nøkkelkoder kan du få ganske mye gjort, men det er noen ganger ikke det du trenger. For eksempel brukes samme nøkkel for tegnene en og EN. Men vi vil fortsatt ha å skille mellom de to. Vel, hendelsen bærer tegnkoden til hendelsesleverandøren.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); funksjonstastDownHandler (event: KeyboardEvent) trace (event.charCode);
Ok, dette virker, men må vi da huske disse tegnkoder? Nei. Heldigvis kan vi bruke funksjonen charCodeAt (), som returnerer tegnkoden til et tegn (i en streng). charCodeAt () tar som standard det første tegnet ut av strengen. charCodeAt (0) er det første tegnet, charCodeAt (1) den andre, etc..
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); funksjon keyDownHandler (event: KeyboardEvent) if (event.charCode == String ("a"). charCodeAt ()) trace ("Du har bare trykket på små bokstaver en tast");
Prøv nå å skrive følgende:
myMC.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); funksjon keyDownHandler (event: KeyboardEvent) trace ("Du har bare trykket på en tast mens du er fokusert på myMC");
Prøv å teste dette, det vil ikke fungere! Hvorfor? Hvis myMC er et filmklipp, vil det ikke akseptere tastaturinngang, slik at tastaturhendelser ikke sendes på filmklipp. Hvis du vil at minMC skal svare, legger du hendelseslytteren til scenen og gjør at minMC gjør noe. Prøv å endre minMC fra et filmklipp til et dynamisk tekstfelt, så vil det fungere.
Hva med to dynamiske tekstfelter? Hvis brukeren skriver, sender begge tekstfelt en hendelse? Nei, bare den du skriver inn. Dette kalles fokus. Tastaturhendelser sendes av objektet som har fokus. Scenen er det eneste objektet som fortsatt har fokus, mens et annet objekt også har fokus.
Denne hendelsen er spesielt bygget for timere. Det blir sendt til en tidtaker som nettopp nådde forsinkelsestiden. Dette betyr at du kan bruke denne hendelsen til å gjøre noe veldig nøyaktig, med bestemte tidsintervaller.
Var minTimer: Timer = Ny Timer (1000, 5); myTimer.start (); myTimer.addEventListener (TimerEvent.TIMER, timerHandler); funksjon timerHandler (hendelse: TimerEvent) trace ("et sekund senere ...");
Alle timere har en valgfri andre parameter. Denne parameteren setter repetertellingen til timeren. Dette betyr at når timeren når forsinkelsestiden, starter den igjen. Hvis timeren har gjentatt så ofte som repetertellingen, vil den sende hendelsen TimerEvent.TIMER_COMPLETE.
Var minTimer: Timer = Ny Timer (1000, 5); myTimer.start (); myTimer.addEventListener (TimerEvent.TIMER_COMPLETE, timerHandler); funksjon timerHandler (hendelse: TimerEvent) trace ("Timeren har gjentatt 5 ganger");
Det var det! Jeg håper at du nå har en grundig forståelse av handlingsrammen for ActionScript 3.0. Gjør innse at de diskuterte hendelsene ikke er alle hendelsene som eksisterte, jeg diskuterte bare de jeg bruker ofte. Ikke glem å alltid sjekke språk- og komponentreferansen, det kan hjelpe deg mye! Det var en glede å skrive for dere!