【问题标题】:Preventing tunneling with this setup?使用此设置防止隧道传输?
【发布时间】:2011-05-13 05:34:16
【问题描述】:

我设置了一个简单的矩形瓷砖碰撞方案,效果很好。

唯一的问题是当你开始从窗台上掉下来的时候。您的速度达到了每帧 Y/X 变化大到足以让您剪辑成固体物体并出现故障的地步。

基本上我的设置如下:

首先,玩家的位置加上了它的速度,所以如果没有发生碰撞,玩家现在就在下一帧的位置。 下面的列表只是一个函数,checkIntersectTiles(Vector2 maskPos);

  1. 计算要检查的角色周围的图块。
  2. 遍历图块,包括边界图块内的图块。
  3. 检查玩家与这些图块的碰撞矩形。
  4. 如果存在交叉点,请将最大的违规轴移出图块,然后将该轴速度设置为 0。
  5. 继续检查。

当你夹入地面时,你会在里面晃动,因为我的算法试图将你移到与你最相撞的地块之外。

我的解决方案:检查从玩家 pos 到玩家 pos + 速度的每个位置。 我被困在那一点上。

谁能帮帮我?

【问题讨论】:

    标签: c# xna collision-detection tunneling


    【解决方案1】:

    我假设您将玩家移出碰撞瓷砖的代码只需一步即可完成。因此,如果玩家与瓷砖碰撞,您确定 Y 方向的穿透深度为 5,您立即将玩家 Y 位置调整 -5。

    按照您的建议,在每一步检查玩家的位置。因此,如果 Y 速度为 5,那么您可以将玩家的 Y 位置调整 1,检查碰撞,然后再重复 4 次。有关处理时间步进的计算,请参见后面。以下只是一些基本的伪代码,只是在 Y 方向上。

    player.Y += vel;
    if (player.CheckCollisions())
    {
      // handle collision
    }
    

    变成

    for (int i = 0; i < vel; ++i)
    {
      player.Y += 1;
      if (player.CheckCollisions())
      {
        // handle collision
        break;
      }
    }
    

    如果你没有调整过去的时间,那是简单的版本。如果是,那么您宁愿执行更小的时间步长

    所以

    player.Y += vel * elapsedTime;
    if (player.CheckCollisions())
    {
      // handle collision
    }
    

    变成

    float currentTimeStep = 0;
    Position startY = player.Y;
    while (currentTimeStep < elapsedTime)
    {
      currentTimeStep = Math.Min(currentTimeStep + stepDelta, elapsedTime); // You need to tune the stepDelta
      player.Y = startY + vel * currentTimeStep;
      if (player.CheckCollisions())
      {
        // handle collision
        break;
      }      
    }
    

    在上述情况下,您需要调整时间步长增量,以确保在性能和准确性之间取得平衡。您可能会考虑动态计算每帧的增量,以确保调整接近 1 个像素。

    【讨论】:

    • 将尝试实现这一点,会回复您。谢谢!
    猜你喜欢
    • 2010-12-22
    • 2021-04-13
    • 2010-09-05
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 2012-03-05
    相关资源
    最近更新 更多