シューティングゲームの基本となる弾について学習しましょう。
等速で直進する基本の弾です。_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; // 回転角度-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;
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; // 移動
}
弾を射出するプログラムを考えます。
準備として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)