【问题标题】:xna collision without max speed没有最大速度的 xna 碰撞
【发布时间】:2014-05-01 01:07:34
【问题描述】:

我正在制作一个平台游戏,并且我研究了在没有旋转的基于图块的游戏中添加碰撞的不同方法。但是我所看到的一切都假设在任何情况下,碰撞物体中的一个都不会以足够快的速度在检测到碰撞之前通过另一个。我尝试过使用 Box2D 和 Farseer,但它们过于复杂并且在制作大量瓷砖时运行速度非常慢。我还尝试了使用 2D 凸包的自己的方法,但运行速度也太慢了。那么有没有一种方法可以在没有最大速度的情况下检测碰撞,或者让物品相互通过,并且不会过于复杂并且可以与大量瓷砖一起使用?非常感谢任何帮助

【问题讨论】:

  • 您将找到/实现的每种算法都会对项目数量有限制,并且当您添加越来越多的对象时运行速度会很慢 - 您对此无能为力。这里没有什么可说的,除了 - 设定目标,配置文件,看看你的情况下什么是慢的。在精确检查之前添加近似检查(例如还包括速度/时间的边界矩形)和一些基于空间位置的分桶对象是可能的优化方法...

标签: c# xna 2d collision


【解决方案1】:

取决于对象及其运动和整个游戏过程。如果您正在向某个障碍物射击子弹,您可以计算子弹是否会在子弹击中障碍物之前与障碍物相交。你有职位,你可以计算他们之间的距离。所以你可以检查碰撞和距离。

其他方式,正如 @cwohlman 建议的那样。你可以有 2 个碰撞框,一个大的“假定”碰撞区域和一个覆盖物体的精确区域。因此,如果对象触发假定的碰撞,您就知道子弹有可能会击中对象,并且您会进行一些详细的计算,如果按钮会击中对象或会在其上方或下方通过。要确定对象是否在假定的碰撞区域中,您可以使用圆形碰撞。

private bool DetectCircularCollision(Sprite a, Sprite b)
{
    float radius = Math.Sqrt(a.Width / 2 * a.Height / 2 + b.Width / 2 * b.Height / 2);
    float distance = Vector2.Distance(a.Position, b.Position);
    if (distance < radius) return true;
    return false;
}

到目前为止我还没有遇到这个问题,因为所有的飞行物体都应该在玩家眼中可见。如果您将对象每帧移动 50 像素或 100 像素,玩家将不会注意到这一点,或者会混淆这是什么。

您可能需要结合一些碰撞方法来实现您所需要的。建议,不要使用像素冲突,因为它完全没有必要,而且是资源杀手。相反,用少量边界框或圆圈覆盖对象。

假设蓝色圆圈为碰撞区域,红色圆圈为精确碰撞区域的示例。

【讨论】:

  • 听起来不错。有谁知道我如何为“如果他们真的碰撞”部分制定算法?此外,我所有的瓷砖和角色都有矩形碰撞框。将较大的碰撞盒作为一个盒子还是一个圆圈会更有效吗?
  • 盒子碰撞比圆形更快,我使用圆形,因为它更好地覆盖物体。然后你可以计算反弹角度,添加一些比矩形更好的伤害效果。视觉上更准确。当您使用框和圆圈时,我添加了另一个图像。大小相同,可以看到碰撞(蓝色)更准确。
  • 到“它们是否会碰撞”,您可以仅使用一个像素(vector2)进行计算,因此如果该像素的位置在其他对象内部,则存在会发生碰撞的通道。如果它们真的发生碰撞,则使用较慢的物体运动来计算碰撞。而不是velocity.x=20 在循环中使用velocity.y=1。
【解决方案2】:

您可以尝试双重算法方法,首先使用简单算法来确定对象是否“可能”发生碰撞,如果是,则使用复杂算法查看它们是否发生碰撞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 2022-12-20
    相关资源
    最近更新 更多