XNA二维平台碰撞与重力

XNA二维平台碰撞与重力,xna,collision,gravity,Xna,Collision,Gravity,我知道这个问题可能会被问很多,为此我很抱歉。但是我有一段时间在比赛中遇到碰撞的问题,我想得到一些帮助 首先,游戏是一个2D平台。每个实体都放在一个列表中。我有一个碰撞检测代码,对我来说非常有用: if (player.rectangle.Intersects(rect)) { player1Collision = true;

我知道这个问题可能会被问很多,为此我很抱歉。但是我有一段时间在比赛中遇到碰撞的问题,我想得到一些帮助

首先,游戏是一个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;
                            }

                        }
if(player.rectangle.Intersects(rect))
{
player1Collision=true;
colSolid=固体;
colRectangle=rect;
}
如果(播放者1集合)
{
矢量2位置=播放器位置;
Vector2 pLeft=新的Vector2(player.BoundingBox.Left,0);
Vector2 pRight=新的Vector2(player.BoundingBox.Right,0);
vector2ptop=newvector2(0,player.BoundingBox.Top);
vector2pbottom=新的Vector2(0,player.BoundingBox.Bottom);
Vector2 sLeft=新的Vector2(colSolid.BoundingBox.Left,0);
Vector2 sRight=新的Vector2(colSolid.BoundingBox.Right,0);
Vector2停止=新Vector2(0,colSolid.BoundingBox.Top);
Vector2 sBottom=新的Vector2(0,colSolid.BoundingBox.Bottom);
if(player.rectangle.Intersects(colRectangle))
{
如果(player.velocity.X>0&&Vector2.Distance(pRight,sLeft)0&&Vector2.Distance(pbotom,sTop)
然而,问题是,如果玩家没有与矩形相交,我将重力设置为on,因此当他与实体碰撞时,他会持续下落,然后被放在顶部以避免与实体碰撞。我需要知道的是:我怎样才能避免这种情况?有没有其他方法可以让我在不让玩家持续朝着固体下落的情况下,将重力设置为on,而让玩家再次回到固体顶部下落


非常感谢您的帮助。

我解决这个问题的方法可能不是最优的(事实上我相信可能不是),但到目前为止,它在我所有的2D平台项目中都对我有效

我首先为sprite类定义第二个矩形。这个矩形的宽度和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来记录玩家是否应该摔倒。还有一个用来跟踪它是否是实心的(在初始化过程中,您显然会根据需要指定)

在Game1类的顶部,我声明了2个整数:

int gravityTotalI = 0;
int gravityCounterI = 0;
初始化精灵时,我通常会将它们全部添加到列表中。这样我就可以做到:

foreach (Sprite s in spriteList)
{
    if (s.isSolid)
    {
        gravityTotalI++;
    }
}
现在,我在Game1更新方法中使用了以下逻辑:

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.
}
构建一个像样的方向碰撞引擎是另一回事,但这项技术将处理基本问题(并消除地狱般的反弹)

希望这不是太冗长/不要错过任何重要的东西,我真的希望它能有所帮助-我与你一样的问题挣扎了很长一段时间,我知道这是多么令人沮丧


我期待着看到其他人处理这个问题的技巧

这个问题可能更适合我们的情况。如果要我将此标记为迁移,请告诉我。
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.
}