Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

[web] Adding KeyEvent to Singleton ActionScript 3

Started by aleisterbukowski Mar 10, 2009 at 2:42 AM 0 replies 2.2k views
Original Post
aleisterbukowski
aleisterbukowski
Hi, I'm trying to add a key event to my singleton object management class that I have, and with what I have and the test I have run I have not been successful. Here I have a canvas called myCanvas that adds a keyboard event listener, and checks for the function keyPressed.

myCanvas.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);

Now I have an entity manager class that manages all objects. A gameObject class, which is the abstract class that all of my objects extend from/to to inherit the gameObject functionality. Here is GameEntity (the resource management class of all game objects)

package
{
	import flash.display.*;
	import flash.events.KeyboardEvent;
	
	import mx.collections.*;
	import mx.core.*;
	
	public class EntityManager 
	{
		// double buffer
		public var backBuffer:BitmapData;
		public var clearColor:uint = 0x333333;
		protected static var instance:EntityManager = null;
		protected var lastFrame:Date;
		protected var gameObjects:ArrayCollection = new ArrayCollection();
		protected var newGameObjects:ArrayCollection = new ArrayCollection();
		protected var removedGameObjects:ArrayCollection = new ArrayCollection();
		protected var nemousArray:Array = new Array();
		protected var player:Player;
		protected var nemous:Nemous;
		
		//if we don't exist create ourselve's
		static public function get Instance():EntityManager
		{
			if ( instance == null )
			instance = new EntityManager();
			return instance;
		}
		
		//constructor of EntityManager
		public function EntityManager()
		{
			if ( instance != null )
				throw new Error( "Only one Singleton instance should be instantiated" ); 
			
			//create the back buffer where we will draw all game entities on the screen	
			backBuffer = new BitmapData(Application.application.width, Application.application.height, false);
		}
		
		//start up "instataniate all game entities in the game. that needs to be started when loading the game.
		public function startup():void
		{
			lastFrame = new Date();
			player = new Player();
			nemous = new Nemous();
			player.startupPlayer();
			nemous.startupNemous();
			
		}
		
		//shutdown all entities
		public function shutdown():void
		{
			shutdownAll();
		}
		
		//update
		public function enterFrame():void
		{
			// Calculate the time since the last frame
			var thisFrame:Date = new Date();
			var seconds:Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;
	    	lastFrame = thisFrame;
	    	
	    	removeDeletedGameObjects();
	    	insertNewGameObjects();
	    	
	    	// now allow objects to update themselves
			for each (var gameObject:GameObject in gameObjects)
			{
				if (gameObject.inuse) 
					gameObject.enterFrame(seconds);
			}
	    	
	    	drawObjects();
		}
		
		//get keys 
		public function keyPressed(evt:KeyboardEvent):void
		{
			
		}
		
		//draw all objects onto the back buffer "double buffer"
		protected function drawObjects():void
		{
			backBuffer.fillRect(backBuffer.rect, clearColor);
			
			// draw the objects
			for each (var gameObject:GameObject in gameObjects)
			{
				if (gameObject.inuse) 
					gameObject.copyToBackBuffer(backBuffer);
			}
		}
		
		//add specific game object "Entity" to the array
		public function addGameObject(gameObject:GameObject):void
		{
			newGameObjects.addItem(gameObject);
		}
		
		//remove specific game object "Entity" to the array
		public function removeGameObject(gameObject:GameObject):void
		{
			removedGameObjects.addItem(gameObject);
		}
		
		//dispose of all objects by moving them to the remove object array, so we only shut them down once
		protected function shutdownAll():void
		{
			// don't dispose objects twice
			for each (var gameObject:GameObject in gameObjects)
			{
				var found:Boolean = false;
				for each (var removedObject:GameObject in removedGameObjects)
				{
					if (removedObject == gameObject)
					{
						found = true;
						break;
					}
				}
				
				if (!found)
					gameObject.shutdown();
			}
		}
		
		//inset entities "new gameObjects into the array for use
		protected function insertNewGameObjects():void
		{
			for each (var gameObject:GameObject in newGameObjects)
			{
				for (var i:int = 0; i < gameObjects.length; ++i)
				{
					if (gameObjects.getItemAt(i).zOrder > gameObject.zOrder ||
						gameObjects.getItemAt(i).zOrder == -1)
						break;
				}
				gameObjects.addItemAt(gameObject, i);
			}
			newGameObjects.removeAll();
		}
		
		//remove all game objects "Entites" in the array that need to be deleted from the removedGameObjects array
		protected function removeDeletedGameObjects():void
		{
			// insert the object acording to it's z position
			for each (var removedObject:GameObject in removedGameObjects)
			{
				var i:int = 0;
				for (i = 0; i < gameObjects.length; ++i)
				{
					if (gameObjects.getItemAt(i) == removedObject)
					{
						gameObjects.removeItemAt(i);
						break;
					}
				}	
			}
			
			removedGameObjects.removeAll();
		}

	}
}

