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

Flock Attack

Get Adobe Flash player
by greentec 12 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/a9p5
 */

// 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 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 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 clicked_Sw:Boolean=false;
        public var clicked:Ship=new Ship(1,1,1,1,999,999);
        public var glow:GlowFilter;
        
        public var W_:int=stage.stageWidth;
        public var H_:int=stage.stageHeight;
        
        public var laser_R:int=30;
        
        public function CirclePlacement() {
            
            //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();
            battle_Sp=new Sprite();
            addChild(battle_Sp);
            //addChild(laser_Sp);
            
            Draw_Space();
            
            
            //addEventListener(Event.ENTER_FRAME, onAdd);
            
            
            Style.LABEL_TEXT = 0xffffff;
            //_sumLabel = new Label(this, 0, 0, "Num : 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, "10");
            _numLabel1.filters=[new DropShadowFilter(2.0, 45,0x0000cc)];
            
            _numLabel2 = new Label(this, 450, H_-100, "10");
            _numLabel2.filters=[new DropShadowFilter(2.0, 45,0xcc0000)];
            
            glow=new GlowFilter(0xffff00);
            
            Init_Fleet();
            Ship_Placement();   
            
            
        }
        
        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%fleetCol)-int(fleetCol/2))*20+10;
                    ship.y=30+int(i/fleetCol)*20+10;
                    ship.rotation=90+Math.random()*20-10;
                    ship.addEventListener(MouseEvent.CLICK, ship_click);
                    battle_Sp.addChild(ship);
                    ships.push(ship);
                }
            }
            
            for(i=0;i<fleet2.length;i++)
            {
                if(fleet2[i]!=0)
                {
                    ship=new Ship(8,6,1,0xff0000,1, i+fleet1.length);
                    ship.x=W_/2-((i%fleetCol)-int(fleetCol/2))*20-10;
                    ship.y=H_-30-int(i/fleetCol)*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);
                        }
                        
                        enemy.hp-=ship.atk;
                        if(enemy.hp<=0)
                        {
                            enemy.hp=0;
                            enemy.unpowered=true;
                            enemy.alpha=0.4;
                            battle_Sp.setChildIndex(enemy,0);//move to back
                            if(ship.vet==0)
                            {
                                ship.vet++;
                                ship.draw_mark();
                                ship.atk+=2;
                            }
                            
                        }
                    }
                }
            }
        }

        
        public function Ship_Move(e:Event):void
        {
            var ship:Ship;
                
            for(var i:int=0;i<ships.length;i++)
            {
                ship=ships[i];
                if(ship.unpowered==false)
                {
                    
                    //ship.seek(ships[ship.target].position);
                    ship.pursue(ships[ship.target]);
                    ship.flock(ships);
                    ship.update();
                }
            }
            
            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 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++;
                }
            }

            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;
        }

        
        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 target:uint;
    
    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, 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;

            _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;
    }

}