In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Squad Control

kill +300pt.
veteran +200pt.
Get Adobe Flash player
by greentec 18 Feb 2011
/**
 * Copyright greentec ( http://wonderfl.net/user/greentec )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/eHS9
 */

// forked from greentec's Flock Attack
// forked from greentec's Fleet Attack
// forked from greentec's Ship Attack
// forked from greentec's Ship Placement
// forked from greentec's Circle Placement
package {
    import flash.filters.GlowFilter;
    import flash.events.MouseEvent;
    import flash.filters.DropShadowFilter;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import com.bit101.components.Label;
    import com.bit101.components.Style;
    import com.bit101.components.Component;
    import com.bit101.components.PushButton;
    import net.wonderfl.score.basic.BasicScoreForm;
    import net.wonderfl.score.basic.BasicScoreRecordViewer;
    import net.wonderfl.utils.FontLoader;
//    import flash.geom.Matrix;

    
    public class CirclePlacement extends Sprite {
        public var circle:Circle;
        public var circs:Array=[];
        public var num:uint=15;
        public var H:Number=stage.stageHeight;
        public var W:Number=stage.stageWidth;
        public var _sumLabel:Label;
        public var _infoLabel1:Label;
        public var _infoLabel2:Label;
        public var _infoLabel3:Label;
        public var _infoLabel4:Label;
        public var _numLabel1:Label;
        public var _numLabel2:Label;
        public var bg_Sp:Sprite;
        public var bgData:BitmapData;
        public var bg:Bitmap;
        public var starNum:uint=300;
        public var ships:Array=[];
        public var time:uint=0;
        public var hp_Sp:Sprite;
        public var battle_Sp:Sprite;
        public var laser_Sp:Sprite;
        public var target_Sp:Sprite;
        public var fleet1:Array=[];
        public var fleet2:Array=[];
        public var fleetCol:int=18;
        public var fleetRow:int=4;
        public var fleetNum:int=fleetCol*fleetRow;
        public var ShipPerFleet:int=50;
        public var ShipPerSquad:int=17;
        
        public var clicked_Sw:Boolean=false;
        public var clicked:Ship=new Ship(1,1,1,1,999,999);
        public var glow:GlowFilter=new GlowFilter(0xffff00);
        public var glow1:GlowFilter=new GlowFilter(0x00ff7f,1,10,10);
        public var glow2:GlowFilter=new GlowFilter(0xffa500,1,10,10);
        public var glow3:GlowFilter=new GlowFilter(0xf0f8ff,1,10,10);
        
        public var targets:Array=[];
        
        public var _squad1:PushButton;
        public var _squad2:PushButton;
        public var _squad3:PushButton;
        public var _clr:PushButton;
        
        public var control_Sw:uint=0;
        
        public var W_:int=stage.stageWidth;
        public var H_:int=stage.stageHeight;
        
        public var laser_R:int=30;
        
        public var score:uint=0;
        
        public var FORM:BasicScoreForm;
        
        public function CirclePlacement() {
            //Component.initStage ( stage ) ;  
            //stage.frameRate=12;          
            
            bg_Sp=new Sprite();
            addChild(bg_Sp);
            hp_Sp=new Sprite();
            addChild(hp_Sp);
            hp_Sp.filters=[new DropShadowFilter(2,45,0x00ff00)];
            laser_Sp=new Sprite();
            target_Sp=new Sprite();
            
            battle_Sp=new Sprite();
            addChild(target_Sp);
            addChild(battle_Sp);
            //addChild(laser_Sp);
            
            var buttonWidth:uint = 20;
            
            _squad1=new PushButton(this, W_/2-buttonWidth*1.5-5,H_-buttonWidth, "1", squadcontrol1);
            _squad2=new PushButton(this, W_/2-buttonWidth*0.5,H_-buttonWidth, "2", squadcontrol2);
            _squad3=new PushButton(this, W_/2+buttonWidth*0.5+5,H_-buttonWidth, "3", squadcontrol3);
            
            _clr=new PushButton(this, W_/2+buttonWidth*1.5+10,H_-buttonWidth, "clr", clr_control);
            
            _squad1.width = buttonWidth;
            _squad2.width = buttonWidth;
            _squad3.width = buttonWidth;
            _squad1.height=buttonWidth;
            _squad2.height=buttonWidth;
            _squad3.height=buttonWidth;
            _squad1.filters=[glow1];
            _squad2.filters=[glow2];
            _squad3.filters=[glow3];
            _clr.width=_clr.height=buttonWidth;

            
            Draw_Space();
            
            
            //addEventListener(Event.ENTER_FRAME, onAdd);
            
            
            Style.LABEL_TEXT = 0xffffff;
            _sumLabel = new Label(this, 0, 0, "Score : 0");
            _sumLabel.filters=[new DropShadowFilter(2.0, 45,0x00ff00)];
            
            _infoLabel1 = new Label(this, 0, 405, "Gene : ");
            _infoLabel1.filters=[new DropShadowFilter(2.0, 45,0x0000ff)];
            
            _infoLabel2 = new Label(this, 0, 420, "HP    : ");
            _infoLabel2.filters=[new DropShadowFilter(2.0, 45,0x6666ff)];
            
            _infoLabel3 = new Label(this, 0, 435, "Speed : ");
            _infoLabel3.filters=[new DropShadowFilter(2.0, 45,0xaaaaff)];
            
            _infoLabel4 = new Label(this, 0, 450, "Attack: ");
            _infoLabel4.filters=[new DropShadowFilter(2.0, 45,0xddddff)];
            
            _numLabel1 = new Label(this, 435, H_-100, "50");
            _numLabel1.filters=[new DropShadowFilter(2.0, 45,0x0000cc)];
            
            _numLabel2 = new Label(this, 450, H_-100, "50");
            _numLabel2.filters=[new DropShadowFilter(2.0, 45,0xcc0000)];
            
            Init_Fleet();
            Ship_Placement();
            
            
            for(var i:int=0;i<3;i++)
            {
                var mark:Mark=new Mark();
                
                mark.x=mark.y=-50;
                mark.rotation=Math.random()*360;
                addChild(mark);
                targets.push(mark);   
            }            
            
        }
        
        public function clr_control(e:MouseEvent):void
        {
            for(var i:int=ShipPerFleet;i<ShipPerFleet*2;i++)
            {
                var ship_:Ship=ships[i];
                ship_.controled=false;
            }
            
            for(i=0;i<3;i++)
            {
                targets[i].x=-50;
                targets[i].y=-50;
            }

            
            //battle_Sp.graphics.clear();
        }

        
        public function control_to(e:MouseEvent):void
        {
            
            for(var i:int=ShipPerFleet;i<ShipPerFleet*2;i++)
            {
                var ship_:Ship=ships[i];
                ship_.filters=[];
                if(ship_.unpowered==false && ship_.squad==control_Sw)
                {
                    ship_.target_Point=new Vector2D(mouseX,mouseY);
                    ship_.controled=true;    
                    
                }               
            }
            
            targets[control_Sw-1].x=mouseX;
            targets[control_Sw-1].y=mouseY;
            
            
            
            bg_Sp.removeEventListener(MouseEvent.CLICK, control_to);
            control_Sw=0;    

        }

        
        public function squadcontrol1(e:MouseEvent):void
        {
            if(control_Sw==0)
            {
                bg_Sp.addEventListener(MouseEvent.CLICK, control_to);  
            }
            
            control_Sw=1;            
            
            for(var i:int=ShipPerFleet;i<ShipPerFleet*2;i++)
            {
                var ship_:Ship=ships[i];
                ship_.filters=[];
                if(ship_.unpowered==false && ship_.squad==1)
                {
                    ship_.filters=[glow1];    
                    
                }               
            }
            
            

        }
        
        public function squadcontrol2(e:MouseEvent):void
        {
            if(control_Sw==0)
            {
                bg_Sp.addEventListener(MouseEvent.CLICK, control_to);  
            }

            control_Sw=2; 
            
            for(var i:int=ShipPerFleet;i<ShipPerFleet*2;i++)
            {
                var ship_:Ship=ships[i];
                ship_.filters=[];
                if(ship_.unpowered==false && ship_.squad==2)
                {
                    ship_.filters=[glow2];    
                    
                }               
            }
            
        }
        
        public function squadcontrol3(e:MouseEvent):void
        {
            if(control_Sw==0)
            {
                bg_Sp.addEventListener(MouseEvent.CLICK, control_to);  
            }
            
            control_Sw=3; 
            
            for(var i:int=ShipPerFleet;i<ShipPerFleet*2;i++)
            {
                var ship_:Ship=ships[i];
                ship_.filters=[];
                if(ship_.unpowered==false && ship_.squad==3)
                {
                    ship_.filters=[glow3];    
                    
                }               
            }
        }

        
        public function Draw_Space():void
        {
            bgData=new BitmapData(465,465,false,0);
            
            for(var i:uint=0;i<starNum;i++)
            {
                var r:uint=Math.random()*100+155;
                var g:uint=Math.random()*100+155;
                var b:uint=Math.random()*100+155;
                var cl:uint=(r<<16)|(g<<8)|b;
                bgData.setPixel(Math.random()*465,Math.random()*465,cl);    
            
            }

            
            bg=new Bitmap(bgData);
            bg_Sp.addChild(bg);
            
            
        }

        
        /*public function onAdd(e:Event):void
        {
            var sw:Boolean=false;
            circle=new Circle();
            circle.x=Math.random()*W;
            circle.y=Math.random()*H;
            
            
            var circ2:Circle;
            var i:int;
            if(circs.length==0)
            {
                addChild(circle);
                circs.push(circle);
            }
            else
            {
                for(i=circs.length-1;i>-1;i--)
                {
                    circ2=circs[i];    
                    if(circ2.hitTestObject(circle)==true)
                    {
                        sw=true;
                    }

                    
                }
   
                if(sw==false)
                {
                    addChild(circle);
                    circs.push(circle);
                    
                    _sumLabel.text="Num : "+circs.length;
                }
            
            }

            
            
            
            if(circs.length==num)
            {
                removeEventListener(Event.ENTER_FRAME, onAdd);
                Init_Fleet();
                Ship_Placement();   
                addEventListener(Event.ENTER_FRAME, wipeCircleOut);
            
            }

        }*/
        
        public function Init_Fleet():void
        {
            
            
            var Cards:Array=[];
            var randCard:int;
            var i:int;
            
            for(i=0;i<fleetNum;i++)
            {
                Cards.push(i);
            }
            
            for(i=0;i<fleetNum;i++)
            {
                fleet1.push(0);
                fleet2.push(0);
            }
            
            for(i=0;i<ShipPerFleet;i++)
            {
                randCard=int(Math.random()*Cards.length);
                fleet1[Cards[randCard]]++;
                Cards.splice(randCard,1);
            }
            
            Cards=[];
            for(i=0;i<fleetNum;i++)
            {
                Cards.push(i);
            }
            
            for(i=0;i<ShipPerFleet;i++)
            {
                randCard=int(Math.random()*Cards.length);
                fleet2[Cards[randCard]]++;
                Cards.splice(randCard,1);
            }
            
        }

        
        /*public function wipeCircleOut(e:Event):void
        {
            for(var i:int=0;i<circs.length;i++)
            {
                circs[i].alpha-=0.02;    
                if(circs[i].alpha<0)
                {
                    removeEventListener(Event.ENTER_FRAME, wipeCircleOut);
                }

            }

        }*/
        
        public function Ship_Placement():void
        {
            var ship:Ship;
            var i:int;
            
            for(i=0;i<fleet1.length;i++)
            {
                if(fleet1[i]!=0)
                {
                        
                    
    
                    /*var r1:Number=Math.random();
                    var r2:Number=Math.random();
                    var r3:Number=Math.random();
                    var total:Number=r1+r2+r3;
                    var totalpoint:int=15;
                    
                    var dp:int=1+r1/total*totalpoint;
                    var ap:int=1+r2/total*totalpoint;
                    var ep:int=1+r3/total*totalpoint;
                    */
                    
                    
                    ship=new Ship(8,6,1,0x0000ff,0, i);
//                    ship.x=W_/2+((i%fleetRow)-int(fleetRow/2))*20+10;
//                    ship.y=30+int(i/fleetRow)*20+10;
                    ship.y=50+((i%fleetRow)-int(fleetRow/2))*20+10;
                    ship.x=30+int(i/fleetRow)*20+10;
                    ship.rotation=90+Math.random()*20-10;
                    ship.addEventListener(MouseEvent.CLICK, ship_click);
                    battle_Sp.addChild(ship);
                    ships.push(ship);
                }
            }
            var ship_no:int=-1;
            for(i=0;i<fleet2.length;i++)
            {
                var squad_no:int;
                
                if(fleet2[i]!=0)
                {
                    ship_no++;
                    squad_no=int(ship_no/ShipPerSquad)+1;
                    
                    ship=new Ship(8,6,1,0xff0000,1, i+fleet1.length,squad_no);
//                    ship.x=W_/2-((i%fleetRow)-int(fleetRow/2))*20-10;
//                    ship.y=H_-30-int(i/fleetRow)*20-10;
                    ship.y=H_-50-((i%fleetRow)-int(fleetRow/2))*20-10;
                    ship.x=W_-30-int(i/fleetRow)*20-10;
                    ship.rotation=-90+Math.random()*20-10;
                    ship.addEventListener(MouseEvent.CLICK, ship_click);
                    battle_Sp.addChild(ship);
                    ships.push(ship);
                }
            }
            
            addChild(laser_Sp);
            
            Ship_targeting();
            
            addEventListener(Event.ENTER_FRAME, Ship_Move);
            
                     

            
        }
        
        public function Ship_targeting():void
        {
            var ship:Ship, enemy:Ship;
            var mindist:Number;
            var target:int;
            var dx:Number, dy:Number, dist:Number;
            var err1:Number, err2:Number, err3:Number, err4:Number;
            var dx1:Number, dy1:Number;
            
            for(var i:int=0;i<ships.length;i++)
            {
                
                ship=ships[i];
                if(ship.unpowered==false)
                {
                    mindist=999999;
                    for(var j:int=ships.length-1;j>-1;j--)
                    {
                        if(i!=j && ship.flag!=ships[j].flag)
                        {
                            enemy=ships[j];
                            dx=ship.x-enemy.x;
                            dy=ship.y-enemy.y;
                            dist=Math.abs(dx*dx+dy*dy);
                            
                            if(dist<mindist && enemy.unpowered==false)
                            {
                                mindist=dist;
                                target=j;
                            }
                        }
    
                    }
                    ship.target=target;
                    enemy=ships[target];
                    
                    if(ship.flag!=enemy.flag && ship.inSight(enemy)==true && enemy.unpowered==false)
                    {
                        with(laser_Sp)
                        {
                            if(ship.flag==0)
                            {
                               graphics.lineStyle(0.5,0x00ff00);
                            }
                            else
                            {
                               graphics.lineStyle(0.5,0xffcc00); 
                            }
                            
                            //err1=Math.random()*5-2.5;
                            //err2=Math.random()*5-2.5;
                            err3=Math.random()*5-2.5;
                            err4=Math.random()*5-2.5;
                            
                            dx1=Math.cos(ship.rotation*Math.PI/180)*8;
                            dy1=Math.sin(ship.rotation*Math.PI/180)*8;
                            
                            graphics.moveTo(ship.x+dx1,ship.y+dy1);
                            graphics.lineTo(enemy.x+err3,enemy.y+err4);
                            score+=0.1;
                        }
                        
                        enemy.hp-=ship.atk;
                        if(enemy.hp<=0)
                        {
                            enemy.hp=0;
                            enemy.unpowered=true;
                            enemy.alpha=0.4;
                            if(enemy.flag==0)
                            {
                                score+=300;
                            }
                            battle_Sp.setChildIndex(enemy,0);//move to back
                            if(ship.vet==0)
                            {
                                ship.vet++;
                                ship.draw_mark();
                                ship.atk+=2;
                                if(ship.flag==1)
                                {
                                    score+=200;
                                }
                            }
                            
                        }
                    }
                }
            }
        }

        
        public function Ship_Move(e:Event):void
        {
            _sumLabel.text="Score :"+String(int(score));
            
            target_Sp.graphics.clear();
            
            
            
            var ship:Ship;
                
            for(var i:int=0;i<ships.length;i++)
            {
                ship=ships[i];
                if(ship.unpowered==false)
                {
                    if(ship.controled==true)
                    {
                        ship.seek(ship.target_Point);
                        target_Sp.graphics.lineStyle(0,0x333333,0.7);
                        target_Sp.graphics.moveTo(ship.x,ship.y);
                        target_Sp.graphics.lineTo(ship.target_Point.x,ship.target_Point.y);
                    }

                    //ship.seek(ships[ship.target].position);
                    else
                    {
                        ship.pursue(ships[ship.target]);

                    }
                    
                    
                    
                    ship.flock(ships);
                    ship.update();
                }
            }
              
            for(i=0;i<3;i++)
            {
                targets[i].rotation+=2;
            }      
            
            time++;
            if(time%3==0)
            {
                laser_Sp.graphics.clear();
                Ship_targeting();
                
                drawHP();
                
                if(clicked_Sw==true)
                {
                    showClickedInfo();
                    

                }
            }
    
        }
        
        public function showClickedInfo():void
        {
            _infoLabel1.text="Gene : [ "+clicked.dp+" "+clicked.ap+" "+clicked.ep+" ]";
            _infoLabel2.text="HP    : "+int(clicked.hp*10)/10+" / "+int(clicked.fullhp*10)/10;
            _infoLabel3.text="Speed : "+int(clicked.vel*10)/10;
            
            if(clicked.vet!=0)
            {
                _infoLabel4.text="Attack: "+int(clicked.atk*10)/10+" *";
            }
            else
            {
                _infoLabel4.text="Attack: "+int(clicked.atk*10)/10;
            }
        }



        public function drawHP():void
        {
            var totalhp1:Number=0, totalhp2:Number=0, totalfullhp1:Number=0, totalfullhp2:Number=0;
            //var squadhp1:Number=0, squadhp2:Number=0, squadhp3:Number=0;
            var squadnum1:int=0, squadnum2:int=0, squadnum3:int=0; 
            var num1:int=0, num2:int=0;    
                
            for(var i:int=0;i<ships.length;i++)
            {
                var ship:Ship=ships[i];
                if(ship.flag==0)
                {
                    totalhp1+=ship.hp;
                    totalfullhp1+=ship.fullhp;
                    if(ship.unpowered==false)
                        num1++;
                }
                else
                {
                    
                                        
                    

                    totalhp2+=ship.hp;
                    totalfullhp2+=ship.fullhp;
                    if(ship.unpowered==false)
                    {
                        num2++;
                        
                        if(ship.squad==1)
                        {
                            squadnum1++;
                        }
                        else if(ship.squad==2)
                        {
                            squadnum2++;
                        }
                        else if(ship.squad==3)
                        {
                            squadnum3++;
                        }
                    }
                }
            }
            
            if(squadnum1==0)
            {    
                _squad1.mouseEnabled=false;
                _squad1.alpha=0.5;
            }
            if(squadnum2==0)
            {
                _squad2.mouseEnabled=false;
                _squad2.alpha=0.5;
            }
            if(squadnum3==0)
            {
                _squad3.mouseEnabled=false;
                _squad3.alpha=0.5;
            }

            hp_Sp.graphics.clear();
            hp_Sp.graphics.lineStyle(0,0xcccccc);
            hp_Sp.graphics.beginFill(0x0000ff,0.8);
            hp_Sp.graphics.drawRect(435,H_-(totalhp1/totalfullhp1)*80,10,(totalhp1/totalfullhp1)*80);
            hp_Sp.graphics.endFill();
            hp_Sp.graphics.beginFill(0xff0000,0.8);
            hp_Sp.graphics.drawRect(450,H_-(totalhp2/totalfullhp2)*80,10,(totalhp2/totalfullhp2)*80);
            hp_Sp.graphics.endFill();
            
            _numLabel1.text=String(num1);
            _numLabel1.y=H_-(totalhp1/totalfullhp1)*80-20;
            _numLabel2.text=String(num2);
            _numLabel2.y=H_-(totalhp2/totalfullhp2)*80-20;
            
            if(num1==0 || num2==0)
            {
                removeEventListener(Event.ENTER_FRAME, Ship_Move);
                score+=num2*1500;
                _sumLabel.text="Score : "+String(int(score));
                
                Style.LABEL_TEXT = 0x666666;
                
                FORM = new BasicScoreForm (
                    stage,
                    100,
                    100,
                    int(score) ,
                    'SAVE SCORE' ,showRanking//,
                    
                    //"01a99d26f2dcfb7160ed9951d449401b576fcece",
                    //"a76b80051993a7c6322bf8b4bbc457b44c3d4f5c"
                    );
                
            }

        }
        
        public function showRanking ( $didSavedScore:Boolean ) :void 
        {
            Style.LABEL_TEXT = 0x666666;
            
            stage.removeChild ( FORM ) ;
            var FORM2:BasicScoreRecordViewer = new BasicScoreRecordViewer (
                stage,
                100,
                100 ,
                'RANKING' ,
                99 ,
                true , null
            //function ( ) :void {
                //stage.removeChild ( FORM2 ) ;
                
            //}
                //,
                //"01a99d26f2dcfb7160ed9951d449401b576fcece",
                //"a76b80051993a7c6322bf8b4bbc457b44c3d4f5c"
                
            )
        }
                       

        
        public function ship_click(e:MouseEvent):void
        {
            
            clicked.filters=[];
            
            clicked=Ship(e.target);
            clicked.filters=[glow];
            clicked_Sw=true;
            
            showClickedInfo();

            
            
            
        }



    }
}



