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

簡易物理計算

簡易物理エンジン
箱の四隅はクリックでつまんで動かせます。
※激しく動かすとすぐに箱はこわれますw
箱同士の判定などは入れていないので、とりあえず場外判定のみ入ってます。
※変形した箱を2つ追加しました。
Get Adobe Flash player
by okoi 26 Mar 2010
    Embed
/**
 * Copyright okoi ( http://wonderfl.net/user/okoi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/prrJ
 */

//
//	簡易物理エンジン
//	箱の四隅はクリックでつまんで動かせます。
//		※激しく動かすとすぐに箱はこわれますw
//	箱同士の判定などは入れていないので、とりあえず場外判定のみ入ってます。
//	
//	※変形した箱を2つ追加しました。	
//
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	
   [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")] 
 	
	/***********************************************************************
	 * メインクラス
	 * @author okoi
	 */
	public class Main extends Sprite 
	{
		private var pathList:Array = new Array();
		private var jointList:Array = new Array();		//	固定用
		private var jointList2:Array = new Array();

		private var jointList3:Array = new Array();
		
		private var grabid:int = -1;
					
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			addPath( 465/2-20, 465/2-20, pathList );
			addPath( 465/2+20, 465/2-20, pathList );
			addPath( 465/2+20, 465/2+20, pathList );
			addPath( 465 / 2 - 20, 465 / 2 + 20, pathList );
			
			addPath( 465/2-130, 465/2-130, pathList );
			addPath( 465/2-80, 465/2-130, pathList );
			addPath( 465/2-80, 465/2-80, pathList );
			addPath( 465/2-130, 465 / 2 - 80, pathList );			
			
			addPath( 465/2+40, 465/2+40, pathList );
			addPath( 465/2+80, 465/2+40, pathList );
			addPath( 465/2+80, 465/2+80, pathList );
			addPath( 465/2+40, 465 / 2 + 80, pathList );

			
			//	固定用
			addJoint( 0, 1, 0.5, jointList, pathList );
			addJoint( 1, 2, 0.5, jointList, pathList );
//			addJoint( 2, 3, 0.5, jointList, pathList );
//			addJoint( 3, 0, 0.5, jointList, pathList );
			addJoint( 0, 2, 0.5, jointList, pathList );
			addJoint( 1, 3, 0.5, jointList, pathList );

			addJoint( 4, 5, 0.5, jointList2, pathList );
			addJoint( 5, 6, 0.5, jointList2, pathList );
			addJoint( 6, 7, 0.5, jointList2, pathList );
			addJoint( 7, 4, 0.5, jointList2, pathList );
			
			addJoint( 8, 9, 0.5, jointList3, pathList );
			addJoint( 9, 10, 0.5, jointList3, pathList );
			addJoint( 10, 11, 0.5, jointList3, pathList );
			addJoint( 11, 8, 0.5, jointList3, pathList );
			addJoint( 8, 10, 0.5, jointList3, pathList );
			addJoint( 9, 11, 0.5, jointList3, pathList );
						
			addEventListener( Event.ENTER_FRAME, EnterFrame );

			stage.addEventListener(MouseEvent.MOUSE_DOWN, GrabPath );
			stage.addEventListener(MouseEvent.MOUSE_UP, ReleasePath );
			stage.addEventListener(MouseEvent.MOUSE_OUT, ReleasePath );
		}
		
		private function EnterFrame(event:Event) : void {
			
			var i:int = 0;
			var j:PathJoint;
			var path:Path;
			
			//	パスの先頭をマウスと合わせる
			if ( grabid != -1 )
			{				
				pathList[grabid]._x = stage.mouseX;
				pathList[grabid]._y = stage.mouseY;
			}
			
			for each ( path in pathList )	path.Move( 0, 0.1 );
			
			for ( var ct:int = 0; ct < 20; ct ++ )
			{
				//	1
				for ( i = 0; i < jointList.length; i++ )	jointList[i].Calc();
				for ( i = jointList.length - 1; i >= 0; i-- )	jointList[i].Calc();
				//	2
				for ( i = 0; i < jointList2.length; i++ )	jointList2[i].Calc();
				for ( i = jointList2.length - 1; i >= 0; i-- )	jointList2[i].Calc();
				//	3
				for ( i = 0; i < jointList3.length; i++ )	jointList3[i].Calc();
				for ( i = jointList3.length - 1; i >= 0; i-- )	jointList3[i].Calc();
				for each ( path in pathList )	path.Calc(stage);
			}
					
			graphics.clear();
			graphics.beginFill( 0x000000 );
			graphics.drawRect( 0, 0, stage.stageWidth, stage.stageHeight );
			graphics.endFill( );
			
			graphics.lineStyle( 1, 0xFF0000 );
			
			for each( j in jointList ) j.DrawSprite( this );
			for each( j in jointList2 ) j.DrawSprite( this );
			for each( j in jointList3 ) j.DrawSprite( this );
			for each( var p:Path in pathList )
			{
				if ( p._id == grabid )	p.DrawSprite( this, 0xFFFF00 );
				else 					p.DrawSprite( this );
			}
			
			graphics.lineStyle( 1, 0xFFFFFF );
			graphics.moveTo( 0, 400 );
			graphics.lineTo( stage.stageWidth, 400 );
		}
		
		/**
		 * パスを掴んだかどうかの判定を行う
		 * @param	e
		 */
		private function GrabPath(e:MouseEvent):void
		{
			var len:uint = pathList.length;
			var p:Path;
			for ( var i:uint = 0; i < len; i++ )
			{
				p = pathList[i];
				if ( (e.stageX - p._x) * (e.stageX - p._x) + (e.stageY - p._y) * (e.stageY - p._y) < 25 )
				{
					grabid = i;
					return;
				}
			}
		}
		private	function ReleasePath(e:MouseEvent):void 
		{
			grabid = -1;
		}
		
	}	
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Stage;

