In deze tutorial zal ik het ActionScript 3.0 Event Framework uitleggen. Na deze tutorial zou je een goed begrip moeten hebben van hoe events, event dispatchers en gebeurtenislisteners werken.
Omdat het AS3-eventraamwerk enorm is, zullen we kijken naar alle verschillende dingen die het eventraamwerk vormen. We leren over het volgende:
Ik denk echt dat je het moeilijk zou hebben om het gebeurteniskader te begrijpen als we meteen in het technische jargon stappen, dus ik zal eerst een situatie uit het echte leven beschrijven. De hele situatie is een metafoor voor het evenementenkader. Oké, dus hier gaan we:
Ik ben een fervent lezer van Computer Arts en ik wacht elke dag op het nieuwe nummer. Wanneer ik het probleem ontvang, begin ik het te lezen.
Oké, we hebben verschillende dingen aan de hand:
Ik heb verschillende dingen genoemd:
Een gebeurtenis is een object dat een occurrence beschrijft, in Stap 1 het evenement is de aankomst van een nieuw nummer.
Meestal ziet u een gebeurtenis die is geschreven in een soortgelijke structuur:
MouseEvent.CLICK
Dit codefragment bestaat uit twee dingen:
Het gebeurtenistype is eigenlijk een statische constante reeks. Het klinkt misschien raar, maar een evenement is niets anders dan een tekenreeks. Probeer dit fragment uit te voeren.
trace (MouseEvent.MOUSE_MOVE);
Je krijgt als uitvoer mouseMove. We hebben zojuist de constante MOUSE_MOVE getraceerd, die zich in de klasse MouseEvent bevindt. Een evenement is een tekenreeks! Maar deze reeks vertegenwoordigt het voorkomen van (in dit voorbeeld) de beweging van de muis.
Een evenement gebeurt altijd ergens. Waar de gebeurtenis plaatsvindt is waar hij wordt ontslagen (verzonden). De wortels van dispatching-evenementen bevinden zich in de klasse EventDispatcher. Realiseer je dat waar de gebeurtenis wordt verzonden, is waar het gebeurt. Dus indien filmclip A verzendt een gebeurtenis en vervolgens een gebeurtenislistener (gebeurtenislisteners worden uitgelegd in stap 5) toegevoegd aan filmclip B zou deze gebeurtenis niet ontvangen.
Om dingen gemakkelijk te maken, hebben alle weergaveobjecten de ingebouwde functie dispatchEvent (event: Event), net als veel andere klassen.
var myMC: MovieClip = new MovieClip (); myMC.dispatchEvent (nieuwe gebeurtenis (MouseEvent.CLICK));
Maar meestal verzendt u gebeurtenissen niet handmatig, meestal worden gebeurtenissen automatisch verzonden. Als ik bijvoorbeeld op filmclip A klik, wordt de gebeurtenis MouseEvent.CLICK automatisch verzonden.
Wanneer een bepaalde gebeurtenis plaatsvindt, willen wij, als Flash-ontwikkelaars, iets doen om op deze gebeurtenis te reageren. Gebeurtenislisteners zijn wat je nodig hebt. Gebeurtenislisteners hebben geen eigen klasse, nee ze zijn een beetje anders. Gebeurtenislisteners worden toegevoegd aan een object. Gebeurtenislisteners zijn objecten die naar een bepaalde gebeurtenis "luisteren". Wanneer deze gebeurtenis plaatsvindt, wordt een functie aangeroepen, a handler (functie).
Kijk naar de afbeelding hieronder, met de syntaxis achter de functie addEventListener (), die wordt gebruikt om een gebeurtenislistener toe te voegen:
Eigenlijk zijn dit niet alle parameters die de methode addEventListener accepteert, er zijn er nog drie die ik niet heb genoemd. Je zult ze bijna nooit gebruiken, vooral niet wanneer je eventlisteners bent gaan gebruiken. Laten we nog eens kijken naar de structuur van de methode addEventListener.
addEventListener (type: String, listener: Function, useCapture: Boolean = false, priority: int = 0, useWeakReference: Boolean = false): void
Laten we de laatste 3 parameters bespreken:
Het verwijderen van een gebeurtenislistener is net zo eenvoudig als het toevoegen ervan.
// dit voegt een gebeurtenislistener toe aan de fase stage.addEventListener (MouseEvent.CLICK, clickHandler); // hiermee wordt de gebeurtenislistener verwijderd die aan de stage stage is toegevoegd.removeEventListener (MouseEvent.CLICK, clickHandler);
Wanneer de gebeurtenis plaatsvindt waarnaar een gebeurtenislistener luistert, roept deze een functie aan. Deze functie wordt de handler of de luisteraar functie. Kijk naar de afbeelding hieronder, die de syntaxis van de handler laat zien:
Let op het argument in de handler, dit argument is verplicht. De listener-functie heeft slechts één argument en mag niet meer hebben. Dit evenement bevat informatie over het evenement, hier zullen we het over hebben stap 9.
Nu willen we dat myMC reageert op de verzonden gebeurtenis, dus we zullen een evenement toevoegen en daarna de handler-functie. Onze code zal er zo uitzien:
// create our myMC movie clip var myMC: MovieClip = new MovieClip (); // laat myMC de gebeurtenis MouseEvent.CLICK myMC.dispatchEvent (nieuwe gebeurtenis (MouseEvent.CLICK)) verzenden; // voeg een gebeurtenislistener toe aan myMC, die naar de gebeurtenis MouseEvent.CLICK luistert, en clickHandler myMC.addEventListener (MouseEvent.CLICK, clickHandler) aanroept; // definieer de handler-functie clickHandler (event: Event) trace ("I heard the event MouseEvent.CLICK");
Test daarna je film (Windows: Ctrl + Enter, Mac: Cmd + Enter).
Heb je output gehad? Nee? Nou, ik ook niet. We zullen kijken naar wat er mis gaat in de volgende stap.
Dus wat gaat er mis? Nou ja, het kan zeker geen syntaxisfout zijn Im niets krijgen. Nee, dit is technisch gezien geen fout. Bekijk de code opnieuw, maar vergeet deze keer niet dat de code regel voor regel wordt uitgevoerd:
// create our myMC movie clip var myMC: MovieClip = new MovieClip (); // laat myMC de gebeurtenis MouseEvent.CLICK myMC.dispatchEvent (nieuwe gebeurtenis (MouseEvent.CLICK)) verzenden; // voeg een gebeurtenislistener toe aan myMC, die naar de gebeurtenis MouseEvent.CLICK luistert, en clickHandler myMC.addEventListener (MouseEvent.CLICK, clickHandler) aanroept; // definieer de handler-functie clickHandler (event: Event) trace ("I heard the event MouseEvent.CLICK");
Ik hoop dat je je hebt gerealiseerd wat er mis is gegaan: de gebeurtenis wordt verzonden voordat een gebeurtenislistener is toegevoegd aan myMC. Dus wanneer de gebeurtenislistener is toegevoegd, is het te laat, de gebeurtenis is gebeurd. Gelukkig is het eenvoudig op te lossen, verander gewoon de volgorde en voeg eerst de gebeurtenislistener toe en verzend daarna de gebeurtenis:
// create our myMC movie clip var myMC: MovieClip = new MovieClip (); // voeg een gebeurtenislistener toe aan myMC, die naar de gebeurtenis MouseEvent.CLICK luistert, en clickHandler myMC.addEventListener (MouseEvent.CLICK, clickHandler) aanroept; // laat myMC de gebeurtenis MouseEvent.CLICK myMC.dispatchEvent (nieuwe gebeurtenis (MouseEvent.CLICK)) verzenden; // definieer de handler-functie clickHandler (event: Event) trace ("I heard the event MouseEvent.CLICK");
Dus waarom hebben we dat allemaal gedaan? Welnu, je zult dit probleem waarschijnlijk tegenkomen en het kan een tijdje duren om te beseffen wat er aan de hand is. Het is beter om je het probleem te laten zien en je te leren hoe je het kunt oplossen.
Elke handler-functie heeft één argument; het gebeurtenisargument. Dit argument bevat gegevens over de gebeurtenis en de gebeurtenisverdeler. De parameter bevat eigenschappen die we zouden willen lezen. Hier is een lijst met enkele van de meest gebruikte:
Hiermee kunnen we dezelfde handler gebruiken voor verschillende soorten evenementen. Hoe? Welnu, we zullen dit in de volgende stap bespreken.
Oké, laten we eerst dit codefragment bekijken:
stage.addEventListener (MouseEvent.MOUSE_DOWN, downHandler); stage.addEventListener (MouseEvent.MOUSE_UP, upHandler); function downHandler (event: MouseEvent) trace ("Down"); function upHandler (event: MouseEvent) trace ("Up");
We gebruiken twee evenementen, namelijk MouseEvent.MOUSE_DOWN en MouseEvent.MOUSE_UP. De eerste gebeurtenis is de gebeurtenis wanneer de muis op de primaire muisknop drukt en deze vasthoudt naar beneden. Wanneer de persoon deze knop loslaat, gebeurt de gebeurtenis MouseEvent.MOUSE_UP. De muisknop gaat omhoog na het loslaten ervan.
Nu kunnen we in plaats van twee handlers gebruiken (namelijk downHandler en upHandler) slechts één handler. Verwijder de code die we hebben geschreven en typ het volgende:
stage.addEventListener (MouseEvent.MOUSE_DOWN, handler); stage.addEventListener (MouseEvent.MOUSE_UP, handler); function handler (event: MouseEvent) trace ("Er is iets gebeurd ...");
Okay, we hebben onze handler opgezet en het werkt, maar we willen dat onze handelaar iets specifieks doet, afhankelijk van welk evenement wordt doorgegeven aan de handler. Gelukkig kunnen we gebruiken Event.type. Laten we het gebruiken!
stage.addEventListener (MouseEvent.MOUSE_DOWN, handler); stage.addEventListener (MouseEvent.MOUSE_UP, handler); function handler (event: MouseEvent) if (event.type == "mouseDown") trace ("Down"); else trace ("Up");
Laten we nu eens aannemen dat er een klik gebeurt op een filmclip, laten we het noemen MCA. Het evenement wordt niet eenvoudig verzonden op mcA, nee, het evenement reist door de hele speler. Dit reizen wordt het gebeurtenisstroom, bedenk eens hoe het evenement door de speler stroomt.
Het evenement begint op het hoogste niveau, op de stadium, daarna gaat het door de ouders van MCA, totdat het evenement mcA bereikt. Daarna zal het evenement "terugbellen" van MCA, terug naar het podium.
Oké, cool, maar waar kan ik dit voor gebruiken? Omdat we nu weten dat een evenement door alle ouders van de coördinator gaat, kunnen we gewoon gebruiken een gebeurtenislistener, om de gebeurtenissen van meer dan één object te volgen.
Oké, laten we een paar filmclips in elkaar maken. U kunt dit zelf doen of gewoon het bestand step-11.fla gebruiken.
We maken 3 filmclips en we geven ze de instantienamen redMC, blueMC en greenMC. Plaats daarna deze allemaal in een grotere filmclip, genaamd houder.
Laten we nu beginnen met het schrijven van code. Ik heb al een laag met de naam gemaakt acties, dus schrijf je code op die laag. Laten we eerst een gebeurtenislistener toevoegen houder, luisteren naar het evenement MouseEvent.CLICK, met de handler genaamd clickHandler.
container.addEventListener (MouseEvent.CLICK, clickHandler); function clickHandler (event: MouseEvent) // function body
We willen weten op welke knop wordt geklikt, dus waarom hebben we een gebeurtenislistener toegevoegd aan de container? Nou, kijk naar de foto hieronder:
Zoals je ziet, wordt de gebeurtenis verzonden met redMC, maar dit zal wel gebeuren bubbel terug naar container. Vervolgens zal de gebeurtenislistener toegevoegd aan de container de gebeurtenis horen en de listenerfunctie clickHandler noemen. Hetzelfde gebeurt met blueMC en greenMC.
Nu gaan we event.target gebruiken, omdat event.target de gebeurtenisverdeler is en de gebeurtenisverdeler redMC is. Dus hoe kunnen we event.target gebruiken? We kunnen controleren op event.target.name, waarmee de naam van het exemplaar als een tekenreeks wordt geretourneerd. Dus we kunnen gewoon normaal gebruiken als statements:
container.addEventListener (MouseEvent.CLICK, clickHandler); function clickHandler (event: MouseEvent) if (event.target.name == "redMC") trace ("Red"); if (event.target.name == "blueMC") trace ("Blue"); if (event.target.name == "greenMC") trace ("Groen");
Nu hebt u een goed begrip van het gebeurtenisraamwerk, maar om iets te bereiken, is het belangrijkste om te weten welke gebeurtenis u wilt gebruiken. Een goede plek om te controleren welke gebeurtenissen bestaan, is de Naslaggids voor ActionScript 3.0 voor taal en componenten. Klik gewoon op een evenement met klasse, zoals MouseEvent, en bekijk wat elke gebeurtenis is.
Deze gebeurtenis vindt plaats wanneer de gebruiker de muis beweegt. Als je een gebeurtenislistener toevoegt terwijl je naar deze gebeurtenis luistert, bijvoorbeeld op een filmclip met de naam myMC, weet je wanneer de muis over myMC beweegt.
myMC.addEventListener (MouseEvent.MOUSE_MOVE, mouseMoveHandler); function mouseMoveHandler (event: MouseEvent) trace ("Uw muis beweegt over myMC");
Deze gebeurtenis vindt plaats wanneer de gebruiker zich verplaatst (zweeftekens). Deze gebeurtenis treedt alleen op wanneer de gebruiker de cursor ergens anders over het object verplaatst. De muis over het object bewegen is dan niet langer de gebeurtenis MouseEvent.MOUSE_OVER, maar de gebeurtenis MouseEvent.MOUSE_MOVE.
myMC.addEventListener (MouseEvent.MOUSE_OVER, overHandler); function overHandler (event: MouseEvent) trace ("U hebt zojuist de muis op myMC verplaatst");
Deze gebeurtenis is precies het tegenovergestelde van MouseEvent.MOUSE_OVER. Dit is wanneer de cursor van de gebruiker van het object af beweegt, of zoals zij (de jongens die AS3 hebben gemaakt) het uit het object noemen.
myMC.addEventListener (MouseEvent.MOUSE_OUT, outHandler); function outHandler (event: MouseEvent) trace ("Je hebt net de muis uit myMC gehaald");
Deze gebeurtenis treedt op wanneer de gebruiker de primaire muis ingedrukt houdt terwijl deze ingedrukt wordt gehouden.
myMC.addEventListener (MouseEvent.MOUSE_DOWN, downHandler); function downHandler (event: MouseEvent) trace ("De primaire muisknop is ingedrukt op myMC");
Deze gebeurtenis is precies het tegenovergestelde van MouseEvent.MOUSE_DOWN. Wanneer de gebruiker de primaire muisknop loslaat, gebeurt de gebeurtenis MouseEvent.MOUSE_UP.
myMC.addEventListener (MouseEvent.MOUSE_UP, upHandler); function upHandler (event: MouseEvent) trace ("De primaire muisknop is losgelaten terwijl deze over myMC zweefde");
De naam maakt het al vrij duidelijk wanneer deze gebeurtenis plaatsvindt. Deze gebeurtenis vindt plaats wanneer de gebruiker klikt (met de primaire muisknop).
myMC.addEventListener (MouseEvent.CLICK, clickHandler); function clickHandler (event: MouseEvent) trace ("U hebt zojuist op myMC geklikt");
Nou, deze gebeurtenis doet zich voor wanneer de gebruiker twee keer klikt (met de primaire muisknop). Houd er rekening mee dat wanneer MouseEvent.DOUBLE_CLICK plaatsvindt, MouseEvent.CLICK zich nu voor de tweede keer voordoet.
myMC.addEventListener (MouseEvent.DOUBLE_CLICK, doubleClickHandler); function doubleClickHandler (event: MouseEvent) trace ("U dubbelklikt gewoon op myMC");
Als je nu je film test en dubbelklikt, gebeurt er niets. Waarom? Nou, standaard hebben filmclips (en bijna alle weergaveobjecten) de eigenschap doubleClickEnabled ingesteld op false. Dus MouseEvent.DOUBLE_CLICK wordt niet verzonden. Zet het gewoon op true en alles zal goed werken.
myMC.addEventListener (MouseEvent.DOUBLE_CLICK, doubleClickHandler); function doubleClickHandler (event: MouseEvent) trace ("U dubbelklikt gewoon op myMC"); myMC.doubleClickEnabled = true;
Deze gebeurtenis vindt elke keer plaats wanneer het object een nieuw frame binnengaat (ja, dat klinkt een beetje raar). In principe komt deze gebeurtenis voor in de snelheid van de framesnelheid. Dat betekent dat als uw film een framerate van 30 fps heeft, het evenement 30 keer per seconde wordt genoemd. Waar zou je dit evenement voor gebruiken? Je kunt dit evenement gebruiken om dingen geleidelijk te laten gebeuren. U kunt bijvoorbeeld de x-coördinaat van een object met 5 verhogen, aan de snelheid van de framesnelheid.
myMC.addEventListener (Event.ENTER_FRAME, enterFrameHandler); function enterFrameHandler (event: Event) myMC.x + = 5;
Deze gebeurtenis vindt plaats wanneer het object voltooit wat het ook aan het doen was. Meestal gebruik je het voor dingen die iets moeten laden, of voor dingen die een of andere vorm van media afspelen. Een URLLoader laadt een URLRequest, nadat de URLLoader het laden heeft voltooid, laden we deze gegevens in een andere lader en voegen daarna de lader aan het podium toe.
var myURLRequest: URLRequest = new URLRequest ("http://farm3.static.flickr.com/2382/1616598266_bafebf0086_o.jpg"); var myURLLoader: URLLoader = new URLLoader (myURLRequest); myURLLoader.dataFormat = URLLoaderDataFormat.BINARY; myURLLoader.addEventListener (Event.COMPLETE, completeHandler); function completeHandler (event: Event) var loader: Loader = new Loader (); Loader.loadBytes (myURLLoader.data); addChild (loader);
Deze gebeurtenis treedt op wanneer de flash-speler of de pagina waar de flitser zich bevindt, wordt verkleind. U kunt deze gebeurtenis gebruiken om objecten opnieuw te positioneren nadat het wijzigen van de grootte is gebeurd.
stage.addEventListener (Event.RESIZE, resizeHandler); functie resizeHandler (event: Event) trace ("De dimensies van de fase zijn" + stage.stageWidth + "x" + stage.stageHeight);
Deze gebeurtenis vindt plaats wanneer ieder toets wordt ingedrukt op het toetsenbord.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); functietoetsDownHandler (event: KeyboardEvent) trace ("U hebt zojuist op een toets gedrukt!");
Deze gebeurtenis is precies het tegenovergestelde van KeyboardEvent.KEY_DOWN, deze gebeurtenis vindt plaats wanneer ieder toets wordt losgelaten (de toets gaat omhoog).
stage.addEventListener (KeyboardEvent.KEY_UP, keyUpHandler); function keyUpHandler (event: KeyboardEvent) trace ("U heeft zojuist een sleutel vrijgegeven");
Het is natuurlijk tamelijk nutteloos om hierop te reageren elke sleutel (behalve een screensaver), dus we zouden informatie moeten ophalen over welke toets is ingedrukt. Gelukkig zijn sommige toetsen ingebouwd in de klasse KeyboardEvent, dit zijn booleans en zijn ingesteld op true wanneer het wordt ingedrukt. Deze ingebouwde booleans zijn:
Dus nu kunnen we dit gebruiken om meer specifiek te zijn welke sleutel moet worden ingedrukt voordat we iets doen.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); functietoetsDownHandler (event: KeyboardEvent) if (event.shiftKey) trace ("U hebt zojuist op de Shift-toets gedrukt");
U vraagt zich misschien af, oke, hoe zit het met alle andere sleutels? Wel, er is iets dat de naam heeft sleutelcode. Elke toets heeft een bepaald aantal; een sleutelcode. We kunnen de sleutelcode van de sleutel controleren die de gebeurtenis heeft geactiveerd. Dit gebeurt met event.keyCode, die een geheel getal retourneert. Klik hier voor een lijst met sleutelcodes. Hoewel het voor javascript is, zijn de sleutelcodes hetzelfde.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); function keyDownHandler (event: KeyboardEvent) if (event.keyCode == 65) trace ("U hebt zojuist op de A-toets gedrukt");
Nu is het eenvoudiger om de sleutelcodes op te slaan in een variabele (of als je hardcore bent, in een klas) en gebruik je die variabele in plaats van de sleutelcode.
var A: uint = 65; stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); function keyDownHandler (event: KeyboardEvent) if (event.keyCode == A) trace ("U hebt zojuist op de A-toets gedrukt");
Met sleutelcodes kun je best veel gedaan krijgen, maar soms is het niet wat je nodig hebt. Bijvoorbeeld, dezelfde sleutel wordt gebruikt voor de karakters een en EEN. Maar we willen nog steeds een onderscheid maken tussen deze twee. Welnu, de gebeurtenis bevat de tekencode van de gebeurtenisverzender.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); function keyDownHandler (event: KeyboardEvent) trace (event.charCode);
Oké, dit werkt, maar moeten we dan deze karaktercodes onthouden? Nee. Gelukkig kunnen we de functie charCodeAt () gebruiken, waarmee de tekencode van een teken (in een tekenreeks) wordt geretourneerd. charCodeAt () neemt standaard het eerste teken uit de reeks. charCodeAt (0) is het eerste teken, charCodeAt (1) het tweede, enzovoort.
stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); function keyDownHandler (event: KeyboardEvent) if (event.charCode == String ("a"). charCodeAt ()) trace ("U hebt zojuist op de kleine toets gedrukt");
Probeer nu het volgende in te typen:
myMC.addEventListener (KeyboardEvent.KEY_DOWN, keyDownHandler); function keyDownHandler (event: KeyboardEvent) trace ("U hebt net op een toets gedrukt, terwijl u op myMC hebt gefocust");
Probeer dit te testen, het zal niet werken! Waarom? Als myMC een filmclip is, accepteert het geen toetsenbordinvoer, dus worden toetsenbordgebeurtenissen niet verzonden in filmclips. Als u wilt dat myMC antwoordt, voegt u de gebeurtenislistener toe aan het podium en maakt u myMC iets. Probeer myMC te veranderen van een filmclip in een dynamisch tekstveld, dan zal het werken.
Hoe zit het met twee dynamische tekstvelden? Als de gebruiker typt, verzenden beide tekstvelden een gebeurtenis? Nee, alleen degene die u invoert. Dit wordt genoemd focus. Toetsenbordevents worden verzonden door het object met focus. Het podium is het enige object dat nog steeds focus heeft, terwijl een ander object ook focus heeft.
Dit evenement is speciaal gebouwd voor timers. Het wordt verzonden met een timer, die net de vertragingstijd heeft bereikt. Dit betekent dat je deze gebeurtenis kunt gebruiken om heel precies iets te doen, met vaste tijdsintervallen.
var myTimer: Timer = new Timer (1000, 5); myTimer.start (); myTimer.addEventListener (TimerEvent.TIMER, timerHandler); function timerHandler (event: TimerEvent) trace ("een seconde later ...");
Alle timers hebben een optionele tweede parameter. Met deze parameter wordt het aantal herhalingen van de timer ingesteld. Dit betekent dat wanneer de timer de vertragingstijd bereikt, deze opnieuw zal beginnen. Als de timer zo vaak is herhaald als de herhalingsteller, wordt de gebeurtenis TimerEvent.TIMER_COMPLETE verzonden.
var myTimer: Timer = new Timer (1000, 5); myTimer.start (); myTimer.addEventListener (TimerEvent.TIMER_COMPLETE, timerHandler); function timerHandler (event: TimerEvent) trace ("De timer heeft 5 keer herhaald");
Dat was het! Ik hoop dat u nu een goed begrip hebt van het gebeurteniskader van ActionScript 3.0. Realiseer je dat de besproken gebeurtenissen niet alle gebeurtenissen zijn die er zijn, ik besprak alleen degene die ik vaak gebruik. Vergeet niet om altijd de taal- en componentenreferentie te raadplegen, het kan u veel helpen! Het was een genoegen om voor jullie te schrijven!