import flash.display.Sprite;
import flash.geom.Matrix;

class Circle extends Sprite
{
    public var r:Number, color:Number;
        
    public function Circle(r:Number=0, color:uint=0x333333)
    {
        var m:Matrix;
        r=Math.random()*10+35;
        
        this.graphics.lineStyle(0,0xffffff);
        this.graphics.beginGradientFill("radial",[0xffffff,0x0000ff],[0.7,0],[0,100],m=new Matrix(400,400,Math.PI/2,0,0));
        this.graphics.drawCircle(0,0,r);
        this.graphics.endFill();
        //this.blendMode="screen";
    }


}




class Vector2D
{
    import flash.display.Graphics;
    
    /**
     * A basic 2-dimensional vector class.
     */
    
        private var _x:Number;
        private var _y:Number;
        
        /**
         * Constructor.
         */
        public function Vector2D(x:Number = 0, y:Number = 0)
        {
            _x = x;
            _y = y;
        }
        
        /**
         * Can be used to visualize the vector. Generally used for debug purposes only.
         * @param graphics The Graphics instance to draw the vector on.
         * @param color The color of the line used to represent the vector.
         */
        public function draw(graphics:Graphics, color:uint = 0):void
        {
            graphics.lineStyle(0, color);
            graphics.moveTo(0, 0);
            graphics.lineTo(_x, _y);
        }
        
