トップページ > Flash入門 > とりあえず(5)
ボールが箱の中で弾む様子を表現します。 これまで確認してきたフレームごとの座標移動と画像の回転を利用して実装します。 物理の要素としては,斜方投射と(非)弾性反射を取り入れています。 今回は全ソースコードのみ示します。
質量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; } } } }