【发布时间】:2016-05-06 13:32:59
【问题描述】:
我有一个 2D 瓷砖矩阵(现在是墙),对于每面墙,我检查我的玩家是否是下一个 Rectangle(下一个,如 下一帧中的位置) 正在与那堵墙发生碰撞,如果是,我希望我的玩家站在它旁边,而不是进入它。
这是我想出的公式(这只是左右碰撞):
//*move entity
if (KState.Down(Keys.W)) en.AddForce(new Vector2(0, -10));
if (KState.Down(Keys.S)) en.AddForce(new Vector2(0, 10));
if (KState.Down(Keys.A)) en.AddForce(new Vector2(-10, 0));
if (KState.Down(Keys.D)) en.AddForce(new Vector2(10, 0));
foreach(Item i in map.Items)
{
//resolve left-right collision
if (en.NextBody(elapsedTime).Intersects(i.Body))
{
//check distance between top left corners
int distance = (int)Math.Abs(i.Position.X - en.Position.X);
//stop player in his horisontal movement
en.AddForce(new Vector2(-en.Force.X, 0));
//place player next to the wall his about to collide with
en.Position = new Vector2(en.Position.X - distance + i.Body.Width, en.Position.Y);
}
}
//stop player in place
if (KState.Clicked(Keys.Space)) en.AddForce(en.Force*-1);
en.Update(elapsedTime);
**
这给了我这个结果(请注意,fps 不稳定,目前的矩形是 32x32 的正方形):
第一行文字是玩家Rectangle,下一行是玩家最后撞墙的Rectangle。
现在,岩石(玩家)向左移动时,我按住左键一段时间,向右移动时,我按住右键一段时间。
问题:正如你在 gif 中看到的,当玩家向左走时,他在左墙之间移动了 1 个像素。当他向右移动时,他会弹起一次,然后就停留在右边的墙壁旁边。我不想要任何弹跳,但我不知道如何在我正在使用的逻辑中解决这个问题。
另外,如果您知道如何解决 Rectangle 冲突的良好逻辑,以便它们不会从任何方面相交,我会很乐意与我分享。
编辑 1: 我设法解决了正确问题的冲突。而不是上面我放的代码
int sign = Math.Sign(i.Position.X - en.Position.X);
en.AddForce(new Vector2(-en.Force.X, 0));
//wall is right and player is left
if (sign > 0) en.Position = new Vector2(i.Body.Left - en.Body.Width, en.Position.Y);
//wall is left and player is right
if (sign < 0) en.Position = new Vector2(i.Body.Right, en.Position.Y);
但是左侧碰撞的问题是一样的。我试过 if (sign < 0) en.Position = new Vector2(i.Body.Right + 1, en.Position.Y); 和 if (sign < 0) en.Position = new Vector2(i.Body.Right - 1, en.Position.Y); 以防万一,但问题是一样的(在“...-1...”情况下玩家卡在墙上)。
编辑 2: 按照@paste 的要求,这里是播放器类中NextBody(float elapsedTime) 的代码。
public Rectangle NextBody(float elapsedTime)
{ return new Rectangle((int)(force.X * elapsedTime) + body.X, (int)(force.Y * elapsedTime) + body.Y, body.Width, body.Height); }
【问题讨论】:
-
你有
en.SetForce()方法吗?当从当前力中减去“相等”的量时,可能会出现一些精度问题,从而使残余力仍在en对象中。这可以通过调用en.SetForce(Vector2.Zero)来解决 -
猜对了,但我查了一下,确实是 0。
-
您可以发布您的
NextBody()代码吗? -
整个项目中是否还有其他地方调用了
AddForce()或更改了Position属性? -
是的。在级别构造函数中。位置已设置,但该函数仅触发一次。这是一个很好的观察,但我知道我为什么发布这个问题。我正在系统地逐部分创建,所以我知道在尝试某些东西时使用了什么代码。 +1 良好观察
标签: xna 2d physics monogame rectangles