        /**
         * Generates a copy of this vector.
         * @return Vector2D A copy of this vector.
         */
        public function clone():Vector2D
        {
            return new Vector2D(x, y);
        }
        
        /**
         * Sets this vector's x and y values, and thus length, to zero.
         * @return Vector2D A reference to this vector.
         */
        public function zero():Vector2D
        {
            _x = 0;
            _y = 0;
            return this;
        }
        
        /**
         * Whether or not this vector is equal to zero, i.e. its x, y, and length are zero.
         * @return Boolean True if vector is zero, otherwise false.
         */
        public function isZero():Boolean
        {
            return _x == 0 && _y == 0;
        }
        
        /**
         * Sets / gets the length or magnitude of this vector. Changing the length will change the x and y but not the angle of this vector.
         */
        public function set length(value:Number):void
        {
            var a:Number = angle;
            _x = Math.cos(a) * value;
            _y = Math.sin(a) * value;
        }
        public function get length():Number
        {
            return Math.sqrt(lengthSQ);
        }
        
        /**
         * Gets the length of this vector, squared.
         */
        public function get lengthSQ():Number
        {
            return _x * _x + _y * _y;
        }
        
        /**
         * Gets / sets the angle of this vector. Changing the angle changes the x and y but retains the same length.
         */
        public function set angle(value:Number):void
        {
            var len:Number = length;
            _x = Math.cos(value) * len;
            _y = Math.sin(value) * len;
        }
        public function get angle():Number
        {
            return Math.atan2(_y, _x);
        }
        
