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

drag and rotate

Get Adobe Flash player
by faseer 10 Apr 2010
  • Related works: 7
  • Talk

    taichiyamadasan at 03 Aug 2010 18:27
    135行目のtは何をしているんですか
    nabe at 06 Aug 2010 21:35
    各加速度を求めていると思います。 直感的には、 1.丁度重心の位置をつかんでドラッグしても回転の勢いは付きません。重心から離れた点をドラッグする必要があります。 2.現在の移動速度と丁度同じ速度でドラッグしても力は加わりません。異なる速度でドラッグする必要があります。 3.重心に向かって、あるいは、重心から離れる方向に力を加えても、回転の勢いは付きません。力の方向と重心の方向が垂直になるようにする必要があります。 つまり、回転速度の変化率は「ドラックしている点の加速度」と「ドラッグしている点の重心から隔たり」の外積に比例します。
    taichiyamadasan at 08 Aug 2010 08:05
    コメントありがとうございます。 今の自分に理解するのには2~3日かかるかと思うのですが 必ずアウトプットします!
    taichiyamadasan at 11 Aug 2010 14:40
    148行~149行目は一次変換なんでしょうか? 誰かわかる方お願いします。
    nabe at 12 Aug 2010 20:02
    直感的には、 ・手を離した状態(free)のカードは、重心を中心に回転します。 ・一方、ドラッグ中のカードは、ドラッグしている点を中心に回転します。 ソースを上から下まで把握してないのですが、勘では、 1.重心(x,y)とドラッグ点(mx,my)の差(dx, dy)を求めます。 2.回転速度vrに合わせて(dx, dy)を回転し(dx', dy')を求めます。(一次変換の一種) 3.(dx, dy)と(dx', dy')の差(aax, aay)を求めて重心(x, y)を移動します。
    taichiyamadasan at 15 Aug 2010 04:15
    nabeさん いつもありがとうございます!

    Tags

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

package {
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    public class FlashTest extends Sprite {
    		private var drList:Array;
        public function FlashTest() {
        	
        		stage.align = StageAlign.TOP_LEFT;
        		stage.scaleMode = StageScaleMode.NO_SCALE;
        		stage.stageFocusRect = false;
        	
        		drList = [];
        		
            for(var i:int=0; i<15; ++i)
            {
            		drList[drList.length] = new DragRotater(
            			addChild(new Card(
            				Math.random()*400,
	            			Math.random()*400,
 	           			100 + Math.random()*100,
  	          			100 + Math.random()*100,
   	         			Math.random()*360)
   	         		) as Sprite
   	         	);
            }
        }
    }
}

import flash.display.Sprite;
class Card extends Sprite
{
	public function Card(x:Number, y:Number, w:Number, h:Number, r:Number)
	{
		graphics.beginFill(Math.random() * 0xFFFFFF);
		graphics.drawRoundRect(-w*.5, -h*.5, w,h, 16, 16);
		graphics.endFill();
		this.x = x;
		this.y = y;
		rotation = r;
	}
}

import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
class DragRotater
{
	protected var x:Number;
	protected var y:Number;
	protected var r:Number;
	protected var vx:Number = .0;
	protected var vy:Number = .0;
	protected var vr:Number = .0;
	protected var aax:Number = .0;
	protected var aay:Number = .0;
	protected var mass:Number = 1.0;
	protected var damp:Number = .9;
	protected var mx0:Number;
	protected var my0:Number;
	protected var free:Boolean = true;
	protected var _skin:Sprite;
	
	public function DragRotater(skin:Sprite = null)
	{
		this.skin = skin;
	}
	
	public function get skin():Sprite{ return _skin; }
	public function set skin(v:Sprite):void
	{
		if(skin) uninit(null);
		_skin = v;
		if(skin){
			if(skin.stage) init(null);
			else skin.addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
		}
	}
	
	protected function init(e:Event):void
	{
		skin.addEventListener(Event.REMOVED_FROM_STAGE, uninit);
		skin.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		skin.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		skin.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		
		x = skin.x;
		y = skin.y;
		r = skin.rotation;
	}
	protected function uninit(e:Event):void
	{
		skin.removeEventListener(Event.REMOVED_FROM_STAGE, uninit);
		skin.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		skin.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		skin.stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
	}
	
	protected function onMouseUp(e:MouseEvent):void
	{
		vx += aax;
		vy += aay;
		aax = aay = 0;
		free = true;
	}
	
	protected function onMouseDown(e:MouseEvent):void
	{
		mx0 = skin.parent.mouseX;
		my0 = skin.parent.mouseY;
		free = false;
	}
	
	protected function onEnterFrame(e:Event):void
	{
		if(free)
		{
			x += vx;
			y += vy;
		}
		else
		{
			var mx:Number = skin.parent.mouseX;
			var my:Number = skin.parent.mouseY;
			var dmx:Number = mx - mx0;
			var dmy:Number = my - my0;
			mx0 = mx;
			my0 = my;
			
			var fx:Number = (dmx - vx) * mass;
			var fy:Number = (dmy - vy) * mass;
			var ax:Number = mx - x;
			var ay:Number = my - y;
			var t:Number = fx * ay - fy * ax;
			
			vx = dmx;
			vy = dmy;
			vr += t * .005;
			
			x += vx;
			y += vy;
			
			var dx:Number = mx - x;
			var dy:Number = my - y;
			var cos:Number = Math.cos(vr * Math.PI / 180);
			var sin:Number = Math.sin(vr * Math.PI / 180);
			aax = dx - (cos * dx + sin * dy);
			aay = dy - (cos * dy - sin * dx);
			
			x += aax;
			y += aay;
		}
		
		r -= vr;
		
		vx *= damp;
		vy *= damp;
		vr *= damp;
		
		skin.x = x;
		skin.y = y;
		skin.rotation = r;
	}
}