第16回 人界剣「悟入幻想 -Easy-」 (3)

今回からボスの攻撃を実装していきます。今回はレーザーを配置してみましょう。

要旨

それではいってみましょう。

レーザーの配置

悟入幻想での攻撃には次の3種類あります。

  1. 一番下に剣戟を放つ。
  2. 剣戟からランダム弾がほぼ真上に放たれる。
  3. ボスから自機狙い 3-way 弾と、逆向き 6-way 弾が放たれる。

先ずは、剣戟から作ってみましょう。右下から左下へ移動するのに合わせて剣戟を放ち、その跡が残ります。その跡は当たり判定を持っています。

剣戟は妖夢独特の攻撃方法なので、東方弾幕風で完全に再現するのは少し面倒です。そこで、設置型レーザーで代用したいと思います。

設置型レーザーを配置するには、CreateLaserA, SetLaserDataA, FireShot の3つの関数を使います。先ず、設置型レーザーの基本的なデータを CreateLaserA に指定します。そして、そのレーザーの動作を SetLaserDataA に指定し、FireShot を実行することで、実際にレーザーを設定します。

少し分かりにくいと思うので、例を見てみましょう。

// レーザーの設置位置
let xLaserBegin = GetClipMaxX + 32;
let xLaserEnd   = GetClipMinX - 32;
let yLaser      = GetClipMaxY - 16;

// 横薙ぎ
sub slash {
    let id    = 0;
    let wMove = 10;
    let wStop = 60 - wMove;
    let span  = (xLaserBegin - xLaserEnd) / wMove;    // レーザーを延ばす間隔

    CreateLaserA(id, xLaserBegin, yLaser, 0, 10, BLUE01, 0);
    SetLaserDataA(id, 0, 180, 0, span, 0, 0);
    SetLaserDataA(id, wMove, NULL, 0, 0, 0, 0);
    FireShot(id);

    SetMovePosition02(xSlash, ySlash, wMove);
    setGraphicMove;
    wait(wMove);
    wait(wStop);
}

では、順番に見ていきましょう。

先ずは CreateLaserA を使った部分です。

let id    = 0;
CreateLaserA(id, xLaserBegin, yLaser, 0, 10, BLUE01, 0);

CreateLaserA の引数は次のようになっています。

CreateLaserA(id, x, y, length, width, type, delay);
    // id     : ID
    // x      : 設置位置の x 座標
    // y      : 設置位置の y 座標
    // length : レーザーの初期長
    // width  : レーザーの幅
    // type   : グラフィックタイプ
    // delay  : 遅延時間(レーザーが実体化するまでの時間)

この中で、殆どの引数の意味は分かると思います。ただ、1つだけ分かりにくいものがあります。それは ID です。設置型レーザーを置くには、色々と動作を指定する必要があります。しかし、それは1つの関数で完結させるには無理があります。そこで、東方弾幕風では何度か何種類かの関数を呼ぶことにより、動作を指定するようになっています。一連の設定が同じレーザーに対して行われることを表すために、ID を使用します。ID は自分で自由に決めることのできる数値です。ここで指定した ID を使って SetLaserDataAFireShot を実行します。すると、ここで行われた設定や発射指定は、その ID を使って作られたレーザーに対してのみ行われます。ID を使うことにより、一度に複数のレーザーの設定を行うことが可能になります。

では、その設定をしている部分を見てみましょう。先ずはこれです。

let span  = (xLaserBegin - xLaserEnd) / wMove;
SetLaserDataA(id, 0, 180, 0, span, 0, 0);

SetLaserDataA の引数は次のようになっています。

SetLaserDataA(id, frame, angle, w, vLen, v, vAngle);
    // id     : CreateLaserA で指定した ID
    // frame  : この動作変化を開始するフレーム(FireShot 後の経過フレーム)
    // angle  : 角度(NULL を指定することで現在の値を引き継ぐ)
    // w      : 角速度(1 フレームあたりの角度変化量)
    // vLen   : 長さの変化速度(1 フレームあたりの長さの変化量)
    // v      : 設置点移動速度(1 フレームあたりの設置点移動量)
    // vAngle : 設置点移動方向
図 1. SetLaserDataA の引数
図 1. SetLaserDataA の引数

上から順に見ていきましょう。

id には、さっき話した ID を指定します。1つのレーザーに対し、いくつもの設定を行うことができますが、この一連の設定が同一のレーザーに対するものであることを保障するには、それら全ての設定において同一の ID を使用します。同時に2つのレーザーの設定を行いたい場合は、それらで ID を変えておき、設定したいレーザーの ID を id に指定して、SetLaserDataA を呼びます。

frame はこの設定が有効になるフレームの番号を指定します。レーザーを設置してから、ここに指定したフレーム数が経過したら、ここに指定した設定が有効になります。何個かの動作を設定した場合、それぞれのフレーム番号に達するごとに、それぞれの設定が有効になります。必ず frame0 を指定した設定が必要になります。これは初期設定に相当します。

angle には、レーザーの角度を指定します。設置点から、ここに指定した方向へとレーザーが伸びます。

w には、角速度を指定します。毎フレーム、設置点を中心としてここに指定しただけ角度が変化します。

vLen には、レーザーの長さの変化速度を指定します。毎フレーム、ここに指定しただけレーザーの長さが変化します。

v には、レーザーの設置点の移動速度を指定します。毎フレーム、ここに指定しただけ設置点が移動します。その移動方向は vAngle に指定します。

以上を踏まえて、もう一度設定を見てみましょう。

SetLaserDataA(id, 0, 180, 0, span, 0, 0);

この設定の意味は次のようになります。「設置後 0 フレーム目(すぐ)、180 度(真左)の方向にレーザーを出します。角度も設置点も変化させませんが、レーザーが毎フレーム span だけ伸びます」

で、さらに次のように設定しています。

SetLaserDataA(id, wMove, NULL, 0, 0, 0, 0);

ここでは角度の指定が何やら NULL というものになっています。角度の部分に NULL を指定した場合は、角度を設定しません。つまり、前のフレームでの角度をそのまま継承します。

以上より、「設置後 wMove フレーム目に、角度も長さも設置点も何もかも変化させないようにします」という意味になります。

両方の設定をまとめると、右下にレーザーを設置して、左下までレーザーを伸ばすという設定になります。ボスの動きに合わせてレーザーを伸ばしてはいますが、一瞬のことなので厳密に位置を合わせてはいません。

以上のように設定を行うだけではレーザーは設置されません。FireShot を実行して初めてレーザーが設置されます。

FireShot(id);

SetLaserDataA で設定したフレーム数は、この FireShot が実行されてからのフレーム数になります。

以上をまとめたプログラムをここに置いておきます。実際に実行してみて、レーザーが設置されることを確認してみてください。

要旨

次回はいよいよ弾を撃たせてみましょう。次回でスペルは完成です。

第15回 | 第17回 | 目次へ戻る

この講座はロベールが作成しました。
inserted by FC2 system