        /**
         * Normalizes this vector. Equivalent to setting the length to one, but more efficient.
         * @return Vector2D A reference to this vector. 
         */
        public function normalize():Vector2D
        {
            if(length == 0)
            {
                _x = 1;
                return this;
            }
            var len:Number = length;
            _x /= len;
            _y /= len;
            return this;
        }
        
        /**
         * Ensures the length of the vector is no longer than the given value.
         * @param max The maximum value this vector should be. If length is larger than max, it will be truncated to this value.
         * @return Vector2D A reference to this vector.
         */
        public function truncate(max:Number):Vector2D
        {
            length = Math.min(max, length);
            return this;
        }
        
        /**
         * Reverses the direction of this vector.
         * @return Vector2D A reference to this vector.
         */
        public function reverse():Vector2D
        {
            _x = -_x;
            _y = -_y;
            return this;
        }
        
        /**
         * Whether or not this vector is normalized, i.e. its length is equal to one.
         * @return Boolean True if length is one, otherwise false.
         */
        public function isNormalized():Boolean
        {
            return length == 1.0;
        }
        
        /**
         * Calculates the dot product of this vector and another given vector.
         * @param v2 Another Vector2D instance.
         * @return Number The dot product of this vector and the one passed in as a parameter.
         */
        public function dotProd(v2:Vector2D):Number
        {
            return _x * v2.x + _y * v2.y;
        }
        
