我有一个精灵,Player
。我通过以下方式更新Player
的位置:
_position += (_direction * _velocity) * (float)gameTime.ElapsedGameTime.TotalSeconds;
_position
,_direction
和_velocity
为Vector2
的位置。
我有一个简单的对撞机(BoxCollider
),它根据对撞机的位置和尺寸生成一个矩形(BoundingBox
)。
在Initialize()
中,我创建了一个新的List<BoxCollider>
,并用该级别的碰撞器填充它。
在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;
}
现在,我尝试实施重力的每一种方式都失败了。如果Player
从过高的位置掉落,nextPosition
会离Player
太远而使其停留在半空中。
我也遇到水平碰撞问题,问题类似:Player
过早停止,两者之间留有空格。有时候我Player
会碰到对手的一侧。
我想知道的是:
如何正确实施重力&amp;与_position
,_direction
和_velocity
一起跳跃?如何正确处理水平和垂直碰撞?
答案 0 :(得分:1)
对于重力,请在更新_position
之前添加此内容:
_velocity += gravity * (float)gameTime.ElapsedGameTime.TotalSeconds;
其中gravity
类似于new Vector2(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...
该代码背后的基本原理可用图片解释:
在该图片中,width
和height
对应于交叉点,为紫色。