Specifically take a look at the KeyPressed that is called

//get keys 
		public function keyPressed(evt:KeyboardEvent):void
		{
			
		}

in my gameObject I have the following as well, which can be over written by the classes that are extended from gameObject

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	/*
		The base class for all objects in the game.
	*/
	public class GameObject
	{
		// object position
		public var position:Point = new Point(0, 0);
		// higher zOrder objects are rendered on top of lower ones
		public var zOrder:int = 0;
		// the bitmap data to display	
		public var graphics:GraphicsResource = null;
		// true if the object is active in the game
		public var inuse:Boolean = false;
		
		public function GameObject()
		{
			
		}
		
		public function startupGameObject(graphics:GraphicsResource, position:Point, z:int = 0):void
		{
			if (!inuse)
			{
				this.graphics = graphics;
				this.zOrder = z;
				this.position = position.clone();
				this.inuse = true;
				
				EntityManager.Instance.addGameObject(this);
				//GameObjectManager.Instance.addGameObject(this);
			}
		}
		
		//change image if needed
		public function setGraphic(graphics:GraphicsResource):void
		{
			this.graphics = graphics;
		}
		
		public function shutdown():void
		{
			if (inuse)
			{				
				graphics = null;
				inuse = false;
				
				EntityManager.Instance.removeGameObject(this);
				//GameObjectManager.Instance.removeGameObject(this);
			}
		}
		
		//copy image to the back buffer.
		public function copyToBackBuffer(db:BitmapData):void
		{
			db.copyPixels(graphics.bitmap, graphics.bitmap.rect, position, graphics.bitmapAlpha, new Point(0, 0), true);
		}
		
		//update frames
		public function enterFrame(dt:Number):void
		{
		
		}
		
		//get events
		public function keyPressed(evt:KeyboardEvent):void
		{
			
		}

	}
}

Take a close look at the keypressed event again

//get events
		public function keyPressed(evt:KeyboardEvent):void
		{
			
		}

Now finally the player class, which is the class that should check for events from the player, and call functions accordingly as they keys are pressed

package
{
	import flash.events.KeyboardEvent;
	import flash.geom.Point;
	
	import mx.controls.Text;
	import mx.core.*;
	
	public class Player extends GameObject
	{
		protected static const speed:Number = 10;
		protected var direction:Point = new Point(5, 5);
		protected var score:Text = new Text();
		
		//constuctor of Player
		public function Player()
		{
			super();
		}
		
		//start the player
		public function startupPlayer():void
		{
			super.startupGameObject(ResourceManager.RobotRightGraphics, new Point(2.0, 2.0));
			score.text = "Score: ";
		}
		
		//shutdown the player
		override public function shutdown():void
		{
			super.shutdown();
		} 
		
		//change image if needed
		override public function setGraphic(graphics:GraphicsResource):void
		{
			this.graphics = graphics;
		}
		
		//update frame for player
		override public function enterFrame(dt:Number):void
		{
			super.enterFrame(dt);
			
			position.x += Motion2D.CalculateVelocity(direction.x*speed, dt);
			position.y += Motion2D.CalculateVelocity(direction.y*speed, dt);
			//position.x += direction.x * speed * dt;
			//position.y += direction.y * speed * dt;
			
			if (position.x >= Application.application.width - graphics.bitmap.width)
				direction.x = -1;
			else if (position.x <= 0)
				direction.x = 1;
				
			if (position.y >= Application.application.height - graphics.bitmap.height)
				direction.y = -1;
			else if (position.y <= 0)
				direction.y = 1;
			
			//change image depending on direction, which player is moving	
			if(direction.x == -1) this.setGraphic(ResourceManager.RobotLeftGraphics);
			else this.setGraphic(ResourceManager.RobotRightGraphics);
		}
		
		//get key events, so we can move the player
		override public function keyPressed(evt:KeyboardEvent):void
		{
			super.keyPressed(evt);
			trace("key = " + evt.keyCode);
			
		}
	}
}

Specifically look at the keyPressed event again


//get key events, so we can move the player
		override public function keyPressed(evt:KeyboardEvent):void
		{
			super.keyPressed(evt);
			trace("key = " + evt.keyCode);
			
		}

I'm calling the KeyPressed function correctly, and I'm sending it to gameObject correctly am I not? however, it's not working they way it should work obviousely right? I was wondering if anyone see's anything that I could have possibly forgotten to add to get this singleton keyevent working as it should. Also would it just be a better idea to make a separate singleton key event manager and add it to the child of mycanvas that is checking for events? [/source]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.