トップページ > Flash入門 > とりあえず(5)

ボールがバウンドするFlash

座標移動+回転を組み合わせて,簡単な物理モデルを再現してみます

ボールが箱の中で弾む様子を表現します。 これまで確認してきたフレームごとの座標移動と画像の回転を利用して実装します。 物理の要素としては,斜方投射と(非)弾性反射を取り入れています。 今回は全ソースコードのみ示します。

全ソースコード: ボールが箱の中でバウンド

質量massや初期速度v_xとv_y,反射居数refの値を変更させると動きが変化します。 srcディレクトリには,表示用画像(今回は“ClearBall_pink.png”という名前)を入れておく必要があります。

//************************************************************************
//2012/03/05
//ボールが箱の中でバウンド (斜方投射+反射)
//Programmed by Koten-Kairoya
//************************************************************************

package
{
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.Event;
 
    //画面サイズと背景色,フレームレートを設定
    [SWF(width="300", height="300", frameRate = "60", backgroundColor="0xffffcc")]  
 
    /**
     * ...
     * @author NB
     */
 
     public class Main extends Sprite 
    {   
        //画像ファイルを読み込む
        [Embed(source = "./ClearBall_pink.png")]
        public var ballImg:Class;
        //"ball"をクラス変数として定義
        public var ball:Bitmap = new ballImg();
		
        //画像回転に使うダミーのスプライト,名前は"sp"とする
        public var sp:Sprite = new Sprite();

        //================================================================
        //重力加速度
		public var g:Number = 9.8;		
		//ballの質量(任意)
		public var mass:Number = 0.01;
		//x,y方向の初期速度(任意)
		public var v_x:Number = 3.0;
		public var v_y:Number = 0.0;
		//反射係数(任意)
		public var ref:Number = 0.99;
		//各境界(上下左右の壁)の座標
		public var stage_top:int = ball.height / 2;
		public var stage_bottom:int = 300 - ball.height / 2;
		public var stage_left:int = ball.width / 2;
		public var stage_right:int = 300 - ball.width / 2;
        //================================================================

		
        //main関数
        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
 
            //フレームごとの処理をイベントリスナへ登録
            this.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);       
             
            //"sp"の座標は,"ball"を表示させたい位置+ballの中心までの距離
            sp.x = ball.width / 2;
            sp.y =  ball.height / 2;
             
            //"sp"を画面に表示
            addChild(sp);
             
            //"ball"の中心が"sp"の原点になるようにする
            //座標の指定は親オブジェクトであるspからの相対距離
            ball.x = -ball.width/2;
            ball.y = -ball.height / 2;
             
            //"ball"を"sp"の上へ貼りつける
            sp.addChild(ball);
        }
 
        //各フレームごとに呼ばれる関数
        private function onEnterFrame(e:Event):void
        {
			//左端にぶつかった時
			if (sp.x < stage_left)
			{
				//バウンド後の速さ=反射係数*現在の速さ,向きは反対向き
				v_x = -ref * v_x;
				//壁に食い込まないように,座標を左端にする
				sp.x = stage_left
			}
			
			//右端にぶつかった時
			if (sp.x > stage_right)
			{
				//バウンド後の速さ=反射係数*現在の速さ,向きは反対向き				
				v_x = -ref * v_x;
				//座標を右端にする
				sp.x = stage_right;
			}
			
			//天井にぶつかった時
			if (sp.y < stage_top)
			{
				//バウンド後の速さ=反射係数*現在の速さ,向きは反対向き
				v_y = -ref * v_y;
				//座標を床の位置に戻す
				sp.y = stage_top
			}
			
			//床にぶつかった時
			if (sp.y > stage_bottom)
			{
				//バウンド後の速さ=反射係数*現在の速さ,向きは反対向き
				v_y = -ref * v_y;
				//座標は天井の位置に戻す
				sp.y = stage_bottom;
			}
		
			//以下,座標を進める処理。
			//x方向は,フレーム更新ごとにv_xずつ座標を加算すれば等速運動
			sp.x += v_x;
			//y方向は加速度運動なので,まずv_yをmgだけ増加させ,そのv_yだけ座標を進める
			v_y += mass * g;
			sp.y += v_y
			
            //以下,回転させる処理(その上に貼りついている"ball"も回転する)
            //回転方向は進行方向に合わせる
			if (v_x > 0)
			{
				sp.rotation += 1.5;
			}
			if (v_x < 0)
			{
				sp.rotation -= 1.5;
			}
        }
    }
}



前へ  次へ