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

forked from: forked from: ぷよんぷよんな栗様

Get Adobe Flash player
by tamac123 25 Jan 2011
    Embed
/**
 * Copyright tamac123 ( http://wonderfl.net/user/tamac123 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1SeL
 */

// forked from tamac123's forked from: ぷよんぷよんな栗様
// forked from fumix's ぷよんぷよんな栗様
/*

ぷよんぷよんな栗様

元ネタ

画像を行列で変形:てらこ23で発表したものの説明2
http://wonderfl.net/code/e56e31f395e7f7457464b00111a6dab5aadc3c7f

ぷよんぷよんな動き:Grid
http://wonderfl.net/code/b287f881a7e6e1f5c6f71d441134b7672dcc4884

どうしても、行列での画像変形がうまくいかずヒビが入ってしまいます涙
一回Bitmapに書き出さず、一気に変換かければうまくいくと思うのですが・・・

*/
package
{
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    
    //import net.hires.debug.Stats;
    
    [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "0x000000")]
    public class puyon extends Sprite
    {
        private var _container:Sprite;
        private var _canvas:Sprite;
        private var _bmdCurrent:BitmapData;
        
        private var _stageW:Number = 465;
        private var _stageH:Number = 465;
        private var _w:Number;
        private var _cP0:CirclePoint;
        private var _cP1:CirclePoint;
        private var _cP2:CirclePoint;
        private var _cP3:CirclePoint;
        private var _matrixArrayCurrent:Array;
        //分割数。増やせば細かくなるが、画像変換がうまくいってないので、増やすとヒビが大きくなるだけ・・・
        private var Pice:int = 5;

        private var Reaction:uint = 100; 
        private var spring:Number = 0.65;
        private var friction:Number = 0.75;
        
        
        private const IMAGE_URL:String = "http://www.planet-ape.net/wonderfl/kuri.jpg";        
        
        private var nextButton:Sprite;
        
        public function puyon()
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            //画像の読み込み
            var req:URLRequest = new URLRequest(IMAGE_URL);
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);    
            loader.load( req, new LoaderContext(true));
            // take a capture after 10 sec
            //Wonderfl.capture_delay( 120 );
        }
        
        //画像読み込み後の処理
        private function loadComplete(e:Event):void 
        {
            e.target.removeEventListener(Event.COMPLETE, loadComplete);
        
            //取得した画像を切り取って_bmdCurrentに入れる
            _bmdCurrent = new BitmapData (465, 465, true, 0xFFFFFF);
            _bmdCurrent.draw (e.target.loader.content.bitmapData);
            
            //キャンバスを用意してコンテナに入れる(重要じゃないので無視無視)
            _canvas = new Sprite();
            _container = new Sprite();
            _container.addChild(_canvas);
            addChild(_container);
            _container.x = 0;//(_stageW - _bmdCurrent.width)/2;
            _container.y = 0;//(_stageH - _bmdCurrent.height)/2;
            
            //画像の大きさに合わせ、ポイントを7x7の格子に配置する(配列に入れる)
            //CirclePointのコンストラクタの中で初期状態のポイント位置を保持してます。(initPoint)
            //その初期ポイントと、マウスドラッグで移動したポイントを比較してるのが、_drawの中。
            _w = _bmdCurrent.width / Pice;

            _matrixArrayCurrent = new Array ();
            //x軸とy軸の2重ループ(配列に入れる
            for (var j:int = 0; j <= _bmdCurrent.width; j += _w) {
                for (var i:int = 0; i <= _bmdCurrent.height; i += _w) {
                    var cp1:CirclePoint = new CirclePoint (i, j);
                    //cp1.addEventListener(MouseEvent.MOUSE_DOWN , _cPMouseDownHandler );
                    _matrixArrayCurrent.push (cp1);
                    _container.addChild (cp1);
                }
            }
            
            //_draw ();
            addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
            
            //速度とかメモリとかチェック(重要じゃないので無視無視)
            //addChild(new Stats());
        }
        private function onEnterFrameHandler(e:Event):void{
            var mousePoint:Point = new Point(mouseX, mouseY); 
            for each (var _point:CirclePoint in _matrixArrayCurrent) { 
                _point.update(mousePoint,  Reaction, spring, friction);
            }
            _draw();
        }
        private function _draw():void {
            /**
             * ポイントの番号は↓な感じ。
             *   0--------1
             *   ----------
             *   ----------
             *   2--------3
             */            
            //マトリックスを適応
            _canvas.graphics.clear();

            //配列のループ
            for (var k:String in _matrixArrayCurrent) {
                //
                if (int(k) > _matrixArrayCurrent.length - (Pice+3)) break;
                if ((int (k) + 1) % (Pice+1) == 0) continue;
                //初期状態のポイント取得
                _cP0 = _matrixArrayCurrent[int (k)];
                _cP1 = _matrixArrayCurrent[int (k) + 1];
                _cP2 = _matrixArrayCurrent[int (k) + (Pice+1)];
                _cP3 = _matrixArrayCurrent[int (k) + (Pice+2)];
                
                var aP0:Point = _cP0.initPoint;
                var aP1:Point = _cP1.initPoint;
                var aP2:Point = _cP2.initPoint;
                var aP3:Point = _cP3.initPoint;

                //初期状態のポイントよりマトリックス取得
                var initMatrix1:Matrix = _getTransformMatrix( aP0 , aP1 , aP2 );
                var initMatrix2:Matrix = _getTransformMatrix( aP3 , aP2 , aP1 );
                //変更状態のポイント取得
                var bP0:Point = new Point(_cP0.x , _cP0.y );
                var bP1:Point = new Point(_cP1.x , _cP1.y );
                var bP2:Point = new Point(_cP2.x , _cP2.y );
                var bP3:Point = new Point (_cP3.x , _cP3.y );
                //変更状態のポイントよりマトリックス取得
                var editMatrix1:Matrix = _getTransformMatrix( bP0 , bP1 , bP2);
                var editMatrix2:Matrix = _getTransformMatrix( bP3 , bP2 , bP1 );
                //初期状態と変更状態のマトリックスを合体
                var newMatrix1:Matrix = initMatrix1.clone();
                newMatrix1.concat(editMatrix1);
                var newMatrix2:Matrix = initMatrix2.clone();
                newMatrix2.concat(editMatrix2);
                
                //(無理やり)分割した1個目の描写のロジック
                //2個目はわざわざ、別のbitmapDataを用意しなくても直接描画できる。
                //1個目は別のbitmapDataを用意ないと順番がめちゃくちゃになる。
                var matBmd:BitmapData = new BitmapData(_w,_w);
                var mat:Matrix = new Matrix ();
                mat.tx = - aP0.x;
                mat.ty = - aP0.y;
                matBmd.draw (_bmdCurrent,mat);

                //分割した1個目を描画
                //_canvas.graphics.lineStyle(1 , 0x00FF00);
                _canvas.graphics.beginBitmapFill(matBmd , newMatrix1,true,true );
                _canvas.graphics.moveTo(bP0.x , bP0.y );
                _canvas.graphics.lineTo(bP2.x , bP2.y );
                _canvas.graphics.lineTo(bP1.x , bP1.y );
                _canvas.graphics.lineTo(bP0.x , bP0.y );
                _canvas.graphics.endFill ();

                //分割した2個目を描画
                //_canvas.graphics.lineStyle(0 , 0x00FF00);
                _canvas.graphics.beginBitmapFill(_bmdCurrent , newMatrix2,true,true );
                _canvas.graphics.moveTo(bP3.x , bP3.y );
                _canvas.graphics.lineTo(bP1.x , bP1.y );
                _canvas.graphics.lineTo(bP2.x , bP2.y );
                _canvas.graphics.lineTo(bP3.x , bP3.y );
                _canvas.graphics.endFill();
            }
        }
        
        
        private function _getTransformMatrix($pt0:Point, $pt1:Point, $pt2:Point):Matrix
        {
            /*
            http://www.adobe.com/jp/devnet/flash/articles/matrix_class.html
            a: 水平方向の伸縮率 = 変換後の幅/もとの幅
            b: 垂直方向の傾斜率 = 垂直方向の傾斜/もとの幅
            c: 水平方向の傾斜率 = 水平方向の傾斜/もとの高さ
            d: 垂直方向の伸縮率 = 変換後の高さ/もとの高さ
            tx: 水平方向の移動ピクセル数
            ty: 垂直方向の移動ピクセル数
            */
            var w:Number = _w;
            var h:Number = _w;
            var mat:Matrix = new Matrix();
            mat.a = ($pt1.x - $pt0.x) / w;
            mat.b = ($pt1.y - $pt0.y) / w;
            mat.c = ($pt2.x - $pt0.x) / h;
            mat.d = ($pt2.y - $pt0.y) / h;
            mat.tx = $pt0.x;
            mat.ty = $pt0.y;
            return mat;
        }
        
        //こっからマウスのドラッグとかの設定(無視無視)
        private function _cPMouseDownHandler(e:MouseEvent):void {
            CirclePoint(e.target).startDrag();
            CirclePoint(e.target).addEventListener(MouseEvent.MOUSE_MOVE , _cPMouseMoveHandler );
            stage.addEventListener(MouseEvent.MOUSE_UP , _cPMouseUpHandler );
        }
        
        private function _cPMouseUpHandler(e:MouseEvent):void {
            CirclePoint(e.target).stopDrag();
            CirclePoint(e.target).removeEventListener(MouseEvent.MOUSE_MOVE , _cPMouseMoveHandler );
            stage.removeEventListener(MouseEvent.MOUSE_UP , _cPMouseUpHandler );
        }
        
        private function _cPMouseMoveHandler(e:MouseEvent):void {
            _draw();
        }
        
        

    }
}


