Source

ld3k / Indicator.as

package
{
	import flash.geom.Rectangle;
	
	import net.flashpunk.Entity;
	import net.flashpunk.Graphic;
	import net.flashpunk.Mask;
	import net.flashpunk.Sfx;
	import net.flashpunk.World;
	import net.flashpunk.graphics.Canvas;
	import net.flashpunk.graphics.Emitter;
	
	import objs.Line;
	import objs.Obj;
	import objs.RemoveLine;
	
	// handles indicate danger objects in indi phase
	public class Indicator extends Entity
	{
		private static const AMOUNT:int = 32;
		private static var _head:Canvas;
		private static var _removehead:Canvas;
		public static var pemit:Emitter;
		private static var _indivec:Array;
		private static var _indisfx:Sfx;
		
		public static function staticInit(world:World):void
		{
			_head  = new Canvas(1, 1);
			_removehead = new Canvas(1, 1);
			pemit = new Emitter(Au.ImgDot, 1, 1);
			_indivec = new Array();
			_indisfx = new Sfx(Au.SndIndi);
			
			_head.fill(new Rectangle(0, 0, 1, 1), Au.HEADCOLOR);
			_removehead.fill(new Rectangle(0, 0, 1, 1), Au.REMVCOLOR);
			pemit.newType("tail", [0]);
			pemit.setAlpha("tail", 1, 0);
			pemit.setMotion("tail", 0, 0, 50);
			pemit.newType("glow", [0]);
			pemit.setMotion("glow",0, 0, 10, 360, 3, 10);
			pemit.newType("explode", [0]);
			pemit.setMotion("explode", 0, 5, 25, 360, 8, 10);
			pemit.newType("rmtail", [1]);
			pemit.setAlpha("rmtail", 1, 0);
			pemit.setMotion("rmtail", 0, 0, 20);
			
			
			for (var ix:int = 0; ix < AMOUNT; ++ix) {
				_indivec.push(new Indicator()); // indicators pool
			}
			
			var dummy:Entity = new Entity(0, 0, pemit);
			world.addList(_indivec);
			world.add(dummy);
		}
		
		public static function handleObj(Ob:Obj):void
		{
			for (var ix:int = 0; ix < AMOUNT; ++ix) {
				if (!_indivec[ix].active) {
					_indisfx.play(0.5);
					_indivec[ix].reset(Ob);
					return;
				}
			}
			throw "not enough indicators";
		}
		
		
		
		//////////////////////////////////////////////////////
		private const VELOCITY:Number = 3.5;
		private const RMVELOCITY:Number = 5;
		
		private var _updateHandler:Function; // avoid if
		private var _line:Line; // temp pointer	
		private var _vec:Vector2D; // stores dx dy
		
		public function Indicator()
		{
			_vec = new Vector2D(0, 0);
			super(-1, -1);
			active = false; // born inactive
		}
		
		public function reset(Ob:Obj):Indicator
		{
			// use this to enable object pooling
			if (Ob is Line) {
				_line = Line(Ob);
				graphic = _head;
				x = _line.startx; y = _line.starty;
				_vec.set(_line.endx - _line.startx, _line.endy - _line.starty);
				_vec.magnitude = VELOCITY; // normalize & velo
				_updateHandler = handleLineAdd;
			} else if (Ob is RemoveLine) {
				_line = RemoveLine(Ob).line;
				graphic = _removehead;
				x = _line.endx; // go reverse
				y = _line.endy;
				_vec.set(_line.startx - _line.endx, _line.starty - _line.endy); // reverse
				_vec.magnitude = RMVELOCITY;
				_updateHandler = handleRemoveLine; // no need to do other things
			}
			
			active = true;
			return this;
		}
		
		private function handleLineAdd():void
		{
			//moveBy(_vec.x, _vec.y);
			x += _vec.x;
			y += _vec.y;
			pemit.emit("tail", x, y);
		}
		
		private function handleRemoveLine():void
		{
			//moveBy(_vec.x, _vec.y);
			x += _vec.x;
			y += _vec.y;
			pemit.emit("rmtail", x, y);
		}
		
		override public function update():void
		{
			_updateHandler();
//			_pemit.emit("tail", x + _vec.x / 2, y + _vec.y / 2);
			super.update();	
			
			// stop on next frame
			if (x < -10 || x > 110 || y < -10 || y > 110) {
				active = false;
			}
		}
	}
}