14

ここにいくつかの背景があります。「崩壊」に似たゲームに取り組んでいます。ブロックは一番下でいっぱいになり、12 個のブロックすべてがいっぱいになると、プレイフィールドに押し上げられます。(intNextSpawn) というカウンターがあります。これは、次の行をいつ「押し上げる」かを通知するだけでなく、グラフィックスのベクトルを計算します。ブロックが押し上げられると 0 にリセットされます。

画面にデバッグ テキストを追加して、何が起こっているのかを確認しましたが、問題を突き止めることができないようです。表示されるはずのブロックをランダム化しようとしている間、まだカウンターをインクリメントしているように見えます(順番が狂っています)。私は最終的に「空白の」ブロックを取得し、テスト中にいくつかの非常に厄介な効果を引き起こします. 速度をジャッキアップすると悪化します。

役立つ可能性のある追加のコードを投稿したいと思います。以下は、これが発生する可能性のある 2 つの主要なブロックです。私が間違っている可能性がありますか、またはこれが起こらないようにする方法があるかもしれません (それがそうである場合)?

どんな助けでも大歓迎です。

編集...最初のコードブロックは「更新」メソッドにあります

// Calculate time between spawning bricks
float spawnTick = fltSpawnSpeed * fltSpawnSpeedModifier;

fltSpawn += elapsed;

if (fltSpawn > spawnTick)
{
    // Fetch a new random block.
    poNextLayer[intNextSpawn] = RandomSpawn();
    // Increment counter
    intNextSpawn++;

    // Max index reached
    if (intNextSpawn == 12)
    {
        // Push the line up. Returns true if lines go over the top.
        if (PushLine())
        {
            gmStateNew = GameState.GameOver;
            gmStateOld = GameState.Playing;
        }

        // Game still in play.
        else
        {
            // Reset spawn row to empty bricks.
            for (int i = 0; i < 12; i++)
                poNextLayer[i] = new PlayObject(ObjectType.Brick, PlayColor.Neutral, Vector2.Zero);

            intNextSpawn = 0;   // Reset spawn counter.
            intLines--;         // One less line to go...
         }
     }

     fltSpawn -= spawnTick;
}

private bool PushLine()
{
    // Go through the playfield top down.
    for (int y = 14; y >= 0; y--)
    {
        // and left to right
        for (int x = 0; x < 12; x++)
        {
            // Top row contains an active block (GameOver)
            if ((y == 14) && (poPlayField[x, y].Active))
                // Stop here
                return true;
            else
            {
                // Not bottom row
                if (y > 0)
                {
                    // Copy from block below
                    poPlayField[x, y] = poPlayField[x, y - 1];
                    // Move drawing position up 32px
                    poPlayField[x, y].MoveUp();
                }
                // Bottom row
                else
                {
                    // Copy from spawning row
                    poPlayField[x, y] = poNextLayer[x];
                    // Move drawing position up 32px (plus 4 more)
                    poPlayField[x, y].MoveUp(4);
                    // Make the block active (clickable)
                    poPlayField[x, y].Active = true;
                }
            }

        }
    }

    // Game still in play.
    return false;
}
4

1 に答える 1

1

したがって、問題の最大の部分は、ティックのサイズに基づいていくつかのタイマーを減らしてから、いくつかの比較を実行していることです。タイマーに対してすべてのことを行うのではなく(特に丸めや浮動小数点数の精度の低下など)、代わりに時間ベースの比較だけを行います。

fltSpawn += elapsedたとえば、後で行うとfltSpawn -= spawnTick、浮動小数点の丸め/精度エラーが発生します。

このようなことをもっと試してください:

int64 spawnDelay = 1000000; // 10,000 ticks per ms, so this is 100ms
...

if (DateTime.Now() > nextSpawn)
{
    // Fetch a new random block.
    poNextLayer[intNextSpawn] = RandomSpawn();
    ...

    // At some point set the next spawn time
    nextSpawn += new TimeSpan(spawnDelay * spawnSpeedModifier);

}
于 2013-03-07T23:37:50.843 に答える