(function(window){	function Aliens(image, point)	{		this.image			= image;		this.offsetPosition	= point;		this.position		= point.clone();		this.initialize();	}	Aliens.prototype = new Container();		Aliens.prototype.image			= null;		Aliens.prototype.spriteSheet	= null;		Aliens.prototype.bitmapSequence	= null;		Aliens.prototype.boundry		= null;				// Rectangle "within the Aliens can move"		Aliens.prototype.position		= new Point(0,0);	// Point respresenting the x and y postion of this (the Aliens). Used as offset when moving/position each Alien		Aliens.prototype.offsetPosition	= new Point(0,0);	// Point respresenting the x and y postion of this (the Aliens). Used to reset the position when resetting the game		Aliens.prototype.width			= 0;				// The width of this (the aliens). Updated on every tick		Aliens.prototype.height			= 0;				// The height of this (the aliens). Updated on every tick		Aliens.prototype.speed			= 2;				// The speed of which the aliens move (x and y increments)		Aliens.prototype.enabled		= false;		Aliens.prototype.alienWidth		= 0;		Aliens.prototype.alienHeight	= 0;		Aliens.prototype.aliens			= [];	// Array to hold each Alien instance		Aliens.prototype.direction		= null;	// Identifies the current direction the aliens move		Aliens.prototype.totalAliens	= 0;	// Total amount of aliens (left)		// Signals		Aliens.prototype.alienKilled	= new signals.Signal();		Aliens.prototype.allKilled		= new signals.Signal();		Aliens.prototype.reachedBottom	= new signals.Signal();		Aliens.prototype.shotFired		= new signals.Signal();		// Const		Aliens.DIR_LEFT		= 'Aliens.DIR_LEFT';		Aliens.DIR_RIGHT	= 'Aliens.DIR_RIGHT';		Aliens.DIR_NONE		= 'Aliens.DIR_NONE';		// Constructor:		Aliens.prototype.Container_initialize = Aliens.prototype.initialize;	// Unique to avoid overiding base class		/**		* INIT METHODS		*/		Aliens.prototype.initialize = function()		{			this.Container_initialize();			this.alienWidth		= this.image.width/2;			this.alienHeight	= this.image.height/2;			this.spriteSheet	= new SpriteSheet(this.image,this.alienWidth,this.alienHeight,{blackClosed:[0,1,'blackOpen'],blackOpen:[1,2,'blackClosed'],greenClosed:[2,3,'greenOpen'],greenOpen:[3,4,'greenClosed'] });			this.bitmapSequence	= new BitmapSequence(this.spriteSheet);			this.setup();		}		Aliens.prototype.setup = function()		{			this.x			= this.offsetPosition.x;			this.y			= this.offsetPosition.y;			this.position.x	= this.offsetPosition.x;			this.position.y	= this.offsetPosition.y;			this.width		= 0;			this.enabled	= false;			this.boundry	= new Rectangle(0, 0, Registry.get('STAGE_WIDTH'), Registry.get('STAGE_HEIGHT') - 40 - this.offsetPosition.y);			this.direction	= Aliens.DIR_RIGHT;			this.aliens		= [];			this.createAliens(4);			this.createAliens(0);			this.createAliens(4);		}		Aliens.prototype.createAliens = function(type)		{			switch(type)			{				case 4:					var _coords		= [{x:0,y:0},{x:0,y:1},{x:0,y:2},{x:1,y:2},{x:2,y:0},{x:2,y:1},{x:2,y:2},{x:2,y:3},{x:2,y:4}];					var _sequence	= 'blackClosed';					var _color		= '#000';					break;				case 0:					var _coords		= [{x:0,y:0},{x:0,y:1},{x:0,y:2},{x:0,y:3},{x:0,y:4},{x:1,y:0},{x:1,y:4},{x:2,y:0},{x:2,y:1},{x:2,y:2},{x:2,y:3},{x:2,y:4}];					var _sequence	= 'greenClosed';					var _color		= '#4d852b';					break;				default: // For TEST only					var _coords		= [{x:0,y:0},{x:1,y:0}];					var _sequence	= 'blackClosed';					var _color		= '#000';					break;			}			var _this		= this;			var _offsetX	= this.width == 0 ? this.x : this.x + this.width + 25;			for(var i=0; i<_coords.length; ++i)			{				this.bitmapSequence	= this.bitmapSequence.clone(); // Rather than creating a brand new instance each time, and setting every property, we can just clone the current one				var alien	= new Alien(this.bitmapSequence, this.spriteSheet, this.alienWidth, this.alienHeight, _sequence, _color);				alien.x		= _coords[i].x * (this.alienWidth+4) + _offsetX;				alien.y		= _coords[i].y * (this.alienHeight+4) + this.y;				alien.shotFired.add(function(point) { _this.onAlienShooting(point); });				this.addChild(alien);				this.aliens.push(alien);			}			this.totalAliens	= this.aliens.length;			this.updateWidthAndHeight();		}		Aliens.prototype.onAlienShooting = function(point)		{			point.x	+= this.x;			point.y	+= this.y;			this.shotFired.dispatch(point); // Would be easier w/ Signal bubbling :/		}		/**		* HITTEST METHODS		*/		Aliens.prototype.checkForHit = function(bullit)		{			for(var i=0; i<this.totalAliens; ++i)			{				var alien	= this.aliens[i];				if(bullit && alien.inHitArea(new Point(bullit.x, bullit.y)) === true)				{					this.destroyAlien(alien);					// Update the width dn height used in movement calculations					this.updateWidthAndHeight();					// Dispatch Signals					this.alienKilled.dispatch(new Point(this.x + alien.x + alien.width/2, this.y + alien.y), alien.color, bullit);					if(this.totalAliens == 0) this.allKilled.dispatch();					break;				}			}		}		/**		* RENDERING METHODS		*/		Aliens.prototype.enable = function()		{			for(var i=0; i<this.totalAliens; ++i) this.aliens[i].enable();			this.enabled	= true;		}		Aliens.prototype.update = function()		{			if(this.enabled === false) return false;			if(this.y + this.height >= this.boundry.height)			{				this.reachedBottom.dispatch();				return false;			}			if(this.direction == Aliens.DIR_RIGHT)	this.updatePositionMovingRight();			if(this.direction == Aliens.DIR_LEFT)	this.updatePositionMovingLeft();			this.x	= this.position.x;			this.y	= this.position.y;		}		Aliens.prototype.updatePositionMovingRight = function()		{			if(this.x + this.speed + this.width - this.boundry.x >= this.boundry.width)			{				this.position.x	= this.boundry.width - this.width;				this.position.y	= this.position.y + this.alienHeight;				this.direction	= Aliens.DIR_LEFT;			}			else			{				this.position.x	= this.x + this.speed;			}		}		Aliens.prototype.updatePositionMovingLeft = function()		{			if(this.x - this.speed <= this.boundry.x)			{				this.position.x	= this.boundry.x;				this.position.y	= this.position.y + this.alienHeight;				this.direction	= Aliens.DIR_RIGHT;			}			else			{				this.position.x	= this.x - this.speed;			}		}		// Since width and height are not recognised properties on a Container, we update them manually on each tick		// The width/height is used to calculate when when aliens are close to the edges of their boundry (allowed movement)		Aliens.prototype.updateWidthAndHeight = function()		{			var _min	= new Point(Registry.get('STAGE_WIDTH'), Registry.get('STAGE_HEIGHT'));			var _max	= new Point(0,0);			for(var i=0; i<this.totalAliens; ++i)			{				var alien	= this.aliens[i];				_min.x		= Math.min(_min.x, alien.x);				_min.y		= Math.min(_min.y, alien.y);				_max.x		= Math.max(_max.x, alien.x + alien.width);				_max.y		= Math.max(_max.y, alien.y + alien.height);			}			this.width		= _max.x - _min.x;			this.height		= _max.y - _min.y;			this.boundry.x	= 0 - _min.x;		}		/**		* DESTROY METHODS		*/		Aliens.prototype.disable = function()		{			//this.alienKilled.removeAll(); // Don't remove the alienKilled Signal, 'cause the spaceship might have fired bullit that are still active...			this.allKilled.removeAll();			this.reachedBottom.removeAll();			this.shotFired.removeAll();			this.direction	= Aliens.DIR_NONE;			for(var i=0; i<this.totalAliens; ++i)			{				if(this.aliens[i]) this.aliens[i].disable();			}		}		Aliens.prototype.destroyAlien = function(alien)		{			this.aliens.splice(this.aliens.indexOf(alien), 1);			this.totalAliens	= this.aliens.length;			alien.disable();			this.removeChild(alien);		}		Aliens.prototype.destroyAliens = function()		{			for(var i=0; i<this.aliens.length; ++i)			{				if(this.aliens[i])				{					this.aliens[i].disable();					this.aliens[i].parent.removeChild(this.aliens[i]);				}			}		}		Aliens.prototype.reset = function()		{			this.alienKilled.removeAll();			this.destroyAliens();			this.setup();		}	window.Aliens = Aliens;}(window));
