-
[AS3] Question about using custom events in games
Is it faster to have an object listen for a custom event rather than, let's say, having the same object check for some variable to change every time it enters a frame?
For example, if certain enemies only target you if you are jumping, would it be better to dispatch a custom event whenever you jump, or have the enemies check your location every frame?
If using a custom event is the right way of doing it, could someone please give me an incredibly simple example of how to set this up in code? I'm trying to figure out how to use custom events, but all the examples I find are for crappy applications, so I'm having a little trouble wrapping my head around this stuff for the first time.
-
Custom User Title
Originally Posted by Sub Tank
Is it faster to have an object listen for a custom event rather than, let's say, having the same object check for some variable to change every time it enters a frame?
Yes
could someone please give me an incredibly simple example of how to set this up in code?
The basic idea its simple, give your object one array of functions, those functions will be the event listeners, so you can add or remove them from that array whenever you want.When you want to dispatch loop on all of them giving your event object as paramenter.
Or if you want, you can make the listeners as objects,thats how it used to be in as2, so for example if one enemie should wait for hero jump he gotta have the function 'onHeroJump' and the hero must have one array of objects.Those objects are the listeners that have that function onHeroJump.When its time to dispatch the hero loops on that array firing the 'onHeroJump' function on each enemie
I like the second way more, but sometimes it makes more sense to use the first one.Both are faster than if you use a class that extends IEventDispatcher.
-
Senior Member
Originally Posted by Sub Tank
If using a custom event is the right way of doing it, could someone please give me an incredibly simple example of how to set this up in code? I'm trying to figure out how to use custom events, but all the examples I find are for crappy applications, so I'm having a little trouble wrapping my head around this stuff for the first time.
Here is some test I wrote about a year ago to understand how to use custom events in AS 3.0
The code was written for three classes A, B, and C. Where C class creates two instances of A and B classes and we want to notify B class that some event occurred in C class.
Here is a code for A class:
Code:
/**
* Example of a class that can fire custom events
* @author Igor Vasiliev a.k.a. The Helmsman
* @version 0.1
*/
package {
// import routines
import flash.events.IEventDispatcher;
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.utils.*;
public class AClass implements IEventDispatcher {
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// public properties
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
public static const ON_ACLASS_EVENT:String = "onAClassEvent";
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// private properties
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
private var intervalDuration:Number = 1000;
private var dispatcher:EventDispatcher;
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// public methods
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
/**
* Class constuctor
*/
public function AClass() {
trace("AClass constructor");
dispatcher = new EventDispatcher(this);
var intervalId:uint = setInterval(onTimeOut, intervalDuration, intervalId);
}
/**
* Execution of some custom event on timeout
* @param intervalId - reference to interval id that must be cleared in the end
*/
public function onTimeOut(intervalId:uint):void {
trace("AClass> classEvent");
// clear interval after execution to be sure that function called only once
clearInterval(intervalId);
// fires custom event
dispatchEvent(new Event(AClass.ON_ACLASS_EVENT));
}
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// methods corresponds to IEventDispatcher interface
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
/**
* Registers an event listener object with an EventDispatcher object so that the
* listener receives notification of an event.
* @param type
* @param listener
* @param useCapture
* @param priority
* @param useWeakReference
*/
public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
dispatcher.addEventListener(type, listener, useCapture, priority);
}
/**
* Dispatches an event into the event flow.
* @param evt
* @return
*/
public function dispatchEvent(evt:Event):Boolean {
return dispatcher.dispatchEvent(evt);
}
/**
* Checks whether the EventDispatcher object has any listeners registered for a
* specific type of event. This allows you to determine where an EventDispatcher
* object has altered handling of an event type in the event flow hierarchy.
* @param type
* @return
*/
public function hasEventListener(type:String):Boolean {
return dispatcher.hasEventListener(type);
}
/**
* Removes a listener from the EventDispatcher object. If there is no matching
* listener registered with the EventDispatcher object, a call to this method has
* no effect.
* @param type
* @param listener
* @param useCapture
*/
public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
dispatcher.removeEventListener(type, listener, useCapture);
}
/**
* Checks whether an event listener is registered with this EventDispatcher object
* or any of its ancestors for the specified event type. This method returns true
* if an event listener is triggered during any phase of the event flow when an
* event of the specified type is dispatched to this EventDispatcher object or any
* of its descendants.
* @param type
* @return
*/
public function willTrigger(type:String):Boolean {
return dispatcher.willTrigger(type);
}
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// private methods
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
}
}
Same for a B class:
Code:
/**
* Example of a class that can receive custom events
* @author Igor Vasiliev a.k.a. The Helmsman
* @version 0.1
*/
package {
public class BClass {
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// public properties
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// private properties
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// public methods
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
/**
* Class constructor
*/
public function BClass() {
trace("BClass constructor");
}
/**
* Callback - handles event fired by another class
* @param eventObj
*/
public function onAClassEvent(eventObj:Object):void {
trace("BClass> onAClassEvent");
trace(eventObj.target);
trace(eventObj.type);
}
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// private methods
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
}
}
And finally code for C class:
Code:
/**
* Example of a class that can register one class to receive events from another class
* @author Igor Vasiliev a.k.a. The Helmsman
* @version 0.1
*/
package {
public class CClass {
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// public properties
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// private properties
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
private var myA:AClass;
private var myB:BClass;
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// public methods
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
/**
* Class constructor
*/
public function CClass() {
trace("CClass constructor");
myA = new AClass(); // create new instance of A class
myB = new BClass(); // create new instance of B class
// register class B to receive custom event from class A
myA.addEventListener(AClass.ON_ACLASS_EVENT, myB.onAClassEvent);
}
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
// private methods
// -=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
}
}
-
Since both your hero and your enemy will mostly likely extend DisplayObject (sprite, moveiclip, etc) you can just have each dispatch events as needed.
So first you would create your hero class. Obviously there will be alot more code than this, but these methods should be in there for when the hero jumps and when he lands.
Code:
package
{
import flash.display.Sprite;
public class Hero extends Sprite
{
public function Hero()
{
}
public function jump():void
{
//we use the second parameter true so that the event will
//will bubble up to it's parent display objects
dispatchEvent(new Event("heroJump", true));
}
private function endJump():void
{
//we use the second parameter true so that the event will
//will bubble up to it's parent display objects
dispatchEvent(new Event("heroLand", true))
}
}
}
Then we create the enemy class
Code:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Enemy extends Sprite
{
public function Enemy(hero:Hero)
{
hero.addEventListener("heroJump", onHeroJump);
hero.addEventListener("heroLand", onHeroLand);
}
private function onHeroJump(e:Event):void
{
//start targetting hero
}
private function onHeroLand(e:Event):void
{
//stop targetting hero
}
}
}
It is important to note here that we pass in a reference of the hero to the Enemy class. This not an ideal solution, you should have some sort of data model so the enemy can just ask for the reference instead of passing it in, but this works for the example here.
In this example there is no need to loop through an array of bad guys to tell them that the hero jumped. In this case the hero just dispatches an event and the enemies who care to know when he jumps are setup to listen.
Hope that helps.
The code should be pretty self explanatory, but let me know if you have more questions.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|