Using Event Driven Programming in games, when is it beneficial?
- by Arthur Wulf White
I am learning ActionScript 3 and I see the Event flow adheres to the W3C recommendations.
From what I learned events can only be captured by the dispatcher unless, the listener capturing the event is a DisplayObject on stage and a parent of the object firing the event. You can capture the events in the capture(before) or bubbling(after) phase depending on Listner and Event setup you use.
Does this system lend itself well for game programming?
When is this system useful?
Could you give an example of a case where using events is a lot better than going without them?
Are they somehow better for performance in games?
Please do not mention events you must use to get a game running, like Event.ENTER_FRAME
Or events that are required to get input from the user like, KeyboardEvent.KEY_DOWN and MouseEvent.CLICK.
I am asking if there is any use in firing events that have nothing to do with user input, frame rendering and the likes(that are necessary). I am referring to cases where objects are communicating.
Is this used to avoid storing a collection of objects that are on the stage?
Thanks
Here is some code I wrote as an example of event behavior in ActionScript 3, enjoy.
package regression
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.EventPhase;
/**
* ...
* @author ...
*/
public class Check_event_listening_1 extends Sprite
{
public const EVENT_DANCE : String = "dance";
public const EVENT_PLAY : String = "play";
public const EVENT_YELL : String = "yell";
private var baby : Shape = new Shape();
private var mom : Sprite = new Sprite();
private var stranger : EventDispatcher = new EventDispatcher();
public function Check_event_listening_1()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
trace("test begun");
addChild(mom);
mom.addChild(baby);
stage.addEventListener(EVENT_YELL, onEvent);
this.addEventListener(EVENT_YELL, onEvent);
mom.addEventListener(EVENT_YELL, onEvent);
baby.addEventListener(EVENT_YELL, onEvent);
stranger.addEventListener(EVENT_YELL, onEvent);
trace("\nTest1 - Stranger yells with no bubbling");
stranger.dispatchEvent(new Event(EVENT_YELL, false));
trace("\nTest2 - Stranger yells with bubbling");
stranger.dispatchEvent(new Event(EVENT_YELL, true));
stage.addEventListener(EVENT_PLAY, onEvent);
this.addEventListener(EVENT_PLAY, onEvent);
mom.addEventListener(EVENT_PLAY, onEvent);
baby.addEventListener(EVENT_PLAY, onEvent);
stranger.addEventListener(EVENT_PLAY, onEvent);
trace("\nTest3 - baby plays with no bubbling");
baby.dispatchEvent(new Event(EVENT_PLAY, false));
trace("\nTest4 - baby plays with bubbling");
baby.dispatchEvent(new Event(EVENT_PLAY, true));
trace("\nTest5 - baby plays with bubbling but is not a child of mom");
mom.removeChild(baby);
baby.dispatchEvent(new Event(EVENT_PLAY, true));
mom.addChild(baby);
stage.addEventListener(EVENT_DANCE, onEvent, true);
this.addEventListener(EVENT_DANCE, onEvent, true);
mom.addEventListener(EVENT_DANCE, onEvent, true);
baby.addEventListener(EVENT_DANCE, onEvent);
trace("\nTest6 - Mom dances without bubbling - everyone is listening during capture phase(not target and bubble phase)");
mom.dispatchEvent(new Event(EVENT_DANCE, false));
trace("\nTest7 - Mom dances with bubbling - everyone is listening during capture phase(not target and bubble phase)");
mom.dispatchEvent(new Event(EVENT_DANCE, true));
}
private function onEvent(e : Event):void
{
trace("Event was captured");
trace("\nTYPE : ", e.type, "\nTARGET : ", objToName(e.target), "\nCURRENT TARGET : ", objToName(e.currentTarget), "\nPHASE : ", phaseToString(e.eventPhase));
}
private function phaseToString(phase : int):String
{
switch(phase)
{
case EventPhase.AT_TARGET :
return "TARGET";
case EventPhase.BUBBLING_PHASE :
return "BUBBLING";
case EventPhase.CAPTURING_PHASE :
return "CAPTURE";
default:
return "UNKNOWN";
}
}
private function objToName(obj : Object):String
{
if (obj == stage) return "STAGE";
else if (obj == this) return "MAIN";
else if (obj == mom) return "Mom";
else if (obj == baby) return "Baby";
else if (obj == stranger) return "Stranger";
else return "Unknown"
}
}
}
/*result :
test begun
Test1 - Stranger yells with no bubbling
Event was captured
TYPE : yell
TARGET : Stranger
CURRENT TARGET : Stranger
PHASE : TARGET
Test2 - Stranger yells with bubbling
Event was captured
TYPE : yell
TARGET : Stranger
CURRENT TARGET : Stranger
PHASE : TARGET
Test3 - baby plays with no bubbling
Event was captured
TYPE : play
TARGET : Baby
CURRENT TARGET : Baby
PHASE : TARGET
Test4 - baby plays with bubbling
Event was captured
TYPE : play
TARGET : Baby
CURRENT TARGET : Baby
PHASE : TARGET
Event was captured
TYPE : play
TARGET : Baby
CURRENT TARGET : Mom
PHASE : BUBBLING
Event was captured
TYPE : play
TARGET : Baby
CURRENT TARGET : MAIN
PHASE : BUBBLING
Event was captured
TYPE : play
TARGET : Baby
CURRENT TARGET : STAGE
PHASE : BUBBLING
Test5 - baby plays with bubbling but is not a child of mom
Event was captured
TYPE : play
TARGET : Baby
CURRENT TARGET : Baby
PHASE : TARGET
Test6 - Mom dances without bubbling - everyone is listening during capture phase(not target and bubble phase)
Event was captured
TYPE : dance
TARGET : Mom
CURRENT TARGET : STAGE
PHASE : CAPTURE
Event was captured
TYPE : dance
TARGET : Mom
CURRENT TARGET : MAIN
PHASE : CAPTURE
Test7 - Mom dances with bubbling - everyone is listening during capture phase(not target and bubble phase)
Event was captured
TYPE : dance
TARGET : Mom
CURRENT TARGET : STAGE
PHASE : CAPTURE
Event was captured
TYPE : dance
TARGET : Mom
CURRENT TARGET : MAIN
PHASE : CAPTURE
*/