シューティングゲームの基本となる弾について学習しましょう。
等速で直進する基本の弾です。_rotationの角度にspeedの距離ずつ直進します。
onClipEvent (load) { var speed = 5;// 移動速度
var x=_x;// 次x座標
var y=_y;// 次y座標
_rotation=90;// ↓向き
} onClipEvent (enterFrame) {// 等速直進弾
// _rotationの角度にspeedだけ進む
x += speed*Math.cos(_rotation/180*Math.PI); y += speed*Math.sin(_rotation/180*Math.PI); _x=x; _y=y;// 移動
}
初期設定で変数speedの値を決め、クリップイベントループを使って移動します。speedの値は フレームレートと合わせて調整します。
次の位置を変数x,yに一度代入しているのは、画面端の処理などで変更する場合に備えてのことです。
_rotationの値は下方向(90度)に初期化していますが、他の方向にする場合には、 弾を画面に配置した後に設定します(後述)。自機狙い弾は、自機の方向を指定します。
加速していく弾です。等速直進弾のspeedの値を徐々に増やします。
onClipEvent (load) { var speed = 5;// 移動速度
var d_speed = 0.5;
// 加速度
var max_speed = 20;
// 最大速度
var x=_x;// 次x座標
var y=_y;// 次y座標
_rotation=90;// ↓向き
} onClipEvent (enterFrame) {// 加速直進弾
// _rotationの角度にspeedだけ進む
x += speed*Math.cos(_rotation/180*Math.PI); y += speed*Math.sin(_rotation/180*Math.PI); _x=x; _y=y;// 移動
speed+=d_speed;
// 加速
speed=Math.min(speed, max_speed);
//速度を上限に抑える
}
速度があまり早くなると、自機を通り抜けてしまうことがあります。
自機の方向に軌道を変えながら進む弾です。一定間隔で_rotationを自機方向に変化させながら移動します。
onClipEvent (load) { var speed = 5;// 移動速度
var x=_x;// 次x座標
var y=_y;// 次y座標
_rotation=90;// ↓向き
var count = 0;
// カウンタ
var max_count=10;
// カウンタ上限
} onClipEvent (enterFrame) {// 誘導弾
if (count == max_count) {
// カウンタ上限に達したら
_rotation=Math.atan2(_parent.jiki_mc._y-_y, _parent.jiki_mc._x-_x)*180/Math.PI;
// 自機方向
count = 0; } count++;
// _rotationの角度にspeedだけ進む
x += speed*Math.cos(_rotation/180*Math.PI); y += speed*Math.sin(_rotation/180*Math.PI); _x=x; _y=y;// 移動
}
あまり頻繁に角度を変えると追尾がきつくなるので、一定間隔になるように、変数countの値を1ずつふやしてmax_countの値 を等しくなったときに変えることにしています。
この誘導弾は、自機方向に角度を変更できるため、永遠に追いかけてきます。これでは 避けるのが大変なので、角度変更に制限を付けるのが一般的です。
誘導弾の角度変更に制限をつけます。
onClipEvent (load) { var speed = 5;// 移動速度
var x=_x;// 次x座標
var y=_y;// 次y座標
_rotation=90;// ↓向き
var count = 0;// カウンタ
var max_count=10;// カウンタ上限
var old_r=_rotation;
// 前角度
var d_r=0;
// 回転角度
var max_d_r=20;
// 最大回転角度
} onClipEvent (enterFrame) {// 回転角度制限付き誘導弾
if (count == max_count) {// カウンタ上限に達したら
old_r=_rotation;
// 前角度保持
_rotation=Math.atan2(_parent.jiki_mc._y-_y, _parent.jiki_mc._x-_x)*180/Math.PI;// 自機方向
d_r=(_rotation-old_r+180)%360-180;
count = 0; } count++;// 回転角度-180〜180になるように補正
d_r=Math.min( max_d_r,d_r);// 最大回転角度制限
d_r=Math.max(-max_d_r,d_r);// 最小回転角度制限
_rotation=old_r+d_r;// _rotationの角度にspeedだけ進む
x += speed*Math.cos(_rotation/180*Math.PI); y += speed*Math.sin(_rotation/180*Math.PI); _x=x; _y=y;// 移動
}
弾を射出するプログラムを考えます。
準備としてjiki_mcと元となる上記の弾をb1_mc〜b4_mcなどでステージ上に作成しておきます。
フレーム1に以下のフレームアクションを設定します。ここでは、関数addBullet()を定義しているだけです。
n=0; // 弾数 function addBullet(type, x, y, r) {// type:種類, x:x座標, y:y座標, r:角度
_root["b"+type+"_mc"].duplicateMovieClip("b"+n, 1000+n);// b[type]_mcをb[n]という名前で深度1000+nに複製
_root["b"+n]._x=x;// x座標
_root["b"+n]._y=y;// y座標
_root["b"+n]._rotation=r;// 角度
n++; }
砲のムービークリップを作成し、ムービークリップアクションを設定します。
on(release) {
_root.addBullet(1, _x, _y, 90); // 下向き弾射出
}
クリックするとb1_mcの弾を下向きに射出します。typeの数字を変えれば異なる弾が射出されます。
on(release) {
_root.addBullet(1, _x, _y, Math.atan2(_parent.jiki_mc._y-_y, _parent.jiki_mc._x-_x)*180/Math.PI); // 自機狙い弾射出
}
クリックするとb1_mcの弾を自機方向に射出します。typeの数字を変えれば異なる弾が射出されます。
on(release) {
for (var i=0; i<12; i++) {
_root.addBullet(1, _x, _y, i*30); // 全方位弾射出
}
}
クリックするとb1_mcの弾を12方向に射出します。typeの数字を変えれば異なる弾が射出されます。
i*30をi*30+15に変えると角度をずらした弾になります。
i*30をi*30+Math.atan2(_parent.jiki_mc._y-_y, _parent.jiki_mc._x-_x)*180/Math.PIにすると、自機狙いになります。
上記例はクリックしたら射出するようになっていますが、ムービークリップのタイムラインのフレームアクションで 関数addBullet()を呼び出すことで、射出タイミングを設定することも可能です。
Programming Laboratory (Shio seminar)