code on 2008-12-23 クラス seiya forked:2favorite:1lines:163license : All rights reserved modified : 2008-12-23 15:35:17 Embed Tweet 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; } } } } Code Fullscreen Preview Fullscreen tenchiwang2 : fungame fun game len data left right deltaTransformPoint localToGlobal Keyboard.DOWN Keyboard.UP Keyboard.RIGHT Keyboard.LEFT Boolean globalToLocal keyCode KeyboardEvent rotation KeyboardEvent.KEY_UP KeyboardEvent.KEY_DOWN addEventListener offset drawCircle sort new page view favorite forked pv0 forked from: code on 2008-12-2.. seiya forked:0 favorite:0lines:163 (diff:1) pv0 forked from: code on 2008-12-2.. seiya forked:0 favorite:0lines:163 (diff:2)