forked from: FF: Ripple01 + Collision

by bradford.sedito forked from FF: Ripple01 + Collision (diff: 7)
-----------------------------------------------------
title : Ripple
波紋効果の練習
-----------------------------------------------------
♥0 | Line 204 | Modified 2016-05-20 00:31:31 | MIT License | (replaced)
play

ActionScript3 source code

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

// forked from WLAD's FF: Ripple01 + Collision
// forked from s8t1h12akj's forked from: forked from: Ripple01
// forked from WLAD's forked from: Ripple01
// forked from chutaicho's Ripple01
//-----------------------------------------------------
// title : Ripple
// 波紋効果の練習
//-----------------------------------------------------
package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.BlendMode;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageQuality;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.ConvolutionFilter;
    import flash.filters.DisplacementMapFilter;
    import flash.filters.DisplacementMapFilterMode;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.net.URLRequest;
    import flash.system.LoaderContext; 
    
    [SWF(backgroundColor="0x000000", frameRate="60", width="465", height="465")]
    public class Ripple01 extends Sprite
    {
        private const IMAGE_URL:String     = "http://assets.wonderfl.net/images/related_images/c/ca/ca47/ca47a073a3ed4057d9290bd18da08bbf14b8d896";
        private const RIPPLE_SIZE:int      = 20.0;     //20; //波紋サイズ
        private const BUFFER_SCALE:Number  = 0.20;   //0.2; //バッファ用ビットマップのサイズ
        
        private var _sample:Bitmap;
        private var _buffer1:BitmapData;
        private var _buffer2:BitmapData;
        private var _defData:BitmapData;
        private var _scale:Number;
        private var _matrix:Matrix; 
        private var _fullRect:Rectangle;
        private var _drawRect:Rectangle;
        private var _origin:Point;
        private var _filter:DisplacementMapFilter;
        private var _convoFilter:ConvolutionFilter;
        private var _colorTransform:ColorTransform;
        
        private var _index:int;
        private var _balls:Array = []; 
        
        public function Ripple01()
        {
            stage.quality = StageQuality.BEST; //.MEDIUM;;
            stage.frameRate = 60;
            graphics.beginFill(0);
            graphics.drawRect(0, 0, 465, 465);
            mouseEnabled = false;
            var BALLS:int = 3; //7;
            for ( _index = 0; _index < BALLS; ++_index ) {
                var ball:Ball = new Ball();
                ball.x = Math.random() * 465;
                ball.y = Math.random() * 465;
                stage.addChild( ball );
                _balls.push( ball );
            }
            stage.addEventListener('mouseUp', function(_:*):void {
                for ( _index = 0; _index < BALLS; ++_index ) {
                    _balls[_index].drag = false;
                }
            });
            stage.addEventListener('enterFrame', function(_:*):void {
                for ( _index = 0; _index < BALLS; ++_index ) {
                    _balls[_index].time();
                }
                for ( _index = 0; _index < BALLS; ++_index ) {
                    for ( var _jindex:int = _index + 1; _jindex < BALLS; ++_jindex ) {
                        if ( Point.distance( _balls[_index].pos, _balls[_jindex].pos ) > 
                        _balls[_index].radius + _balls[_jindex].radius ) {
                            //_balls[_index].contact = false;
                            //_balls[_jindex].contact = false;
                        }else _balls[_index].bounce( _balls[ _jindex ] );
                    }
                }
            });
            init();
        }    
        private function init():void
        {
            var req:URLRequest = new URLRequest(IMAGE_URL);
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);    
            loader.load( req, new LoaderContext(true));
        }
        private function loadComplete(e:Event):void
        {    
            e.target.removeEventListener(Event.COMPLETE, loadComplete);
            var sw:int = stage.stageWidth;
            var sh:int = stage.stageHeight;
            
            // 読み込んだ画像を一旦リサイズ
            var source:Bitmap = e.target.loader.content as Bitmap;
            var resizeData:BitmapData = new BitmapData(sw, sh);
            source.width = sw;
            source.height = sh;
            resizeData.draw( source );
            
            _sample = new Bitmap(resizeData);
            addChild(_sample);
            
            // ちょっと傾ける
            //rotationX = -30;
            
            
            
            _buffer1 = new BitmapData(_sample.width*BUFFER_SCALE, _sample.height*BUFFER_SCALE, false, 0x000000);
            _buffer2 = new BitmapData(_buffer1.width, _buffer1.height, false, 0x000000);
            _defData = new BitmapData(_sample.width, _sample.height, false, 0x7f7f7f);

            
            _fullRect = new Rectangle(0, 0, _buffer1.width, _buffer1.height);
            _drawRect = new Rectangle();
            
            _filter = new DisplacementMapFilter(_buffer1, new Point(), BitmapDataChannel.BLUE, BitmapDataChannel.BLUE, 50, 50, DisplacementMapFilterMode.WRAP);
            _sample.filters = [_filter];
        
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        
            _convoFilter = new ConvolutionFilter(3, 3, [0.5, 1, 0.5, 1, 0, 1, 0.5, 1, 0.5], 3);
            _colorTransform = new ColorTransform(1, 1, 1, 1, 0, 128, 128);       
            _matrix = new Matrix(_defData.width/_buffer1.width, 0, 0, _defData.height/_buffer1.height);
        }
        private function enterFrameHandler(event : Event) : void
        {
            var rad:int = RIPPLE_SIZE/2 * -1;
            for ( _index = 0; _index < _balls.length; ++_index ) {
                if ( _balls[_index].force > 1 ) {
                    _drawRect.x = ( rad + _balls[_index].x ) * BUFFER_SCALE;    
                    _drawRect.y = ( rad + _balls[_index].y ) * BUFFER_SCALE;
                    _drawRect.width = _drawRect.height = RIPPLE_SIZE * BUFFER_SCALE;
                    _buffer1.fillRect(_drawRect, 0xFF);
                }
            }
            var temp:BitmapData = _buffer2.clone();
            _buffer2.applyFilter(_buffer1, _fullRect, new Point(), _convoFilter);
            _buffer2.draw(temp, null, null, BlendMode.SUBTRACT, null, false);
            _defData.draw(_buffer2, _matrix, _colorTransform, null, null, true);
            _filter.mapBitmap = _defData;
            _sample.filters = [_filter];
            temp.dispose();
            switchBuffers();
        }
        // バッファの入れ替え
        private function switchBuffers():void
        {
            var temp : BitmapData;
            temp = _buffer1;
            _buffer1 = _buffer2;
            _buffer2 = temp;
        }
    }
}
import flash.display.Sprite;
import flash.geom.Point;