        /**
         * Calculates the cross product of this vector and another given vector.
         * @param v2 Another Vector2D instance.
         * @return Number The cross product of this vector and the one passed in as a parameter.
         */
        public function crossProd(v2:Vector2D):Number
        {
            return _x * v2.y - _y * v2.x;
        }
        
        /**
         * Calculates the angle between two vectors.
         * @param v1 The first Vector2D instance.
         * @param v2 The second Vector2D instance.
         * @return Number the angle between the two given vectors.
         */
        public static function angleBetween(v1:Vector2D, v2:Vector2D):Number
        {
            if(!v1.isNormalized()) v1 = v1.clone().normalize();
            if(!v2.isNormalized()) v2 = v2.clone().normalize();
            return Math.acos(v1.dotProd(v2));
        }
        
        /**
         * Determines if a given vector is to the right or left of this vector.
         * @return int If to the left, returns -1. If to the right, +1.
         */
        public function sign(v2:Vector2D):int
        {
            return perp.dotProd(v2) < 0 ? -1 : 1;
        }
        
        /**
         * Finds a vector that is perpendicular to this vector.
         * @return Vector2D A vector that is perpendicular to this vector.
         */
        public function get perp():Vector2D
        {
            return new Vector2D(-y, x);
        }
        
        /**
         * Calculates the distance from this vector to another given vector.
         * @param v2 A Vector2D instance.
         * @return Number The distance from this vector to the vector passed as a parameter.
         */
        public function dist(v2:Vector2D):Number
        {
            return Math.sqrt(distSQ(v2));
        }
        
