0

XNA で pacman クローンを作成しています。ここまで2D配列を使ってタイルマップを描き、別の2D配列を使って丸薬を追加し、pacmanが動く2D配列を作りました。

実際のゲームでは、上に移動しながら右を押すと、右に移動してターンするまで待機します。

spritePosition % 32 = 16 の場合にのみターンを許可するシステムを配置しています。これは、スプライトが壁の間の中央に配置されることを意味します。

最後に押されたキーを記憶するか、回転する前に正しい位置に移動するプログラムが必要ですが、それを行う方法が見つかりません。これは、私が試していることをカバーするコードの一部です。

public void MovementCheck()
        {
            presentKey = Keyboard.GetState();
            spritePosition = spriteVelocity + spritePosition;
            pacManRec = new Rectangle((int)spritePosition.X,     (int)spritePosition.Y, pacManTex.Width, pacManTex.Height);
            spriteOrigin = new Vector2(pacManRec.Width / 2, pacManRec.Height / 2);

        //Press Right
        if (presentKey.IsKeyDown(Keys.Right) && pastKey.IsKeyUp(Keys.Right))
        {

            Right();
        }
}

private void Right()
        {
            direction = "right"; 
//if the next block in tile map to the right is a 1, and the sprite is centred - allow a turn
            if (inputMap[(int)Math.Floor(spritePosition.Y / 32), (int)Math.Floor(spritePosition.X / 32) + 1] == 1 && (spritePosition.Y % 32 == 16))
            {
                rotation = ((float)Math.PI / 180);
                spriteVelocity.X = 0;
                spriteVelocity.Y = 0;
                spriteVelocity.X = movementSpeed;
            }
        }

右のキーのみが表示され、他のキーも同様ですが、方向がすべて変更され、それに応じてタイル マップへのチェックが変更されます。(ここのXに+1)

私は次のようなことを試しました

while (spritePosition.Y % 32 != 16)
{ spritePosition = spriteVelocity + spritePosition; }

しかし、それはスプライトを画面上に飛ばすだけです (ちょっと明らかに) :(

そして、Right() 呼び出しの前に新しいメソッドを試しました

bool RightCheck()
{
    if ( CONDITIONS MET HERE )
    return true
    else
    { 
      //dont remember if I used this line, but something similar
      spritePosition = spriteVelocity + spritePosition;
      RightCheck()
    }
    return false; //allows program to build
 }

ただ a は無限再帰を引き起こします。

4

1 に答える 1

0

1 つの解決策は、フレーム/時間ステップごとにint counter = 0;( を使用して) ゲームループで更新する を追加することです。counter++;有効な入力を行い、その入力を保存するたびに 0 に設定します。

アウトライン化されたコード:

public class GameClassWhereUpdateIsDone
{
    private enum Directions { None, Up, Down, Left, Right };

    private int counter = 0;
    private Directions currentDirection; // Current movement-direction
    private Directions lastInput; // Last direction from input

    public void Update(...)
    {
       var keyboardState = Keyboard.GetState();
       if(keyboardState.IsKeyPressed(Keys.Right))
       {
           counter = 0;
           direction = Directions.Right;
       }

       if(currentDirection != lastInput && counter < 5) // Allow turning 5 updates ahead.
       {
           // Player want to turn
           if(AllowedToTurn(lastInput)
           {
                currentDirection = lastInput;
           }
       }

       MoveDirection(currentDirection);

       counter++;
    }

    private bool AllowedToTurn(Directions direction)
    {
       if(direction == Directions.Right)
       {
           return RightCheck();
       }
    }
}

重要なアイデアは、入力された移動方向と最後の方向を追跡することです...

オリジナルのパックマンでは「プレターニング」が実際に使用されてました。興味深い読み物です。

于 2015-02-25T12:21:54.973 に答える