Flashゲーム講座 & アクションスクリプトサンプル集



移動量と角度から x と y 方向の移動量を求める

 
 




向きと移動量がわかっているときに、x軸方向の移動量とy軸方向の移動量に振り分けたいときの計算です。 これを利用するとどの方向にも一定の距離を移動する事ができます。









これを三角関数を用いてx方向とy方向に分けます。
 




 
x軸方向移動量を求める

	x軸方向移動量 = cos( 角度 ) * 距離


y軸方向移動量を求める

	y軸方向移動量 = sin( 角度 ) * 距離
 
これをアクションスクリプトで記述すると以下のようになります。
 
x軸方向移動量を求める

	x軸方向移動量 = Math.cos( 角度 * Math.PI / 180 ) * 距離


y軸方向移動量を求める

	y軸方向移動量 = Math.sin( 角度 * Math.PI / 180 ) * 距離
 
Math.cos()メソッドとMath.sin()メソッドを用いるとsin と cos が求まります。ただし、このメソッドの引数にはラジアンを指定する必要があります。 ラジアンとは0~2πの間で角度を表す単位です。







角度からラジアン、ラジアンから角度へ変換するには下の式を用いると実現できます。
 
角度からラジアンに変換する

	ラジアン =  角度 * Math.PI / 180;


ラジアンから角度に変換する

	角度 =  ラジアン * 180 / Math.PI;
 
では、これを使って作れるサンプルを紹介します。
 
 
車の動き
サンプルをダウンロード
 

 
車を例にします。
車には向きとスピードの2つのパラメータがあり、その値でx軸方向の移動量とy軸方向の移動量に変換しています。
 
車の移動

onClipEvent (load) {
	speed = 0;	// 移動量
	rot = -90;	// 向き(注.右向きを0とする)
	dx = 0;		// x方向移動量
	dy = 0;		// y方向移動量
}
onClipEvent (enterFrame) {
	
	// 上を押したとき
	if(Key.isDown(Key.UP))	speed ++;
	// 下を押したとき
	if(Key.isDown(Key.DOWN))	speed --;
	// 左を押したとき
	if(Key.isDown(Key.LEFT))	rot --;
	// 右を押したとき
	if(Key.isDown(Key.RIGHT))	rot ++;

	// 移動量を求める
	dx = Math.cos(rot * Math.PI / 180) * speed;	
	dy = Math.sin(rot * Math.PI / 180) * speed;

	// 摩擦
	speed *= 0.9;

	// 座標更新
	_x += dx;
	_y += dy;
	_rotation = rot;


	// 画面ループ
	if(_x < 0)	_x = 400;
	if(_x > 400)	_x = 0;
	if(_y < 0)	_y = 300;
	if(_y > 300)	_y = 0;
}

 
どの方向にも一定の速度で移動するキャラクター
サンプルをダウンロード
 

 
上下左右に5ずつ移動するキャラクターがいます。

このキャラクターが右上に動くとき上に5、右に5ずつ移動すると直線距離では、5√2になり斜めに移動すると少し早く移動できてしまいます。

そこで、三角関数を使って斜めの場合は直線距離を5として上と右の移動量を求めます。
 
キャラクターの移動