        /**
         * Calculates the distance squared from this vector to another given vector.
         * @param v2 A Vector2D instance.
         * @return Number The distance squared from this vector to the vector passed as a parameter.
         */
        public function distSQ(v2:Vector2D):Number
        {
            var dx:Number = v2.x - x;
            var dy:Number = v2.y - y;
            return dx * dx + dy * dy;
        }
        
        /**
         * Adds a vector to this vector, creating a new Vector2D instance to hold the result.
         * @param v2 A Vector2D instance.
         * @return Vector2D A new vector containing the results of the addition.
         */
        public function add(v2:Vector2D):Vector2D
        {
            return new Vector2D(_x + v2.x, _y + v2.y);
        }
        
        /**
         * Subtacts a vector to this vector, creating a new Vector2D instance to hold the result.
         * @param v2 A Vector2D instance.
         * @return Vector2D A new vector containing the results of the subtraction.
         */
        public function subtract(v2:Vector2D):Vector2D
        {
            return new Vector2D(_x - v2.x, _y - v2.y);
        }
        
        /**
         * Multiplies this vector by a value, creating a new Vector2D instance to hold the result.
         * @param v2 A Vector2D instance.
         * @return Vector2D A new vector containing the results of the multiplication.
         */
        public function multiply(value:Number):Vector2D
        {
            return new Vector2D(_x * value, _y * value);
        }
        
        /**
         * Divides this vector by a value, creating a new Vector2D instance to hold the result.
         * @param v2 A Vector2D instance.
         * @return Vector2D A new vector containing the results of the division.
         */
        public function divide(value:Number):Vector2D
        {
            return new Vector2D(_x / value, _y / value);
        }
        
        /**
         * Indicates whether this vector and another Vector2D instance are equal in value.
         * @param v2 A Vector2D instance.
         * @return Boolean True if the other vector is equal to this one, false if not.
         */
        public function equals(v2:Vector2D):Boolean
        {
            return _x == v2.x && _y == v2.y;
        }
        
        /**
         * Sets / gets the x value of this vector.
         */
        public function set x(value:Number):void
        {
            _x = value;
        }
        public function get x():Number
        {
            return _x;
        }
        
        /**
         * Sets / gets the y value of this vector.
         */
        public function set y(value:Number):void
        {
            _y = value;
        }
        public function get y():Number
        {
            return _y;
        }
        
        /**
         * Generates a string representation of this vector.
         * @return String A description of this vector.
         */
        public function toString():String
        {
            return "[Vector2D (x:" + _x + ", y:" + _y + ")]";
        }
    
}

class Vehicle extends Sprite
{
    protected var _edgeBehavior:String = BOUNCE;
    protected var _mass:Number = 50.0;
    protected var _maxSpeed:Number = 10;
    protected var _position:Vector2D;
    protected var _velocity:Vector2D;
    
    // potential edge behaviors
    public static const WRAP:String = "wrap";
    public static const BOUNCE:String = "bounce";
    
