第21回 波符「赤眼催眠マインドシェイカー」 Easy (3)

前回でスペルは完成しましたが、もう少しだけ手を加えてみたいと思います。

要旨

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

条件ループ

前回の弾用タスク TMagicShot をもう一度見てみましょう。

task TMagicShot(x, y, v, angle, type, right) {
    let obj = Obj_Create(OBJ_SHOT);
    let dx;
    let dy  = 0.2;

    if(right) { dx = 0.25; } else { dx = -0.25; }

    Obj_SetX(obj, x);
    Obj_SetY(obj, y);
    Obj_SetAngle(obj, angle);
    ObjShot_SetGraphic(obj, type);

    loop {
        if(Obj_BeDeleted(obj)) { break; }

        Obj_SetSpeed(obj, v);
        Obj_SetAlpha(obj, 255);
        Obj_SetCollisionToPlayer(obj, true);

        loop {
            if(onPhantasm) { break; }
            yield;
        }

        Obj_SetSpeed(obj, 0);
        Obj_SetAlpha(obj, 128);
        Obj_SetCollisionToPlayer(obj, false);

        loop {
            if(! onPhantasm) { break; }
            Obj_SetX(obj, Obj_GetX(obj) + dx);
            Obj_SetY(obj, Obj_GetY(obj) + dy);
            yield;
        }
    }
}

ループの部分に注目してください。

loop {
    if(Obj_BeDeleted(obj)) { break; }
loop {
    if(onPhantasm) { break; }
loop {
    if(! onPhantasm) { break; }

全部同じ形になっていますね。全て、ある条件が満たされるまでループを行っているのです。このような処理は非常によく行われるので、実はもっと簡単に書けるようになっています。それには、while というものを使います。while を使うと、それぞれ次のようになります。

while(! Obj_BeDeleted(obj)) {
while(! onPhantasm) {
while(onPhantasm) {

見て分かるとおり、while条件が満たされている間ループする命令です。「条件が満たされるまで」ではなく「条件が満たされている間」なので、while を使わなかったときと条件が逆になっている点に注意して下さい。

while を使ったプログラムをここに置いておきます。while を使うとプログラムが少しすっきりし、意味も分かりやすくなると思います。

背景の停止とモーションブラー

本物のスペルでは、幻視状態の時に背景の変化速度が若干低下します。これを実装するには、第18回で話した @BackGround を使って自前で背景を制御する必要があります。ですが、背景の動きを止めるのは簡単なので、背景を止めるように変更してみましょう。

背景を止めるには、TimeStop という関数を使います。正確には、以下のように背景以外のものも止めることができます。

TimeStop(frame, player, shot, bg);
    // frame  : 動きを止めるフレーム数
    // player : 自機を止めるかどうか
    // shot   : 弾を止めるかどうか(自機の弾も止まります)
    // bg     : 背景を止めるかどうか

ここで注意が必要です。ここには truefalse を指定するのではなく、10 を指定します1 を指定すれば止まって、0 を指定すれば止まりません。

例えば背景のみを 100 フレーム止めるには、

TimeStop(100, 0, 0, 1);

とします。

また、幻視状態の時には弾が半透明になるだけではなく、少しぼやけます。ぼやける、という処理を行うのは難しいので、ここでは残像を残すことでぼやける感じを出したいと思います。

残像を残すには、MotionBlurMotionBlurEx という関数を使います。

MotionBlur(target, frame, intensity);
    // target    : 残像を残す対象
    //             ALL  / 全てのものに残像を残す
    //             SHOT / 弾のみに残像を残す
    // frame     : 残像を残すフレーム数
    // intensity : 残像の強度(0〜255)
MotionBlurEx(target, frame, intensity, type);
    // type : 残像のタイプ
    //        ALPHA / αブレンド
    //        ADD   / 加算ブレンド

残像の表示方法にはαブレンドと加算ブレンドの2種類があります。αブレンドというのは後ろのものとある比率で混ぜ合わせる方法で、Obj_SetAlpha で半透明にするのと同じ方法です。加算ブレンドは後ろのものに色を加える形で混ぜ合わせる方法です。MotionBlur では加算ブレンドを行います。一般に、加算ブレンドは白く光りがちになり、αブレンドはもっと柔らかくぼやける感じになります。今回はαブレンドの方がしっくりくるのでαブレンドにしますが、αブレンドの方が低速です。

以上の変更を加えると、phantasm は次のようになります。

// 幻視
sub phantasm {
    let wStop = 100;

    onPhantasm = true;

    TimeStop(wStop, 0, 0, 1);
    MotionBlurEx(SHOT, wStop, 128, ALPHA);
    wait(wStop);

    onPhantasm = false;
}

以上の変更を加えたプログラムをここに置いておきます。これで随分それっぽくなったと思います。さらに後ろに狂気の目を表示したりするとそれっぽくなると思いますが、そこまでやるのはやめておきます。

要旨

これで終わりかと思いきや、次回ももう1点変更を行いたいと思います。

第20回 | 第22回 | 目次へ戻る

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