A Flash Developer Resource Site

Results 1 to 4 of 4

Thread: [AS3] Question about using custom events in games

  1. #1
    Member
    Join Date
    Apr 2006
    Posts
    37

    [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.

  2. #2
    Custom User Title Incrue's Avatar
    Join Date
    Feb 2004
    Posts
    974
    Quote 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.

  3. #3
    Senior Member The Helmsman's Avatar
    Join Date
    Aug 2005
    Location
    _root
    Posts
    450
    Quote 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
    		//	-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-
    	}
    }

  4. #4
    Junior Member
    Join Date
    Nov 2008
    Posts
    1
    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
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center