    /**
     * Constructor.
     */
    public function Vehicle()
    {
        _position = new Vector2D();
        _velocity = new Vector2D();
        draw();
    }
    
    /**
     * Default graphics for vehicle. Can be overridden in subclasses.
     */
    protected function draw():void
    {
        /*graphics.clear();
        graphics.lineStyle(0);
        graphics.moveTo(10, 0);
        graphics.lineTo(-10, 5);
        graphics.lineTo(-10, -5);
        graphics.lineTo(10, 0);*/
    }
    
    /**
     * Handles all basic motion. Should be called on each frame / timer interval.
     */
    public function update():void
    {
        // make sure velocity stays within max speed.
        _velocity.truncate(_maxSpeed);
        
        // add velocity to position
        _position = _position.add(_velocity);
        
        // handle any edge behavior
        if(_edgeBehavior == WRAP)
        {
            wrap();
        }
        else if(_edgeBehavior == BOUNCE)
        {
            bounce();
        }
        
        // update position of sprite
        x = position.x;
        y = position.y;
        
        // rotate heading to match velocity
        rotation = _velocity.angle * 180 / Math.PI;
    }
    
    /**
     * Causes character to bounce off edge if edge is hit.
     */
    private function bounce():void
    {
        if(stage != null)
        {
            if(position.x > stage.stageWidth)
            {
                position.x = stage.stageWidth;
                velocity.x *= -0.7;
            }
            else if(position.x < 0)
            {
                position.x = 0;
                velocity.x *= -0.7;
            }
            
            if(position.y > stage.stageHeight)
            {
                position.y = stage.stageHeight;
                velocity.y *= -0.7;
            }
            else if(position.y < 0)
            {
                position.y = 0;
                velocity.y *= -0.7;
            }
        }
    }
    
    /**
     * Causes character to wrap around to opposite edge if edge is hit.
     */
    private function wrap():void
    {
        if(stage != null)
        {
            if(position.x > stage.stageWidth) position.x = 0;
            if(position.x < 0) position.x = stage.stageWidth;
            if(position.y > stage.stageHeight) position.y = 0;
            if(position.y < 0) position.y = stage.stageHeight;
        }
    }
    
    /**
     * Sets / gets what will happen if character hits edge.
     */
    public function set edgeBehavior(value:String):void
    {
        _edgeBehavior = value;
    }
    public function get edgeBehavior():String
    {
        return _edgeBehavior;
    }
    
    /**
     * Sets / gets mass of character.
     */
    public function set mass(value:Number):void
    {
        _mass = value;
    }
    public function get mass():Number
    {
        return _mass;
    }
    
    /**
     * Sets / gets maximum speed of character.
     */
    public function set maxSpeed(value:Number):void
    {
        _maxSpeed = value;
    }
    public function get maxSpeed():Number
    {
        return _maxSpeed;
    }
    
    /**
     * Sets / gets position of character as a Vector2D.
     */
    public function set position(value:Vector2D):void
    {
        _position = value;
        x = _position.x;
        y = _position.y;
    }
    public function get position():Vector2D
    {
        return _position;
    }
    
    /**
     * Sets / gets velocity of character as a Vector2D.
     */
    public function set velocity(value:Vector2D):void
    {
        _velocity = value;
    }
    public function get velocity():Vector2D
    {
        return _velocity;
    }
    
    /**
     * Sets x position of character. Overrides Sprite.x to set internal Vector2D position as well.
     */
    override public function set x(value:Number):void
    {
        super.x = value;
        _position.x = x;
    }
    
    /**
     * Sets y position of character. Overrides Sprite.y to set internal Vector2D position as well.
     */
    override public function set y(value:Number):void
    {
        super.y = value;
        _position.y = y;
    }
    
}

class Ship extends Vehicle
{
    public var color:Number;
    public var dp:int;//durability - increases HP, decreases velocity
    public var ap:int;//armed - increases attack, decreases velocity
    public var ep:int;//engine - increases velocity, decreases HP
    public var hp:Number;
    public var fullhp:Number;
    public var vel:Number;
    public var Min_vel:int=1;
    public var atk:Number;
    public var unpowered:Boolean=false;
    public var flag:int=0;
    public var id:int;
    public var col:uint;
    public var colr:uint=0xcccccc;
    public var vet:int=0;//veteran
    public var squad:int=0;
    
    public var target:uint;
    public var target_Point:Vector2D;
    public var controled:Boolean=false;
    
    private var _steeringForce:Vector2D;
    private var _maxForce:Number = 0.5;//1
    private var _inSightDist:int=40;//laser_Range
    private var _tooCloseDist:int=10;    
    
    public function Ship(dp:int, ap:int, ep:int, col:uint, flag:int, id:int, squad:int=0,color:uint=0xcccccc)
    {
            //var col:uint=(((ap/18)*0xff) << 16) | ((dp/18)*0xff << 8) | ((ep/18)*0xff);
            //ap - red color, dp - green color, ep - blue color
            
            
            this.col=col;
            this.colr=color;
            
            draw_();
            
            this.unpowered=false;
            
            this.dp=dp;
            this.ap=ap;
            this.ep=ep;
            
            this.hp=(dp+10)*5-ep*2;
            this.fullhp=this.hp;
            this.vel=ep*2-(dp*0.1+ap*0.3);
            if(this.vel<=Min_vel)
                this.vel=Min_vel;
            this.atk=ap;
        
            this._mass=1000-this.vel*2;
            if(this.vel<10)
            {
                this._maxSpeed=this.vel/2;    
            }
            else
            {
                this._maxSpeed=5;
            }
            
            this.flag=flag;
            this.id=id;
            this.squad=squad;
            
            this.controled=false;

            _steeringForce = new Vector2D();
            super();

    }
    
