我该如何处理这种类型的碰撞?

时间:2014-07-08 22:06:26

标签: c++ collision-detection sfml tile

所以我一直在搞乱简单的游戏开发一段时间,并在squidi.net/three/entry.php?id=85上找到了一个有趣的游戏创意。我正在使用带有C ++的SFML 2.1,我在VertexArray中有一个显示级别的tilemap。以下是我到目前为止的内容,您可以看到我的简单拼贴: LINK 。在如何处理潜艇(不是基于网格的运动系统)和墙壁之间的碰撞方面,我很遗憾。问题是如果我从底部接近图块2(检查图块集图像),如果我检查子图块和整个图块之间的碰撞,则子图案在它甚至到达图像中的实际墙壁之前将停止。以下是帮助解释此问题的图片: LINK

对于之前的混乱感到抱歉,我希望这不像以前那么糟糕。

非常感谢任何帮助。

谢谢,

卡雷尔

编辑:重写问题,试图让它更清晰。

2 个答案:

答案 0 :(得分:1)

我会警告你,如果有问题的物体比你的collsiion瓦片的分辨率移动得快,那么简单的基于网格的碰撞会严重破坏。假装您的碰撞盒大小为8x8像素。现在,当潜艇移动时每个抽搐发出16个像素的情况会发生什么?你可以看到它可以穿过单层厚度的碰撞墙,如果你不太注意你如何检查碰撞 - 检查潜艇在移动时撞击的每个瓦片而不是直接用力度更新位置。它甚至比这更糟糕 - 图像,你每秒只移动2个像素,只是剪切一个瓷砖的边缘,但在另一边结束 - 再次基于图块的碰撞,没有代码跟踪你移动时触摸的每个块,会失败。

更通用的方法是使用基于线或矢量的碰撞。基本上,使用表示墙边的矢量列表而不是平铺贴图。要检查2D中的碰撞,您可以检查起始点与collsion向量的perpdot(垂直点积)的符号以及针对碰撞向量的运动终点的符号。如果它们不同,则越过该线并发生碰撞。如果其中一个为0,则表示您处于碰撞线上。请务必检查线路的终点以及更多点阵产品。

这种方法的另一个好处是,它可以很容易地在碰撞时沿墙壁“滑动”你的角色,而不是仅仅将它们支撑到前一个位置,这会导致墙壁粘连和振动。它真的很快只是一些乘法和减法。它也可以轻松扩展到SIMD样式代码。

有关详情,请参阅this question

答案 1 :(得分:0)

您的潜艇比平铺小,因此潜艇在任何给定时间最多可覆盖4个平铺。

  1. 识别潜艇重叠的地砖。至少1,最多4。
  2. 对于每个重叠的图块,调用与该图块的类型(0到6)对应的函数
  3. 您可以向子函数传递每个函数与该图块中心的距离。

    这是最简单的:

    bool collided_with_tile_0( int x_offset, int y_offset )
    {
      return false;  // Nothing to collide with
    }
    

    这个也很容易:

    bool collided_with_tile_1( int x_offset, int y_offset )
    {
      return std::abs( y_offset ) < SUB_SIZE;  // Collision if y_offset is close to 0
    }
    
    祝你好运!