class Ball extends Sprite
{
    public var velocityX:Number = 0;
    public var velocityY:Number = 0;
    public var mass:Number = 1;
    public var radius:Number = 14;
    public var drag:Boolean = false;
    public var force:Number = 0;
    public var contact:Boolean = false;
    public function get pos():Point { return new Point(x, y);}
    
    public function Ball()
    {
        useHandCursor = buttonMode = true;
        velocityX = ( Math.random() - 0.5 ) * 4;
        velocityY = ( Math.random() - 0.5 ) * 4;
        graphics.beginFill( 0x88EBF0 | ( Math.random() * 0x333333 ) );
        graphics.drawCircle( 0, 0, 14 );
        graphics.endFill();
        graphics.beginFill( 0xFFFFFF );
        graphics.drawCircle( 4, 0, 2);
        graphics.endFill();
        graphics.beginFill( 0xFFFFFF, 0.5 );
        graphics.drawCircle( 4, 0, 4);
        graphics.endFill();
        addEventListener('mouseDown', function(_:*):void { drag = true; });
    }
    
    public function time():void
    {
        rotation = Math.atan2( y - stage.mouseY, x - stage.mouseX ) * 57.295779;
        x += velocityX;
        y += velocityY;
        if ( x - radius < 0 ) velocityX = Math.abs( velocityX );
        if ( x + radius > 465 ) velocityX = -Math.abs( velocityX );
        if ( y - radius < 0 ) velocityY = Math.abs( velocityY );
        if ( y + radius > 465 ) velocityY = -Math.abs( velocityY );
        velocityX *= 0.99;
        velocityY *= 0.99;
        if ( drag ) {
            velocityX += ( stage.mouseX - x ) * 0.05; 
            velocityY += ( stage.mouseY - y ) * 0.05; 
        }
        if ( Math.abs(velocityX) < 0.1 ) velocityX = 0;
        if ( Math.abs(velocityY) < 0.1 ) velocityY = 0;
        force = Math.sqrt( velocityX * velocityX + velocityY * velocityY);
    }
    
    public function bounce( ball:Ball ):void
    {
    
        //if ( ball.contact || contact ) return;
        //ball.contact = true; contact = true;
        var dx:Number = ball.x - x;
        var dy:Number = ball.y - y;
        var a:Number  = Math.atan2(dy, dx);
        var m1:Number = Math.sqrt(ball.velocityX * ball.velocityX + ball.velocityY * ball.velocityY);
        var m2:Number = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
        var d1:Number = Math.atan2(ball.velocityY, ball.velocityX);
        var d2:Number = Math.atan2(velocityY, velocityX);
        var s1x:Number = m1 * Math.cos(d1 - a);
        var s1y:Number = m1 * Math.sin(d1 - a);
        var s2x:Number = m2 * Math.cos(d2 - a);
        var s2y:Number = m2 * Math.sin(d2 - a);
        var v1x:Number = ((ball.mass - mass) * s1x + (mass + mass) * s2x) / (ball.mass + mass);
        var v2x:Number = ((ball.mass + ball.mass) * s1x + (mass - ball.mass) * s2x) / (ball.mass + mass);
        var v1y:Number = s1y;
        var v2y:Number = s2y;
        ball.velocityX = Math.cos(a) * v1x + Math.cos(a + Math.PI / 2) * v1y;
        ball.velocityY = Math.sin(a) * v1x + Math.sin(a + Math.PI / 2) * v1y;
        velocityX = Math.cos(a) * v2x + Math.cos(a + Math.PI / 2) * v2y;
        ball.velocityY = Math.sin(a) * v2x + Math.sin(a + Math.PI / 2) * v2y;
    }
}