0

XNA を使用して単純な 2D タイル ベースの RPG ゲームを作成しています。各タイルの四角形を含む Tile オブジェクトのリストを使用して、単純なタイル マップを作成しました。プレーヤーの動きの更新では、最初に次のフレームでプレーヤーを表す四角形を作成します。次に、foreach ループを実行して、タイル リスト内のすべてのタイルがプレーヤーの四角形と交差するかどうかを確認します。もしそうなら、衝突ブール値をtrueに設定し、プレイヤーが衝突するであろうタイルも記憶します。

プレイヤーが衝突する場合、プレイヤーがタイルに入る前にタイルに触れるようにプレイヤーの位置を設定します。私が抱えている問題は、タイルの壁に対して「スライド」できないことです。たとえば、下と左に同時に移動すると、タイルにヒットするとすぐに、左に移動し続けるとプレイヤーが動けなくなります。どのように動いても正しく動作するようにメソッドを改善する方法はありますか?

public void MovementUpdate(KeyboardState ks, GameTime time, List<Tile> tlist)
    {
        Direction = Vector2.Zero;
        Rectangle nextPosRec;

        if (ks.IsKeyDown(Keys.Right)){
            Direction.X = MOVE_RIGHT;
        }

        if (ks.IsKeyDown(Keys.Down))
        {
            Direction.Y = MOVE_DOWN;
        }

        if (ks.IsKeyDown(Keys.Up))
        {
            Direction.Y = MOVE_UP;
        }

        if (ks.IsKeyDown(Keys.Left)){
            Direction.X = MOVE_LEFT;
        }

        Vector2 nextPos = Position ;
        nextPos += Direction * Speed * (float)time.ElapsedGameTime.TotalSeconds;
        nextPosRec = new Rectangle((int)nextPos.X, (int)nextPos.Y, 32, 32);

        bool colide = false;
        Tile ctile = new Tile(playerTexture, Position, 0);

        foreach (Tile t in tlist)
        {
            if (t.tileRectangle.Intersects(nextPosRec))
            {
                colide = true;
                ctile = t;
            }
        }

        if (colide == false)
        {
            Position = nextPos;
        }
        else
        {
            if (Position.Y < ctile.tileRectangle.Top - 32)
            {
                //COLLIDE TOP
                Position.Y = ctile.tileRectangle.Top - 32;
            }

            if(Position.Y > ctile.tileRectangle.Bottom)
            {
                //COLLIDE BOTTOM
                Position.Y = ctile.tileRectangle.Bottom;
            }

            if (Position.X < ctile.tileRectangle.Left - 32)
            {
                //COLLIDE LEFT
                Position.X = ctile.tileRectangle.Left - 32;
            }

            if (Position.X > ctile.tileRectangle.Right)
            {
                //COLLIDE RIGHT
                Position.X = ctile.tileRectangle.Right;
            }

        }

    }

手伝ってくれてありがとう!

4

1 に答える 1

0

衝突ロジックにはいくつかの欠陥があります。

  • 複数の衝突を無視し、1つだけを処理しています(との衝突ctile
  • 衝突方向のロジックが正しくありません。交差点があったかどうかはチェックしますが、タイルのどの境界線が交差したかはチェックしません。これが、貼り付け動作の原因です。

衝突処理は、現在行っている最後のタイルだけでなく、交差するタイルごとに実行する必要があります。衝突処理では、オブジェクトがx軸とy軸で衝突したタイルに侵入した量だけオブジェクトを戻すことができます。

また、実際にタイルマップ(タイルのグリッド)を使用している場合、すべてのタイルを反復処理するのは非常に非効率的です。移動しているオブジェクトと交差するタイルを計算するだけです。

于 2012-12-19T14:00:11.247 に答える