シューティングゲームにおける狙い撃ち弾
前回のコラムで二点間の距離を取得する関数を紹介しましたが、それを使用する例も紹介しましょう。
シューティングゲームで敵(ex, ey)が自機(mx, my)を狙って弾を発射するとします。
1/60フレームで動作し5回の移動で自機まで到達する速度を考えると、以下のような式が導かれます。
// 1/60フレームごとの変位
vx = (mx - ex) / 5;
vy = (my - ey) / 5;
ただこの計算には問題点があります。
この計算だと敵と自機の距離によって変位量が変わってしまいます。
遠ければ速く、近ければ遅いということになります。
通常のシューティングゲームの弾は、一定の速度で自機に対して飛んでくるはずです。
では一定の速度で弾を飛ばすにはどうすればよいのかというと、回数ではなく距離で割ればOKです。
二点間の距離で示した通り、距離はXとYの関数となっていますので、距離で割れば変位量は一定に保たれるからです。
サンプルプログラムを用意しました。
サンプル※要FlashPlayer
数字の部分は弾の速度レベルです。1~9が入力できます。
キーで右下の自機が移動できます。
ソースコード
// 初期化
if (!flg_init) {
// 弾を生成
_root.attachMovie("bullet", "tama", 1);
tama._x = teki._x;
tama._y = teki._y;
// 自機と敵との距離を計測
var d:Number = GetDistancePointToPoint(jiki._x, jiki._y, teki._x, teki._y);
// 弾スピード初期設定
var sp:Number = 1;
var jsp:Number;
// 速度を設定
var vx:Number = (jiki._x - teki._x) / d * sp;
var vy:Number = (jiki._y - teki._y) / d * sp;
// 初期化フラグオン
flg_init = true;
}
// 弾が画面内になければ生成
if (tama._x < 0 || tama._x > 300 || tama._y < 0 || tama._y > 300) {
// 弾を削除
tama.removeMovieClip();
// 弾を生成
_root.attachMovie("bullet", "tama", 1);
tama._x = teki._x;
tama._y = teki._y;
// 自機と敵との距離を再計測
d = GetDistancePointToPoint(jiki._x, jiki._y, teki._x, teki._y);
// 速度を設定
vx = (jiki._x - teki._x) / d * sp;
vy = (jiki._y - teki._y) / d * sp;
}
else {
// 入力文字が0~9なら再設定
jsp = parseInt(speed.text, 10);
if (jsp > 0 && jsp < 10 && !isNaN(jsp)) {
sp = jsp;
}
tama._x += vx;
tama._y += vy;
}
// 距離計算関数
function GetDistancePointToPoint(p1_x:Number, p1_y:Number, p2_x:Number, p2_y:Number) : Number
{
// X
var x:Number = Math.pow((p1_x - p2_x), 2);
// Y
var y:Number = Math.pow((p1_y - p2_y), 2);
// 距離計算
return Math.sqrt(x + y);
}