/**
 * パス追加処理
 * @param	_x
 * @param	_y
 * @param	list
 */
function addPath(_x:Number, _y:Number, list:Array):void 
{
	var id:uint = list.length;
	var path:Path = new Path( id, null, _x, _y );
	list.push( path );
}

/**
 * パスとパスの結合要素を追加
 * @param	start
 * @param	end
 * @param	ratio	startパスに掛かる力
 * @param	jList	結合要素リスト
 * @param	pList	パス要素リスト
 */
function addJoint(start:int, end:int, ratio:Number, jList:Array, pList:Array):void 
{
	jList.push( new PathJoint( null, pList[start], pList[end], ratio ) );
}


/***************************************************************************
 * パスクラス
 */
class Path {
	
	private var _parent:Sprite;
	public var _x:Number;
	public var _y:Number;
	public var _id:int;
	
	public var _prevX:Number;
	public var _prevY:Number;
	public var _moveX:Number = 0;
	public var _moveY:Number = 0;
	
	public	function Path(__id:int,  _p:Sprite, __x:Number, __y:Number) {
		_parent = _parent;
		_prevX = _x = __x;
		_prevY = _y = __y;
		
		_id = __id;
	}
	public	function DrawSprite(_sp:Sprite=null, _col:uint = 0xFF0000):void 
	{
		if ( _sp == null )
		{
			if ( _parent == null ) return;
			_sp = _parent;
		}
		_sp.graphics.lineStyle(3, _col);
		_sp.graphics.drawCircle(_x, _y, 5);
	}
	//	おもに場外判定
	public	function Calc(stage:Stage):void 
	{
		
		if ( _y < 0 )
		{
			_x += (_prevX - _x) * 0.02;
			_y = 0;
			_prevY = 0;
			_moveY = 0;
		}
		if ( _y >= 400 )
		{
			_x += (_prevX - _x) * 0.02;
			_y = 400;
			_prevY = 400;
			_moveY = 0;	
		}
		if ( _x <= 0 )
		{
			_x = 0;
			_prevX = 0;
			_moveX = 0;
		}
		if ( _x >= stage.stageWidth )
		{
			_x = stage.stageWidth;
			_prevX = stage.stageWidth;
			_moveX = 0;
		}
	}
	
	public	function Move(mx:Number, my:Number):void 
	{
		_moveX = (_x - _prevX) + mx;
		_moveY = (_y - _prevY) + my;
		_prevX = _x;
		_prevY = _y;
				
		_x += _moveX;
		_y += _moveY;
	}
	
}
/***************************************************************************
 * パスとパスを繋げるクラス
 */
class PathJoint {
	
	private var _parent:Sprite;
	private var _Start:Path;
	private var _End:Path;
	private var _defLength:Number;
	
	private var _ratio:Number;		//	_Startに掛かる力
	
	public function PathJoint (_p:Sprite, _sp:Path, _ep:Path, _r:Number = 0.5) {
		_parent = _p;
		_Start  = _sp;
		_End 	= _ep;
		_defLength = Math.sqrt( (_ep._x - _sp._x) * (_ep._x - _sp._x) + (_ep._y - _sp._y) * (_ep._y - _sp._y) );
		
		_ratio = _r;
	}
	
	/**
	 * パス間の距離が初期状態と変わっていたら、パスの座標にその差分を増減させて、パス間の距離を一定に保つ
	 */
	public function Calc() : void {
		
		var vecX:Number = _End._x - _Start._x;
		var vecY:Number = _End._y - _Start._y;
		var length:Number = Math.sqrt( vecX * vecX + vecY * vecY );
		//	パスの方向ベクトル(正規化)
		var nx:Number = vecX / length;
		var ny:Number = vecY / length;
		
		if ( _defLength == length )
		{
		}else
		{
			length = _defLength;
			
			nx *= length;
			ny *= length;
			
			//	距離の差分をパスの座標に反映させる
			_Start._x += (vecX - nx) * _ratio;
			_Start._y += (vecY - ny) * _ratio;
			_End._x -= (vecX - nx) * (1-_ratio);
			_End._y -= (vecY - ny) * (1-_ratio);		
		}
	}
	
	public	function DrawSprite(_sp:Sprite):void 
	{
		if ( _sp == null )
		{
			if ( _parent == null ) return;
			_sp = _parent;
		}
		_sp.graphics.lineStyle(3, 0xFF0000);
		_sp.graphics.moveTo(_Start._x, _Start._y);
		_sp.graphics.lineTo(_End._x, _End._y);
	}
	
}