import flash.display.Bitmap;
import flash.display.Shape;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.geom.Point;

/**
 * 赤い点を書いてる。
 * それと初期状態のポイントをinitPointに保持してる。
 */
class CirclePoint extends Sprite {
    private var vx:Number = 0; 
    private var vy:Number = 0; 
    public var initPoint:Point;
    
    public function CirclePoint($x:Number , $y:Number) {

        this.x = $x;
        this.y = $y;
        this.initPoint = new Point( $x , $y );
        this.graphics.beginFill(0xFF0000,1);
        this.graphics.drawCircle(0,0,5);
        this.graphics.endFill();
        //this.buttonMode = true;
    }
    
    public function update(mousePoint:Point, Reaction:uint, spring:Number, friction:Number):void { 
       var dx:Number;
       var dy:Number;
       var distance:Number = Point.distance(mousePoint, initPoint); 
        if (distance < Reaction) { 
            var diff:Number     = distance * -1 * (Reaction - distance) / Reaction; 
            var radian:Number   = Math.atan2(mousePoint.y - initPoint.y, mousePoint.x - initPoint.y); 
            var diffPoint:Point = Point.polar(diff, radian); 
            dx = initPoint.x + diffPoint.x; 
            dy = initPoint.y + diffPoint.y; 
        } else{
            dx = initPoint.x; 
            dy = initPoint.y; 
        }
        vx += (dx - x) * spring; 
        vy += (dy - y) * spring; 
        vx *= friction; 
        vy *= friction; 
        x += vx; 
        y += vy; 
    }
}