2

私は現在、C# と XNA を使用してゲームを作成しており、トップダウンの観点を除いて、Minecraftに似た一種のブロック機能を実装しました。ブロックの追加は、ブロックとそのベクトルのリストを使用して実装されます (誰かがゲームをロードしようとしたときにすべてのブロックを再追加できるようにするため)。これは問題なく動作していますが、(ゲームに 4 つの新しいブロックを追加した後) 各ブロックを更新すると、膨大な量の遅延が発生することがわかりました。

ブロックのバウンディング ボックスがビューポートの境界内にあるかどうかを確認する関数を実装しました。

for (int b = 0; b < blocklist.Count; b++)
{
    if (view.Contains((int)blocklist[b].blockposition.X, (int)blocklist[b].blockposition.Y))
    {
        blocklist[b].visible = true;
    }
    else
    {
        blocklist[b].visible = false;
    }
}

visibleequalsの場合true、ブロックは描画されますが、それでも少しラグが発生するので、これから更新メソッドを制限できるかどうか疑問に思っていました:

foreach (Builder b in blocklist)
{
    b.Update();
}

これに:

foreach (Builder b in blocklist)
{
    if (b.visible == true)
    {
        b.Update();
    }
}

ブロックが画面上にない場合、これはブロックの更新を無視しますか?

入力とパフォーマンスのヒントをありがとう!

編集:配列のアイデアを実装しようとしていますが、いくつか問題があります

        if (player.Builder == true && player.LMBpressed == true && blockspawnamount >=                                     placeblock && collisionengine.connecting <= 0)
        {
            if (build.BlockID == 1 && menu.open == false)
            {

                position = new Vector2((int)(cursor.cursorPos.X/ 58) * 58, (int)(cursor.cursorPos.Y / 58) * 58);

                blocktex1 = grass1;
                Builder[,] blocks = new Builder[grass1.Width, grass1.Height];
                Builder block = blocks[x,y];

                for (int x = view.Left; x < view.Right; ++x)
                {
                    for (int y = view.Top; y < view.Bottom; ++y)
                    {
                        blocks[x,y].Update();
                    }
                }


                blockpos1.Add(position);


                placeblock = 200.0f;
            }


        }

私が抱えている問題は、ここにあります:

    Builder block = blocks[x,y];

インデックスが配列の範囲外だったと言います。

これがどのように機能するかを説明します。クリックすると、カーソルの位置をブロック テクスチャの幅 (この場合は int 58) で割った位置に設定され、ブロックがリストに追加され、後で描画されます。ブロックの種類を管理する別の Blocks クラスはありませんが、Builder クラスは配置と配置されるブロックの種類の両方を制御します。

ここで質問です。通常リストに追加するように、配列に追加しますか? リストのように描画できますか?

また: Builder クラスがブロックの配置を制御するため、位置変数を削除できません。そうすると、ブロックを配置する位置がなくなります。

4

2 に答える 2

1

構造をリストから2D Array() に変更する必要があります。これはあなたが行っていることにとって理想的であり、リストを使用するよりもパフォーマンスが大幅に向上します。

例えば:

Builder[,] Blocks = new Builder[WIDTH,HEIGHT];

クラスに位置変数は必要ないので、Builder削除できます。

任意のブロックを取得または設定する場合、リストではなくグリッドを使用するようなものなので、特定のブロックを取得するのは非常に簡単です

Builder Block = Blocks[x,y];

これらのブロックを更新または描画するときに、カリングと呼ばれる方法を導入できます。これにより、シーン外にあるオブジェクトが描画/更新されるのを防ぐことができます。

for (int x = left; x < right; ++x)
{
     for (int y = top; y < bottom; ++y)
     {
          Blocks[x,y].Update()
     } 
}

leftこれでright、、、topおよびbottom変数がビューポート/カメラの端になります。カリングせずにこれをテストしたいだけの場合はleft、0 に設定し、右に設定しますBlocks.GetUpperBound(0);(0 は幅、1 は高さ)。

また、何が問題なのかを推測しようとしないでください。プロファイラーを使用して、CPU を食い尽くしているものを見つける必要があります。

あなたを助けるかもしれない私が持っていたいくつかの関連する問題があります。

FPS が低い場合、どのプロファイリング アプリケーションを使用すればよいですか?

タイルで更新ティックを実行する

于 2013-05-29T23:48:28.127 に答える
0

これは、コードのどこかでそのようなフラグを自分で更新した場合にのみ機能します。このフラグを設定するロジックを適用すると、もちろんこれは機能します。そうしないと、そのようなフラグは役に立ちません。コードのプロファイリングを行い、ボトルネックを見つけてください。推測しないでください。

于 2013-05-29T23:44:07.427 に答える