/* ぷよんぷよんな栗様 元ネタ 画像を行列で変形:てらこ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 = "60", 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 _pointsArray:Array; //分割数。増やせば細かくなるが、画像変換がうまくいってないので、増やすとヒビが大きくなるだけ・・・ private var Pice:int = 15; private var Reaction:uint = 100;//変化する範囲(半径) private var spring:Number = 0.75;//びよーんってなる数(振動数?? private var friction:Number = 0.85;//びよーんってなる大きさ private const IMAGE_URL:String = "http://www.planet-ape.net/wonderfl/kuri.jpg"; private var nextButton:Sprite; private var mouseSp: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 (); _pointsArray = 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); _matrixArrayCurrent.push (cp1); _container.addChild (cp1); var _points:Points = new Points(i,j); _pointsArray.push(_points); //cp1.addEventListener(MouseEvent.MOUSE_DOWN , _cPMouseDownHandler ); } } //_draw (); addEventListener(Event.ENTER_FRAME,onEnterFrameHandler); //速度とかメモリとかチェック(重要じゃないので無視無視) //addChild(new Stats()); } private function onEnterFrameHandler(e:Event):void{ var mousePoint:Point = new Point(mouseX, mouseY); var i:int; for each (var _point:Points in _pointsArray) { _point.update(mousePoint, Reaction, spring, friction); _matrixArrayCurrent[i].x = _point.x; _matrixArrayCurrent[i].y = _point.y; i++; } _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 { public var initPoint:Point; public function CirclePoint($x:Number , $y:Number) { x = $x; 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; } } import flash.geom.Point; class Points { private var localX:Number; private var localY:Number; private var vx:Number = 0; private var vy:Number = 0; private var _x:Number; private var _y:Number; public function Points(x:Number, y:Number) { _x = localX = x; _y = localY = y; } public function update(mousePoint:Point, Reaction:uint, spring:Number, friction:Number):void { var dx:Number; var dy:Number; var distance:Number = Point.distance(mousePoint, new Point(localX, localY)); if (distance < Reaction) { var diff:Number = distance * -1 * (Reaction - distance) / Reaction; var radian:Number = Math.atan2(mousePoint.y - localY, mousePoint.x - localX); var diffPoint:Point = Point.polar(diff, radian); dx = localX + diffPoint.x; dy = localY + diffPoint.y; } else{ dx = localX; dy = localY; } vx += (dx - _x) * spring; vy += (dy - _y) * spring; vx *= friction; vy *= friction; _x += vx; _y += vy; } public function get x():Number { return _x; } public function get y():Number { return _y; } } ぷよんぷよんな栗様(キレイなぷよんぷよんバージョン