トップページ > 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;
}
}
}
}