package { import flash.display.*; import flash.events.*; import flash.text.*; public class Tower extends Sprite { public var running:Boolean = false; public var bullets = []; public var bulletMap:BitmapData; public var bmpBullet:Bitmap; //terrain and obstacles map public var terrain:Terrain; public var map:BitmapData; //tower rotation and fire rate public var tt:Sprite; public var salve:int = 10; //fire rate : how bullets are generated per update public var angle:Number = 0; public var speed:Number = .5; //hueRotator var nColorAngle:Number = 0; var nAngleInc:Number = .001; //output text var output:TextField; public function Tower( X:Number, Y:Number, terrain:Terrain ) { this.terrain = terrain; //BitmapData to play with the bullets map = terrain.map; //creates and places the emitter tt = new Sprite(); tt.graphics.lineStyle( 2, 0x000000, 1 ); tt.graphics.drawCircle( 0, 0, 10 ); tt.graphics.lineTo( 0, 0 ); tt.x = terrain.x + X; tt.y = terrain.y + Y; addChild( tt ); //Bitmapdata on which the bullets will be drawn bulletMap = new BitmapData( terrain.width, terrain.height, true, 0x00000000 ); bmpBullet = new Bitmap( bulletMap ); addChild( bmpBullet ); } public function getColor():uint { nColorAngle += nAngleInc; // Détermine la couleur du tracé en fonction de la variable nColorAngle var nR:Number = Math.cos( nColorAngle ) * 127 + 128 << 16; var nG:Number = Math.cos( nColorAngle + 2 * Math.PI / 3) * 127 + 128 << 8; var nB:Number = Math.cos( nColorAngle + 4 * Math.PI / 3) * 127 + 128; return ( 255 << 24 | nR | nG | nB ); } public function update( e:Event = null ):void { //refreshes the stage and the bullets bitmapdata graphics.clear(); bulletMap.fillRect( bulletMap.rect, 0x00000000 ); //rotates the Tower angle = ( (angle + speed ) % 360 ); tt.rotation = Math.cos( angle / 180 * Math.PI ) * 360; // bullet generation var bt:Bullet; for( var s:int = 0; s < salve; s++) { //Bullet( x, y, angle, speed, color ) bt = new Bullet( tt.x, tt.y, tt.rotation, 1 + Math.random() * 2, getColor() ); bullets.push( bt ); } //temporary array to avoid splicing the bullets array( muuuch faster ) var tmp:Array = []; //hitTests series //vars about the bullets, as thereare quite a lot, //I do prefer storing them inside local variables instead of getting the variable value through the instance var ox:int; var oy:int; var A:Number; var V:Number; var C:uint; var nx:int; var ny:int; bulletMap.lock(); var i:int = bullets.length; while( i-- ) { bt = bullets[ i ]; //if the bullet is inside the terrain if( bt.x > 0 && bt.x < terrain.width && bt.y > 0 && bt.y < terrain.height ) { bt.move(); ox = bt.x; oy = bt.y; A = bt.a;; V = bt.v; C = bt.c; //draws a line of the vector length, shows a lot better on high speed bullets for( var j:int = 0; j < V; j++ ) { nx = ox + Math.cos( A ) * j; ny = oy + Math.sin( A ) * j; bulletMap.setPixel32( nx, ny, 0xFF666666 ); } //hitTests //if the bullet hits a transparent pixel if( map.getPixel32( bt.x, bt.y ) == 0x00000000 ) { //stores it in th valid bullets array tmp.push( bt ); }else{ //draws a pixel on the terrain map.setPixel32( ox, oy, C ); //and an impactcircle graphics.lineStyle( 1, C, 1 ); graphics.drawCircle( ox, oy, 3 ); } }else{ //if the bullet is outside the terrain bt = null; } } bulletMap.unlock(); //sets the new array of valid bullets bullets = tmp; } public function startStop( e:Event = null ):void { running != running ? true : false; if( running ) { removeEventListener( Event.ENTER_FRAME, update ); }else{ addEventListener( Event.ENTER_FRAME, update ); } } } }