onClipEvent (load) {
	rot = 0;
	speed = 0;
	_root.AnimePlay(0);	
}
onClipEvent (enterFrame) {
	// 左上を押したとき
	if (Key.isDown(Key.UP) && Key.isDown(Key.LEFT)) {
		rot = 215;
		speed = 2;
		_root.AnimePlay(1);
	// 左下を押したとき
	} else if (Key.isDown(Key.DOWN) && Key.isDown(Key.LEFT)) {
		rot = 135;
		speed = 2;
		_root.AnimePlay(0);
	// 右上を押したとき
	} else if (Key.isDown(Key.UP)  && Key.isDown(Key.RIGHT)) {
		rot = 315;
		speed = 2;
		_root.AnimePlay(1);
	// 右下を押したとき
	} else if (Key.isDown(Key.DOWN) && Key.isDown(Key.RIGHT)) {
		rot = 45;
		speed = 2;
		_root.AnimePlay(0);
	// 上を押したとき
	} else if (Key.isDown(Key.UP)) {
		rot = 270;
		speed = 2;
		_root.AnimePlay(1);
	// 下を押したとき
	} else if (Key.isDown(Key.DOWN)) {
		rot = 90;
		speed = 2;
		_root.AnimePlay(0);
	// 左を押したとき
	} else if (Key.isDown(Key.LEFT)) {
		rot = 180;
		speed = 2;
		_root.AnimePlay(2);
	// 右を押したとき
	} else if (Key.isDown(Key.RIGHT)) {
		rot = 0;
		speed = 2;
		_root.AnimePlay(3);
	// 何も押さなかったとき
	}else{
		speed = 0;		
	}

	// 移動量を求める
	dx = Math.cos(rot * Math.PI / 180) * speed;	
	dy = Math.sin(rot * Math.PI / 180) * speed;

	_x += dx;
	_y += dy;


	// 画面ループ
	if(_x < 0)	_x = 400;
	if(_x > 400)	_x = 0;
	if(_y < 0)	_y = 300;
	if(_y > 300)	_y = 0;

}
AnimePlay()
自作関数。引数に番号を指定するとその番号に用意されたアニメを再生。

 
砲台の制御
サンプルをダウンロード
 

 
砲台を例にします。

砲台には"向き""スピード"の2つのパラメータがあり、その値でx軸方向の移動量とy軸方向の初期移動量を求めます。

また、"砲台の向き""回転軸から砲台の発射口までの長さ"から初期位置を求めます。

 
砲台管理

onClipEvent (load) {
    rot = 0;
    speed = 3;
}
onClipEvent (enterFrame) {
    if(Key.isDown(Key.UP))		rot --;
    if(Key.isDown(Key.DOWN))	rot ++;
    if(Key.isDown(Key.LEFT))	speed -= 0.2;
    if(Key.isDown(Key.RIGHT))	speed += 0.2;

    // リミッタ
    if(rot > 0)		rot = 0;
    if(rot < -90)		rot = -90;
    if( speed < 1 )	speed = 1;
    if( speed > 8 )	speed = 8;

    if(Key.isDown(Key.SPACE) && push == 0){
    
        order = new Object();
	
	// 初期座標
        order.x = _x + Math.cos( rot * Math.PI / 180 ) * 30;
        order.y = _y + Math.sin( rot * Math.PI / 180 ) * 30;
	
	// 移動量
        order.dx = Math.cos( rot * Math.PI / 180 ) * speed;
        order.dy = Math.sin( rot * Math.PI / 180 ) * speed;
	
	// 砲弾作成
        _root.GunCreate(order);
	
    }
    push = Key.isDown(Key.SPACE);


    // 砲台回転
    _rotation = rot;

    // 砲弾処理	
    _root.GunExective();
}
GunCreate()
自作関数。弾をひとつ生成する。引数にオブジェクト形式でステータスを入れる。

GunExective()
自作関数。弾の処理をまとめて記述している。

 
 




2つの座標から角度を求める

 

サンプルをダウンロード
 



 
マウスポインタを向く矢印
 
 
自分の座標を(my_x ,my_y )とします。
相手の座標を(target_x ,target_y)とします。

自分から見て相手はどの角度にいるかを計算します。
 
2点でできる線の角度を求める

	rad = Math.atan2(target_y - my_y,target_x - my_x);
	_rotation = rad * 180 / Math.PI;
 
rad = Math.atan2(相手のy座標 - 自分のy座標, 相手のx座標 - 自分のx座標);
角度 = rad * 180 / Math.PI;

 




x方向とy方向の移動量から角度を求める

 

サンプルをダウンロード
 



 
自分の移動量を(spd_x ,spd_y )とします。
移動量からどの角度に進んでいるかを計算します。
 
x方向とy方向の値から角度を求める

	rad = Math.atan2(spd_y, spd_x);
	_rotation = rad * 180 / Math.PI;
 
rad = Math.atan2(y移動量, x移動量);
角度 = rad * 180 / Math.PI;