circles

by ShipNK
use keyboard up, down, left, right
move big circle

and hit lots of small circle
♥0 | Line 169 | Modified 2011-08-04 02:35:19 | MIT License
play

ActionScript3 source code

/**
 * Copyright ShipNK ( http://wonderfl.net/user/ShipNK )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/dpFP
 */

package {
    import flash.display.Sprite;        
    import flash.display.Shape;
    import flash.events.KeyboardEvent;
    import flash.events.Event;
    import flash.geom.Rectangle;
    
    public class FlashTest extends Sprite {

        private var i:int;
        private var j:int;
        private var keys:Array = [];
        private var shape:Shape = new Shape();
        private var circle:Object;
        private var circle2d:Circle2D = new Circle2D( 0.6, 0, 0, 1 );

        public function FlashTest ()
        {
            circle2d.addWall( new Rectangle( 0, 0, 450, 450 ), 0.4 );
            circle2d.addCircle( 100, 100, 40, 50, 0, 0 );
            for( i = 0; i < 150; ++ i )
            {
                circle2d.addCircle( Math.random()*400 + 110, Math.random()*300 + 50, 10, 3, Math.random() - 2, Math.random() - 2 );
            }
            
            stage.addEventListener(Event.ENTER_FRAME, ENTER_FRAME );
            stage.addEventListener(KeyboardEvent.KEY_DOWN, downKey );
            stage.addEventListener(KeyboardEvent.KEY_UP, upKey ); 
            this.addChild( shape );
        }
        
        
        
        private function ENTER_FRAME (e:Event):void
        {
            circle2d.process();
            shape.graphics.clear();
            shape.graphics.lineStyle( 1 );
            for( i = 0; i < circle2d.circles.length; ++ i )
            {
                circle = circle2d.circles[ i ] as Object;
                shape.graphics.drawCircle( circle.x, circle.y, circle.radius );
            }
            //
            if( keys[ 38 ] )
            {
                circle2d.circles[ 0 ].speedY -= 1;
            }
            if( keys[ 40 ] )
            {
                circle2d.circles[ 0 ].speedY += 1;
            }
            if( keys[ 37 ] )
            {
                circle2d.circles[ 0 ].speedX -= 1;
            }
            if( keys[ 39 ] )
            {
                circle2d.circles[ 0 ].speedX += 1;
            }
        }
        
        private function downKey ( e:KeyboardEvent ):void
        {
            keys[ e.keyCode ] = true;
        }
        
        private function upKey (e:KeyboardEvent ):void
        {
            keys[ e.keyCode ] = false;
        }
    }
    
    //
   
    
}

import flash.geom.Rectangle;
    class Circle2D {
        
        private var i:int;
        private var j:int;
        public var circles:Array = [];
        private var circle:Object;
        private var circlePower:Number;
        private var circleRotation:Number;
        private var slideNumber:Number;
        private var wall:Rectangle = null;
        private var wallPower:Number = 0.9;
        private var removePower:Number;
        private var gravityX:Number;
        private var gravityY:Number;
        
        public function addCircle( cx:Number, cy:Number, cr:Number, cm:Number = 1, cspdX:Number = 0, cspdY:Number = 0 ):void
        {
            circle = {x:cx,y:cy,radius:cr,mass:cm,speedX:cspdX,speedY:cspdY};
            circles.push( circle );
        }
        public function addWall( rect:Rectangle, power:Number = 0.9 ):void
        {
            wallPower = power;
            wall = rect.clone();
        }
        public function removeWall():void
        {
            wall = null;
        }
        
        public function process ():void
        {
            for( i = 0; i < circles.length; ++ i )
            {
                circles[ i ].x += circles[ i ].speedX;
                circles[ i ].y += circles[ i ].speedY;
                circles[ i ].speedX *= slideNumber;
                circles[ i ].speedY *= slideNumber;
                circles[ i ].speedX += gravityX;
                circles[ i ].speedY += gravityY;
            }
            if( wall != null )
            {
                for( i = 0; i < circles.length; ++ i )
                {
                    if( circles[ i ].x - circles[ i ].radius < wall.left )
                    {
                        circles[ i ].speedX = Math.abs(circles[ i ].speedX) * wallPower;
                        circles[ i ].x = wall.left + circles[ i ].radius;
                    }
                    if( circles[ i ].x + circles[ i ].radius > wall.right )
                    {
                        circles[ i ].speedX = -1* Math.abs(circles[ i ].speedX) * wallPower;
                        circles[ i ].x = wall.right - circles[ i ].radius;
                    }
                    if( circles[ i ].y - circles[ i ].radius < wall.top )
                    {
                        circles[ i ].speedY = Math.abs(circles[ i ].speedY) * wallPower;
                        circles[ i ].y = wall.top + circles[ i ].radius;
                    }
                    if( circles[ i ].y + circles[ i ].radius > wall.bottom )
                    {
                        circles[ i ].speedY = -1* Math.abs(circles[ i ].speedY) * wallPower;
                        circles[ i ].y = wall.bottom - circles[ i ].radius;
                    }
                }
            }
            //
            for( i = 0; i < circles.length; ++ i )
            {
                for( j = i + 1; j < circles.length; ++ j)
                {
                    if( circleDistance( circles[ i ].x, circles[ i ].y, circles[ j ].x, circles[ j ].y ) < (circles[ j ].radius + circles[ i ].radius) * (circles[ j ].radius + circles[ i ].radius) )
                    {
                        circlePower = Math.abs(circles[ i ].speedX) + Math.abs(circles[ i ].speedY) + Math.abs(circles[ j ].speedX) + Math.abs(circles[ j ].speedY);
                        //
                        circleRotation = Math.atan2( circles[ i ].y - circles[ j ].y, circles[ i ].x - circles[ j ].x );
                        circles[ i ].speedX += Math.cos( circleRotation ) * circlePower / circles[ i ].mass * removePower;
                        circles[ i ].speedY += Math.sin( circleRotation ) * circlePower / circles[ i ].mass * removePower;
                        //
                        circleRotation = Math.atan2( circles[ j ].y - circles[ i ].y, circles[ j ].x - circles[ i ].x );
                        circles[ j ].speedX += Math.cos( circleRotation ) * circlePower / circles[ j ].mass * removePower;
                        circles[ j ].speedY += Math.sin( circleRotation ) * circlePower / circles[ j ].mass * removePower;
                        if( circles[ i ].mass < circles[ j ].mass )
                        {
                            circles[ i ].x = circles[ j ].x + Math.cos( circleRotation ) * (circles[ j ].radius + circles[ i ].radius);
                            circles[ i ].y = circles[ j ].y + Math.sin( circleRotation ) * (circles[ j ].radius + circles[ i ].radius);
                        }
                        else
                        {
                            circles[ j ].x = circles[ i ].x + Math.cos( circleRotation ) * (circles[ j ].radius + circles[ i ].radius);
                            circles[ j ].y = circles[ i ].y + Math.sin( circleRotation ) * (circles[ j ].radius + circles[ i ].radius);
                        }
                    }
                }
            }
        }
        
        
        public function Circle2D ( stopPower:Number, gX:Number = 0, gY:Number = 0, slide:Number = 1 ):void
        {
            gravityX = gX;
            gravityY = gY;
            removePower = stopPower;
            slideNumber = slide;
            circles = [];
        }

        private function circleDistance( ax:Number, ay:Number, bx:Number, by:Number ):Number
        {
            return (ax-bx)*(ax-bx)+(ay-by)*(ay-by);
        }

    }