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

code on 2008-12-23

クラス
Get Adobe Flash player
by seiya 23 Dec 2008
package {
	import flash.display.*;
	import flash.text.*;
	import flash.ui.*;
	import flash.utils.*;
	import flash.events.*;
	import flash.net.*;
	import flash.geom.*;
	
	//クラス
	public class VecTest extends Sprite {
		//変数宣言
		private var left	:Boolean = false;
		private var right	:Boolean = false;
		private var up		:Boolean = false;
		private var down	:Boolean = false;
		
		
		private var ball:Sprite;
		private var rad:int = 5;
		private var vx:Number = 0;
		private var vy:Number = 0;
		
		private var fld:Sprite;
		private var lines:Array = new Array();
		
		private var courseData:Array = 
		[
			[100,300,500,300],
			[500,300,200,350],
			[200,350,300,400],
		];
		
		//コンストラクタ
		public function VecTest() {
			//初期化
			
			//ボールの描画
			ball = new Sprite();
			ball.x = 250;
			ball.y = 20;
			ball.graphics.beginFill(0xff0000);
			ball.graphics.drawCircle(0,0,rad);
			ball.graphics.endFill();
			addChild(ball);
			
			//コースの線が乗るSprite
			fld = new Sprite();
			addChild(fld);
			
			//courseDataのデータに沿って線を描画
			var t:Sprite = new Sprite();
			for(var i:int=0; i<courseData.length; i++){
				t.graphics.lineStyle(1,0x0000ff);
				t.graphics.moveTo(courseData[i][0], courseData[i][1]);
				t.graphics.lineTo(courseData[i][2], courseData[i][3]);
			}
			fld.addChild(t);
			
			
			//イベントリスナーの登録
			stage.addEventListener(Event.ENTER_FRAME, EnterFrame);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, KeyUp);
		}
		
		
		
		//フレームごとの処理
		private function EnterFrame(e:Event) : void {
			
			//回転する角度を取得
			var deg:int = 0;
			
			if(left ){ deg += 2; }
			if(right){ deg -= 2; }
			
			//回転が必要なら
			if(deg != 0){
				var pPos:Point = fld.globalToLocal(new Point(275, 200));
				var oPos:Point;		//回転前の座標
				var nPos:Point;		//回転後の座標
				
				// 回転前と回転後のグローバル座標にそれぞれ変換
				oPos = fld.localToGlobal(pPos);	//回転前
				fld.rotation += deg;				//実際に回転させる
				nPos = fld.localToGlobal(pPos);	//回転後
				
				// 回転前と回転後の座標の差を補正
				fld.x += oPos.x - nPos.x;
				fld.y += oPos.y - nPos.y;
			}
			
			
			
			
			
			if(up && vy > 0){
				vy--;
			}
			if(vy < 30){
				vy++;
			}
			
			ball.x += vx;
			ball.y += vy;
			
			if(ball.x < 0 || ball.x > 550){
				vx = -vx;
			}
			if(ball.y < 0 || ball.y > 400){
				vy = -vy;
			}
			
			for(var i:int=0; i<courseData.length; i++){
				calcVecLine(courseData[i]);
			}
		}
		

		//////////////////////////////////////////////////////
		//線(pt1.x, pt1.y),(pt2.x, pt2.y)と交差するか判定する
		//////////////////////////////////////////////////////
		private function calcVecLine( data:Array ):Boolean{
			var flg:Boolean = false;
			var nx:Number;
			var ny:Number;
			var len:Number;
			var ft:Number;
			var fb:Number;
			var cx:Number;
			var cy:Number;
			var sx:Number;
			var sy:Number;
			var t:Number;
			var pt1:Point;
			var pt2:Point;
			var mtx:Matrix;
			var tmp:Array;
			
			//------------------------------------------------------
			//変換行列のデータを取得
			mtx = fld.transform.matrix;
			
			//座標を回転後の座標にしてpt1とpt2に設定
			pt1 = mtx.deltaTransformPoint(new Point(data[0],data[1]));
			pt2 = mtx.deltaTransformPoint(new Point(data[2],data[3]));
			pt1.offset(fld.x,fld.y);
			pt2.offset(fld.x,fld.y);
			
			//------------------------------------------------------
			//線の法線のベクトルを計算して正規化する
			nx  = pt2.y - pt1.y;
			ny  = pt1.x - pt2.x;
			len = Math.sqrt(nx * nx + ny * ny);	//辺の長さを計算
			if(len > 0){ len = 1/len; }
			nx *= len;
			ny *= len;
			
			
			//------------------------------------------------------
			//球が表面へ侵入するときのみ判定をする。
			//ベクトルの内積が負の数の時表面
			fb = nx * vx + ny * vy;
			if(fb <= 0){
				
				//球から面と垂直な線
				sx = -nx * rad;
				sy = -ny * rad;
				
				//-----------------------------------------------------------------
				//玉の半径と移動軌跡の2パターンで調べる
				
				//計算用
				ft  = nx * ball.x + ny * ball.y - (pt1.x * nx + pt1.y * ny);
				tmp = [ [(nx * sx + ny * sy), sx, sy] , [fb, vx, vy] ];
				
				//判定の実行
				for(var i:int=0; i<2 && flg == false; i++){
					
					//倍数(t)が0~1なら交差している
					t = -ft / tmp[i][0];
					if( 0 < t && t <= 1.0 ){
						
						//線と交差する座標を算出
						cx = ball.x + tmp[i][1] * t;
						cy = ball.y + tmp[i][2] * t;
						
						//交差する座標が線分の間か調べる
						//ベクトルの内積が負の数の時は範囲内
						flg = (cx - pt1.x) * (cx - pt2.x) + (cy - pt1.y) * (cy - pt2.y) < 0;
					}
				}
				
				//------------------------------------------------------
				if(flg == true){
					//交差位置に位置修正
					ball.x = (cx + nx * rad);
					ball.y = (cy + ny * rad);
					
					
					//動きを反射させる 反射率 1.0~2.0
					t = - fb / (nx * nx + ny * ny);
					vx += t * nx * 2;
					vy += t * ny * 2;
				}
			}
			return flg;
		}
		
		
		
		//キーが押された時の処理
		private function KeyDown(e:KeyboardEvent) : void {
			switch(e.keyCode){
			case Keyboard.LEFT:
				left = true;
				break;
			case Keyboard.RIGHT:
				right = true;
				break;
			case Keyboard.UP:
				up = true;
				break;
			case Keyboard.DOWN:
				down = true;
				break;
			}
		}
		
		
		//キーが離された時の処理
		private function KeyUp(e:KeyboardEvent) : void {
			switch(e.keyCode){
			case Keyboard.LEFT:
				left = false;
				break;
			case Keyboard.RIGHT:
				right = false;
				break;
			case Keyboard.UP:
				up = false;
				break;
			case Keyboard.DOWN:
				down = false;
				break;
			}
		}
	}
}