2

作成中のゲームでマップセグメント(クラスター)を保持するためにジャグ配列を使用しています。配列内の位置は、マップ内のクラスターの位置に対応しています。さらに、内側の配列(ギザギザの部分)にクラスターがロードされていない場合(クラスターは未使用のタイムアウト後に配列から削除されます)、外側の配列のその要素はnullに戻され、マップのメモリ使用量が維持されます。下。

ゲームがマップからクラスターを取得しようとすると、問題は一見ランダムに発生します。

public Cluster getCluster(int xIndex, int yIndex)
{
    lock (xAxis)
    {
        loadCluster(xIndex, yIndex);
        return xAxis[xIndex][yIndex];
    }
}

public void loadCluster(int xIndex, int yIndex)
{
    lock (xAxis)
    {
        if (xAxis[xIndex] == null)
            xAxis[xIndex] = new Cluster[(int)worldSize.Y];
        if (xAxis[xIndex][yIndex] == null)
            xAxis[xIndex][yIndex] = new Cluster(this, new Vector2(xIndex * 256, yIndex * 256), worldLoader.loadClusterData(xIndex, yIndex));
    }
}

メソッドは、クラスターが配列を取得する前に、ほとんどの場合、loadCluster(int, int)クラスターが配列にロードされていることを確認する必要がありますが、クラスターの追加に失敗することがあります。getCluster(int, int)loadCluster(int, int)

特定のクラスターでは発生しないようですが、内部アレイが追加されていない場合は常に発生します(ただし、ほとんどの場合、問題なく内部アレイが作成されます)。loadCluster(int, int)また、Visual Studioが後続のnullポインター例外をキャッチすると、ステップバックして常に(少なくともこれまでのところ)再呼び出しが通常どおりに機能します。loadCluster(int, int)メソッドにに呼び出しを追加するとgetCluster(int, int)、このバグの頻度も大幅に減少します。

正直なところ、このかなり単純な関数が、一見ランダムにさえ機能しない原因が何であるのかわかりません。どんな助けでも大歓迎です

編集:xAxis[][]を編集する他のコード

public override void Update(GameTime gameTime)
{
    for (int x = 0; x < worldSize.X; x++)
    {
        if (xAxis[x] == null) continue;
        int loaded = 0;
        for (int y = 0; y < worldSize.Y; y++)
        {
            if (xAxis[x][y] == null)
            {
                continue;
            }
            xAxis[x][y].Update(gameTime);

            if (xAxis[x][y].clusterLoaded)
            {
                loaded++;
            }
            else if (xAxis[x][y].clusterTimer == 0)
            {
                xAxis[x][y] = null;
            }
        }

        if(loaded == 0) xAxis[x] = null;
    }
}

Cluster.clusterLoadedクラスターが現在使用されているかどうかを示すブール値です。 は、 falseになるとCluster.clusterTimerカウントダウンするintです。再び真になるとclusterLoaded最大値にリセットされます。falseの 場合、実行するclusterLoadedたびに1ずつ減少します。現在の内部配列にロードされているクラスターの数をカウントするために使用されます。Cluster.Update(GameTime)clusterLoadedloaded

4

1 に答える 1

3

ここで最初に変更することは、xAxis[xIndex][yIndex] 値を直接返すように loadCluster メソッドを変更することです。その場合、getCluster メソッドでロックする必要はありません。コードの他のセクションについてはどうですか-説明から、マルチスレッドの問題のようです。xAxis 変数をロックしましたが、他に何をしているのかわかりません。もう 1 点 - 言語の配列は実際にはコア機能であるため、そこにバグがあるとは予想外です (Microsoft のことです)。

于 2012-08-16T22:13:35.120 に答える