コードスペランカー

ゲーム開発日誌など

ってなわけで、ソートをすることにしたわけだが

DXライブラリの癖の続き
ソートが必要になったので、適当にソートしてみることにした。
手始めに、Listを新たに作って、挿入していく形式だ。当然ながらむちゃくちゃ遅かった。Listは挿入可能だが、元が配列なだけに、むちゃくちゃ遅い、要素数が増えるとさらに遅い。60fps目標で50もやると処理落ちしてくる。駄目だこりゃ。
そーいや、挿入せんでも入れ替えれば良いんじゃないか?って思い出したので、バブルソートを実装してみた

// バブルソート
for (int i = 0; i < (_cara.Count - 1); i++)
{
    float kyori = GameFunctions.PointFromPointUnSqur(_cam.Position, _cara[i].Location.VECTOR);
    for (int j = i + 1; j < _cara.Count; j++)
    {
        if (kyori < GameFunctions.PointFromPointUnSqur(_cam.Position, _cara[j].Location.VECTOR))
        {
            Character.ICaractor temp = _cara[i];
            _cara[i] = _cara[j];
            _cara[j] = temp;
            kyori = GameFunctions.PointFromPointUnSqur(_cam.Position, _cara[j].Location.VECTOR);
        }
    }
}

って感じで適当実装。 GameFunctions.PointFromPointUnSqurは距離を測る関数。2点間の距離を測って総当りでソートしてるわけだ。一番最初の適当ソートより格段に早く1フレームに250要素をソートできた。すごいぜバブルソート
で、バブルソートを実装したところで、250のオブジェクトで足りるか?ってな疑問にぶち当たる。最近の弾幕シューティングなら1000個なんて当たり前のご時勢だ。しかもソートにそれだけのリソースを割くと、他の処理が出来なくなるというおまけ付だ。
で、学生のころもっと早いソート方法やったよな〜って感じで、クイックソートという単語を思い出してみる。クイックっていうぐらいなので、とっても早かったはずだ。やり方はGoogle先生に聞けばよい。こことかこことか、ここを参考にしてみた。

private void qsort(int start, int end)
{
    if ((end - start) <= 0)
    {
        return;
    }
    int left = start;
    int right = end;
    int split = -1;
    Character.ICaractor temp;
    float target = GameFunctions.PointFromPointUnSqur(_cam.Position, _cara[(start + end)/2].Location.VECTOR);
            
    while (split == -1)
    {
        while (target < GameFunctions.PointFromPointUnSqur(_cam.Position, _cara[left].Location.VECTOR))
        {
            left += 1;
            if (left == right)
            {
                split = left;
                break;
            }
        }
        while (target >= GameFunctions.PointFromPointUnSqur(_cam.Position, _cara[right].Location.VECTOR))
        {
            right -= 1;
            if (left == right)
            {
                split = left;
                break;
            }
        }
        if (split != -1) break;
        temp = _cara[left];
        _cara[left] = _cara[right];
        _cara[right] = temp;
    }
    if (left == end) return;
    if (right == start) return;
    if (split == -1) return;
    qsort(start, split - 1);
    qsort(split, end);
}

ってかんじで、これまた適当実装。やってみると1800個ぐらいは処理可能と段違いの性能を見せ付ける。これならソートに200〜300ぐらい分のリソースを割いてもゲームが出来そうだ。