XNA 2D对象碰撞(没有Tiles / Grid)

时间:2014-10-31 17:48:53

标签: vb.net xna collision

第一次在这里发帖。试图寻找以前帮助的主题。

我正在使用Visual Basic,但到目前为止,我已经能够关注C#并转换为VB。

我想要没有瓷砖的碰撞。平稳运动,没有任何类型的卡扣。我已经向下移动了,我的精灵停在了屏幕的边缘。

我读过我可以使用Bounds和Intersects,我试过了。当我每次按下它时将IF语句应用于箭头键时,使用Bounds和Intersects(我只是防止sprite移动,如果它相交),它适用于一个键。我向左移动到一个物体,我停下来。如果我将IF应用于所有键,它将在第一次工作。假设我向左移动到一个对象,IF语句检查相交是否为真,并采取相应的行动。

现在我想向右移动,远离物体。我不能,因为我的精灵已经与对象发生碰撞,因为如果有交点,每个箭头键被编程为不移动。我完全明白为什么会这样。

我目前拥有的代码:(每个箭头键具有相同的代码,并对其进行了更改)

If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Right) And rBlockBounds.X <= 
    graphics.GraphicsDevice.Viewport.Width - rBlockBounds.Width = True Then


            If rBlockBoundBoxBounds.Intersects(rObstructBounds) Then

                rBlockBounds.X += 0
                rBlockBoundBoxBounds.X = rBlockBounds.X - 1
            Else

                rBlockBounds.X += 1
                rBlockBoundBoxBounds.X = rBlockBounds.X - 1
            End If
        End If
  • rBlockBounds是我的精灵As Rectangle

  • rBlockBoundBoxBounds是另一个矩形(比rBlockBounds大1个像素)用作命中框或多或少用rBlockBounds移动,并且是进行碰撞检查的东西

  • rObstructBounds是我正在移动我的精灵的静止物体。

任何人都有关于如何使这项工作的建议?

1 个答案:

答案 0 :(得分:0)

因为我自己用C#编程,而不是VB我不能编写你的解决方案,但我可以解释一个更好的方法来接近它。

您要做的是防止两个矩形相交。为此,您需要在代码中实现move方法,以检查两个磁贴是否发生冲突。这是一个C#示例:

public bool MoveX(float distance) // Move Player Horizontally in this example
{
    rBlockBounds.X += distance;
    if(rBlockBoundBoxBounds.Intersects(rObstructBounds)
    {
        rBlockBounds.X -= distance;
        return false;
    }
    return true;
}

这实际上意味着如果你遇到一个对象,你将被推出它。因为它出现在一个刻度线中,所以你不会得到任何突然的前后动画。

这应该做你想要的。您可以对此进行测试,然后将其实现为y坐标。

另外,你可能会注意到我已经让函数返回了一个bool。这是可选的,但允许您检查您的播放器是否已移动。

请注意,如果您将一个物体传送到另一个物体,它将导致问题,所以请记住每次移动任何物体时都要实现。

但那应该做你想要的。

修改

请注意,由于您的对象不在平铺网格中,因此您需要在非常小的步骤中移动大量时间。

这样的事情:

public bool MoveX(float distance) // Move Player Horizontally in this example
{
    rBlockBounds.X += distance;
    if(rBlockBoundBoxBounds.Intersects(rObstructBounds)
    {
        rBlockBounds.X -= distance;
        return false;
    }
    return true;
}

public bool MoveX(float distance, int repeat)
{
    for(int i=0; i < repeat; i++)
    {
        rBlockBounds.X += distance;
        if(rBlockBoundBoxBounds.Intersects(rObstructBounds)
        {
            rBlockBounds.X -= distance;
            return false;
        }
    }
    return true;
}

第二个将采取多个步骤。这就是你使用它的原因:

MoveX(500); // Will move 500 right. Could easily skip over objects!
MoveX(5, 100); // Will move 5 right one hundred times
// ^ This will take more time but will not skip object

同样对你的你可以这样做:

MoveX(3);        // If contact object will be max 3 pixels away
MoveX(1, 3);     // If contact object will be max 1 pixels away
MoveX(0.5f, 6);  // If contact object will be max 0.5 pixels away

现在我猜你所有的xy位置都是整数。如果是这样的话,你可以在第二次通话时离开,并且完全相邻。如果没有,你会做第三次电话。

希望这会有所帮助。