    public function draw_():void
    {
        graphics.clear();
        graphics.beginFill(this.col,0.8);
        //graphics.beginFill(col,1);
    
        graphics.lineStyle(0,this.colr);
        graphics.moveTo(8,0);
        graphics.lineTo(-8,4);
        graphics.lineTo(-8,-4);
        graphics.lineTo(8,0);
        
        graphics.endFill();
    
    }
    
    public function draw_mark():void
    {
        graphics.lineStyle(0,0xffffff);
        graphics.moveTo(-4,3);
        graphics.lineTo(-4,-3);
        graphics.lineStyle(0,0x000000);
        graphics.moveTo(-6,3.5);
        graphics.lineTo(-6,-3.5);    
    
    }


    
    override public function update():void
    {
        _steeringForce.truncate(_maxForce);
        _steeringForce = _steeringForce.divide(_mass);
        _velocity = _velocity.add(_steeringForce);
        _steeringForce = new Vector2D();
        super.update();
    }
    
    public function seek(target:Vector2D):void
    {
        var desiredVelocity:Vector2D = target.subtract(_position);
        desiredVelocity.normalize();
        desiredVelocity = desiredVelocity.multiply(_maxSpeed);
        var force:Vector2D = desiredVelocity.subtract(_velocity);
        _steeringForce = _steeringForce.add(force);
    }
    
    public function seek2(target:Vector2D):void
    {
        var desiredVelocity:Vector2D = target.subtract(_position);
        desiredVelocity.normalize();
        desiredVelocity = desiredVelocity.multiply(_maxSpeed/5);//minimalize force-for flock err
        var force:Vector2D = desiredVelocity.subtract(_velocity);
        _steeringForce = _steeringForce.add(force);
    }
    
    public function pursue(target:Vehicle):void
    {
        var lookAheadTime:Number = position.dist(target.position) / _maxSpeed;
        var predictedTarget:Vector2D = target.position.add(target.velocity.multiply(lookAheadTime));
        seek(predictedTarget);
    }
    
    public function flee(target:Vector2D):void
    {
        var desiredVelocity:Vector2D = target.subtract(_position);
        desiredVelocity.normalize();
        desiredVelocity = desiredVelocity.multiply(_maxSpeed);
        var force:Vector2D = desiredVelocity.subtract(_velocity);
        _steeringForce = _steeringForce.subtract(force);
    }
    
    public function flock(vehicles:Array):void
    {
        var averageVelocity:Vector2D = _velocity.clone();
        var averagePosition:Vector2D = new Vector2D();
        var inSightCount:int = 0;
        for(var i:int = 0; i < vehicles.length; i++)
        {
            var vehicle:Ship = vehicles[i] as Ship;
            if(vehicle != this && inSight(vehicle) && this.flag==vehicle.flag)
            {
                averageVelocity = averageVelocity.add(vehicle.velocity);
                averagePosition = averagePosition.add(vehicle.position);
                if(tooClose(vehicle)) flee(vehicle.position);
                inSightCount++;
            }
        }
        if(inSightCount > 0)
        {
            averageVelocity = averageVelocity.divide(inSightCount);
            averagePosition = averagePosition.divide(inSightCount);
            
            seek2(averagePosition);
            _steeringForce.add(averageVelocity.subtract(_velocity));
        }
    }
    
    public function inSight(vehicle:Vehicle):Boolean        
    {
        if(_position.dist(vehicle.position) > _inSightDist) return false;
        var heading:Vector2D = _velocity.clone().normalize();
        var difference:Vector2D = vehicle.position.subtract(_position);
        var dotProd:Number = difference.dotProd(heading);
        
        if(dotProd < 0) return false;//120 degree
        return true;
    }
    
    public function tooClose(vehicle:Vehicle):Boolean
    {
        return _position.dist(vehicle.position) < _tooCloseDist;
    }

}

class Mark extends Sprite
{
    public function Mark():void
    {
        graphics.lineStyle(2,0x00ff00,0.9);
        //graphics.drawEllipse(-10,-5,20,10);
        graphics.drawCircle(0,0,10);
        graphics.lineStyle(0,0x00dd00,0.9);
        //graphics.drawEllipse(-4,-2,8,4);
        graphics.drawCircle(0,0,12);
        graphics.drawCircle(0,0,4);
        graphics.drawCircle(0,0,2);
        graphics.lineStyle(3,0x000000,0.8);
        graphics.moveTo(-12,0);
        graphics.lineTo(12,0);
        graphics.moveTo(0,-12);
        graphics.lineTo(0,12);
        
        //graphics.drawCircle(10,0,1);
        this.mouseEnabled=false;
    }

}