C# XNA/Monogame:平台跳跃物理和对撞机问题

C# XNA/Monogame:平台跳跃物理和对撞机问题,c#,xna,2d,game-physics,monogame,C#,Xna,2d,Game Physics,Monogame,我有一个精灵,播放器。我通过以下方式更新玩家的位置: \u位置+=(\u方向*\u速度)*(float)gameTime.ElapsedGameTime.TotalSeconds 其中\u位置,\u方向和\u速度是矢量2s 我有一个简单的碰撞器(BoxCollider),它根据碰撞器的位置和尺寸生成一个矩形(BoundingBox) 在Initialize()中,我创建了一个新的列表,并用该级别的碰撞器填充它 在Update()上,我将列表传递给Player以检查冲突 碰撞检查方法: publi

我有一个精灵,
播放器
。我通过以下方式更新玩家的位置:

\u位置+=(\u方向*\u速度)*(float)gameTime.ElapsedGameTime.TotalSeconds

其中
\u位置
\u方向
\u速度
矢量2
s

我有一个简单的碰撞器(
BoxCollider
),它根据碰撞器的位置和尺寸生成一个矩形(
BoundingBox

Initialize()
中,我创建了一个新的
列表
,并用该级别的碰撞器填充它

Update()
上,我将列表传递给
Player
以检查冲突

碰撞检查方法:

public void CheckPlatformCollision(List<BoxCollider> colliders, GameTime gameTime)
{
    var nextPosition = _position + (_direction * _velocity) * (float)gameTime.ElapsedGameTime.TotalSeconds;
    Rectangle playerCollider = new Rectangle((int)nextPosition.X, (int)nextPosition.Y, BoundingBox.Width, BoundingBox.Height);
    foreach(BoxCollider collider in colliders)
    {
        if(playerCollider.Intersects(collider.BoundingBox))
        {
            nextPosition = _position;
        }
    }
    Position = nextPosition;
}
public void CheckPlatformCollision(列出碰撞器,游戏时间)
{
var nextPosition=_位置+(_方向*_速度)*(浮点)gameTime.ElapsedGameTime.TotalSeconds;
矩形播放集合=新矩形((int)nextPosition.X,(int)nextPosition.Y,BoundingBox.Width,BoundingBox.Height);
foreach(碰撞器中的BoxCollider碰撞器)
{
if(playerCollider.Intersects(collider.BoundingBox))
{
下一个位置=_位置;
}
}
位置=下一个位置;
}
现在,我试图实现重力的每一种方法都失败了。如果
Player
从太高的位置落下,
nextPosition
Player
太远,使其卡在半空中

我也遇到了水平碰撞的问题,问题是类似的:
Player
停得太快了,在两者之间留下了一个空间。有时我让
播放器
站在对撞机的一侧

我想知道的是:


如何正确使用
\u位置
\u方向
,以及
\u速度
?如何正确处理水平和垂直碰撞?

对于重力,请在更新
\u位置之前添加此项:

_velocity += gravity * (float)gameTime.ElapsedGameTime.TotalSeconds;
其中
gravity
类似于
newvector2(0,10)


对于跳跃,当玩家按下跳跃按钮时,需要设置速度的垂直分量:

if (jumpPressed && jumpAvailable)
{
    _velocity.Y = -10; // Numbers are example. You need to adjust this
    jumpAvailable = false;
}
当玩家触地时,您需要重置
jumpAvailable


碰撞是一件非常复杂的事情。但是如果你在互联网上寻找“XNA工具冲突”,你会找到很多答案

有很多方法。其中之一是将玩家推回boxcollider的边界,而不是像代码中那样不让他移动。守则是:

if (IntersectsFromTop(playerCollider, collider.BoundingBox))
{
    _position.Y = collider.BoundingBox.Y - BoundingBox.Height;
}
else if (IntersectsFromRight(playerCollider, collider.BoundingBox))
{
    _position.X = collider.BoundingBox.X + collider.BoundingBox.Width;
}
// And so on...
助手方法的实现方式如下:

private static bool IntersectsFromTop(Rectange player, Rectangle target)
{
    var intersection = Rectangle.Intersect(player, target);
    return player.Intersects(target) && intersection.Y == target.Y && intersection.Width >= intersection.Height;
}

private static bool IntersectsFromRight(Rectange player, Rectangle target)
{
    var intersection = Rectangle.Intersect(player, target);
    return player.Intersects(target) && intersection.X + intersection.Width == target.X + target.Width && intersection.Width <= intersection.Height;
}
// And so on...
private static bool intersects fromtop(矩形播放器,矩形目标)
{
var intersection=Rectangle.Intersect(玩家、目标);
返回player.Intersects(target)和&intersection.Y==target.Y和&intersection.Width>=intersection.Height;
}
私有静态布尔交叉自右(矩形玩家,矩形目标)
{
var intersection=Rectangle.Intersect(玩家、目标);
返回player.Intersects(target)&&intersection.X+intersection.Width==target.X+target.Width&&intersection.Width这可能会帮助您: