読者です 読者をやめる 読者になる 読者になる

Thunderbeam/muraduki長文欄

むらづきのブログ(三代目)

Wisplisp Heehaw(と、偏差射撃再び)

ひじきを投げるSTG(WispLisp)が大変な事になってて面白かったです。
難しいは難しいのですが、小さくまとまってるので頑張れる。
白羊の強化によって、反撃弾の反動が重要な要素になった気がしました。
改めて最初のWispLispから見てみたら妙な感慨が。
WispLisp()WispLisp+WispLisp++Wisplisp Heehaw
で、先読み攻撃繋がりで、先日の偏差射撃について。
あのソースには色々間違いがあった事が判明しましたので訂正情報です。
というか改めて書き直しです。書かないと理屈を忘れるので…。



偏差射撃については色々考えてたのですが、思いついた方法の基本的な理屈は
「敵の座標、自機の座標、弾速、自機のx速度、自機のy速度より、
敵から敵弾の距離と、敵から自機の距離が同じになる地点に撃つ」

というものです(移動範囲についてはとりあえず無視)。
それをどうにかGameMakerでそれっぽく再現した形が
「変数fに一定数ずつ数を足していって、
弾速*f > fフレーム後の敵と自機の距離
になったら、fフレーム後の自機の位置に撃つ」

というものです。

{
    f = 0;
    while (s < p)
    {
        f += 1;
        p = point_distance(x,y,Player.x + (f *Player.hspeed),Player.y + (f * Player.vspeed));
        s = argument0 * f;
    }
}

それに、ゼロ距離時の対策を加えたらこうなりました。

{
    f = 270;
    p = point_distance(x,y,Player.x,Player.y);
    s = 0;

    if (p != s)
    {
        f = 0;
        while (s < p)
        {
            f += 1;
            p = point_distance(x,y,Player.x + (f *Player.hspeed),Player.y + (f * Player.vspeed));
            s = argument0 * f;
        }
    }
}

で、これが前に書いた式になるのは
「fをもっと細かくしたら精度が上がるだろう。
しかしいきなり細かい数字で計算すると処理落ちするので、
大きい数字で一度出してピッタリでなかったら、
一つ戻して細かい数字で再計算してみよう。」

という発想です。
前回の間違い1:「if (frac(f) != 0)」。要するにfの小数点の数字が0かどうかを見てるのですが…
これが成り立たなかったらピッタリでない、って、どんな発想だか今となっては分からない。
前回の間違い2:そもそもそんな精度が要るのか。試しに、単純に上の式のfを細かくして実験。
結果、「自機の当たり判定<自機の移動量」な状況でないとあまり意味がないっぽい。
さらに、別の方法で精度が上げられると判明。

{
    f = 270;
    p = point_distance(x,y,Player.x,Player.y);
    s = 0;

    if (p != s)
    {
        f = 0;
        while (s < p)
        {
            f += 1;
            p = point_distance(x,y,Player.x + (f *Player.hspeed),Player.y + (f * Player.vspeed));
            s = argument0 * f;
        }
        f1 = abs((argument0 * f) - point_distance(x,y,Player.x + (f *Player.hspeed),Player.y + (f * Player.vspeed)));
        f -= 1;
        f0 = abs((argument0 * f) - point_distance(x,y,Player.x + (f *Player.hspeed),Player.y + (f * Player.vspeed)));
        if (f1 < f0){f += 1;}
    }
}

「弾速*f > fフレーム後の敵と自機の距離」が成立したフレームと、その前のフレームで、
「弾速*f」と「fフレーム後の敵と自機の距離」の差が小さい方を採用する。という話。
これでfを小さくすればさらに精度は上がります。
とりあえず今回はこれで終り…一行で求められそうな気もするんだけど、うー…。
というわけで、続く。