0

この質問はよく聞かれるかもしれませんが、申し訳ありません。しかし、しばらくの間、ゲームでの衝突に問題がありました。助けが必要です。

まず、このゲームは 2D プラットフォーマーです。各ソリッドはリストに入れられます。私はかなりうまく機能する衝突検出のためのこのコードを持っています:

                  if (player.rectangle.Intersects(rect))
                        {
                            player1Collision = true;
                            colSolid = solid;
                            colRectangle = rect;
                        }


                        if (player1Collision)
                        {
                            Vector2 pos = player.position;
                            Vector2 pLeft = new Vector2(player.BoundingBox.Left, 0);
                            Vector2 pRight = new Vector2(player.BoundingBox.Right, 0);
                            Vector2 pTop = new Vector2(0, player.BoundingBox.Top);
                            Vector2 pBottom = new Vector2(0, player.BoundingBox.Bottom);

                            Vector2 sLeft = new Vector2(colSolid.BoundingBox.Left, 0);
                            Vector2 sRight = new Vector2(colSolid.BoundingBox.Right, 0);
                            Vector2 sTop = new Vector2(0, colSolid.BoundingBox.Top);
                            Vector2 sBottom = new Vector2(0, colSolid.BoundingBox.Bottom);

                            if (player.rectangle.Intersects(colRectangle))
                            {
                                if (player.velocity.X > 0 && Vector2.Distance(pRight, sLeft) < player.texture.Width / 2)//left
                                {
                                    player.velocity.X = 0f;
                                    pos.X = colSolid.BoundingBox.Left - player.BoundingBox.Width;

                                }
                                else if (player.velocity.X < 0 && Vector2.Distance(pLeft, sRight) < player.texture.Width / 2)//right
                                {
                                    player.velocity.X = 0f;
                                    pos.X = colSolid.BoundingBox.Right;
                                }

                                if (player.velocity.Y > 0 && Vector2.Distance(pBottom, sTop) < player.texture.Height/ 2) //top
                                {
                                    player.velocity.Y = 0f;
                                    player.gravityOn = false;                        
                                    pos.Y = colSolid.BoundingBox.Top - player.BoundingBox.Height;

                                }
                                else if (player.velocity.Y < 0 && Vector2.Distance(pTop, sBottom) < player.texture.Height / 2)//bottom
                                {
                                    player.velocity.Y = 0f;
                                    pos.Y = colSolid.BoundingBox.Bottom;

                                }
                                player.position = pos;
                            }
                            else
                            {
                                player.gravitySpeed = 0.15f;
                                player.gravityOn = true;
                            }

                        }

ただし、問題は、プレーヤーが長方形と交差していない場合、重力をオンに設定しているため、ソリッドと衝突すると継続的に落下し、衝突しないように上に置かれることです。私が知る必要があるのは、どうすればこれを回避できるかということだけです。プレイヤーが連続して固体に向かって落下することなく、再び落下するために固体の上に戻されるだけで、重力をオンに設定できる他の方法はありますか?

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

4

1 に答える 1

0

この問題に対処する方法は最適ではないかもしれません (実際、おそらくそうではないことは確かです) が、これまでのすべての 2D プラットフォーム プロジェクトでうまくいきました。

まず、スプライト クラスの 2 つ目の四角形を定義します。この長方形は、メインのバウンディング ボックスと同じ幅と X 座標を持ちますが、わずかに高くなります (私の場合は 2 または 3)。説明するために、両方の長方形の下端がインラインになるようにオフセットする必要もあります。

Rectangle boundingRect = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
Rectangle gravityRect = new Rectangle((int)boundingRect.X, (int)boundingRect.Y - 3, texture.Width, texture.Height + 3); 

スプライト クラスには、プレイヤーが落下するかどうかを追跡するための bool も必要です。そして、それがしっかりしているかどうかを追跡するためのものです(初期化中に、明らかに必要に応じて割り当てます)。

public bool isGrounded = false;
bool isSolid;

Game1 クラスの先頭で、2 つの int を宣言します。

int gravityTotalI = 0;
int gravityCounterI = 0;

スプライトを初期化するときは、通常、それらすべてをリストに追加します。私がこれを行うことができるように:

foreach (Sprite s in spriteList)
{
    if (s.isSolid)
    {
        gravityTotalI++;
    }
}

ここで、Game1 Update メソッドで次のロジックを使用します。

foreach (Sprite s in spriteList)
{
    if (!s.Equals(player)
    {
        if (player.boundingRect.Intersects(s.boundingRect) || player.boundingRect.Intersects(s.gravityRect))
        {
            player.isGrounded = true;
            gravityCounterI = 0;
        }
        else
        {
            gravCounterI++;
            if (gravCounterI >= gravTotalI)
            {
                 player.isGrounded = false;
                 gravCounterI = 0;
            }
        }

       if (player.boundingRect.Intersects(s.boundingRect))
        {
            player.position.Y -= 2f; //set the resistance of the platform here
        }
    }
} //end of foreach loop.
if (!player.isGrounded)
{
    player.position.Y += 2f; //set the force of gravity here.
}

まともな方向性衝突エンジンを構築することは別のことですが、この手法は基本を処理します (そして、その地獄のバウンスを取り除きます)。

これが長すぎない/重要なことを見逃していないことを願っています.それが役立つことを本当に願っています.

これを処理するための他の人のテクニックを見るのを楽しみにしています!

于 2013-08-19T02:28:06.070 に答える