用于处理斜坡的2D碰撞面罩

我一直在看例子: http : //create.msdn.com/en-US/education/catalog/tutorial/collision_2d_perpixel,并试图找出一旦发现碰撞后如何调整精灵。 正如David在Sidescroller提出的步行/碰撞的可变地形高度图中所建议的那样 ,我制作了一些传感器点(英尺,侧面,底部中心等),并且可以很容易地检测到这些点实际上是否与第二个纹理的不透明部分发生碰撞坡)。 我在实际上如何调整基于碰撞的精灵位置的algorithm遇到麻烦。

假设我发现与精灵右脚的斜坡发生碰撞。 我怎样才能扫描斜率纹理数据findY位置放置精灵的脚,使其不再在斜率内? 在这个例子中存储为一维数组的方式有点令人困惑,我应该尝试将数据存储为二维数组吗? 为了testing的目的,我正在考虑将斜率纹理alpha本身作为一个原始的,容易的碰撞掩膜(除了简单的非线性斜率之外,没有草位或其他东西)。 然后,就像在这个例子中,我find斜率纹理和精灵传感器之间的任何碰撞的坐标,并将这些特殊的传感器碰撞标记为已经发生。 最后,在向上移动一个斜坡的情况下,我将扫描上面的第一个透明像素(在该X的纹理的Ys中)右脚碰撞点,并将其设置为精灵的新高度。

我也不清楚什么时候应该做这些调整。 碰撞检查每个game.update()所以我会迅速改变精灵的位置,在下一次更新被调用之前?

我也注意到有几个人提到,最好是将碰撞检查横向和纵向分开,为什么这样呢?

如果这是一个低效或不准确的方式来处理这个问题,请打开任何建议。

我希望MSDN提供了一个这样的例子,我不知道它会比NES Mario风格的纯盒子平台复杂得多。

基本的方法

直接查询纹理可能会很慢,所以我可能会单独存储碰撞掩码。 您存储的格式不相关。 我没有看到任何问题将它存储为一个二维数组,如你所说。 像这样的东西就足够了:

// Use bool or byte to save space bool[,] collisionMask = new bool[TileWidth, TileHeight]; 

在加载的时候,我会从瓦片纹理的Alpha通道创建所有的蒙版arrays,但是对于每种types的瓦片只创建一次 。 换句话说,不要将这些信息存储在每个单独的tile中,而是将其存储在tileset中。

至于为角色正确的位置进行扫描,我会用powershell的方法 – 在与你的脚感应传感器相同的位置查询模板,然后逐个像素地向上移动,直到find一个非封锁一个。 然后移动你的角色相同的数额。

由于瓷砖可能不会太大,所以我认为这种简单的方法不会有太多的性能问题。

但在某些情况下可以简化它

根据瓷砖的可变性,您可能会简化存储信息的方式。 例如,如果您的拼贴块始终从底部开始,并且没有洞,则可以将它们的碰撞遮罩存储为单个一维高度贴图arrays:

 // Essentially an height map for the tile type byte[] collisionMask = new byte[TileWidth]; 

或者,如果他们不总是从底部开始,但仍然没有洞或多个“岛”,你可以将其存储为:

 // Use Point.X for bottom height and Point.Y for top height Point[] collisionMask = new Point[TileWidth]; 

所以这一切都取决于你想要瓷砖的复杂程度。

何时移动角色

我也不清楚什么时候应该做这些调整。 碰撞检查每个game.update()所以我会迅速改变精灵的位置,在下一次更新被调用之前?

是的。 首先你移动你的角色。 然后你有碰撞检测阶段,最后是碰撞响应阶段。 这基本上是通过将角色移动到平铺之外来完成的。

独立的轴处理

我也注意到有几个人提到,最好是将碰撞检查横向和纵向分开,为什么这样呢?

这在这里并不是什么大问题,因为你的脚感传感器的碰撞反应总是将人物向上移动。 无论如何,您将使用中间传感器分别处理与墙壁的碰撞。

我已经做了这个图片的另一个问题,但我会在这里重新发布它的上下文:

在这里输入图像描述

基本上,如果一次移动对角线,它可能会产生一个模糊性,algorithm需要猜测它应该从哪个方向推出。 可以使其足够智能以便始终使用正确的方向,但是单独处理每个轴上的移动更容易,因为这样没有歧义。

我没有使用XNA,我也没有彻底阅读你的话题,但无论如何。

他们的方式我做到了(在AS3中,但这并不重要)是获得斜坡的向量。

假设你想要一个45度的坡度。 为了获得vector,你只需要这样做:

 the slope's X - the character's X = the character's Y 

所以, y=(slope.y-tileHeight/2)+slope.x(+tile width/2)-x(+character width/2)

然后补偿角色的高度,所以-charHeight/2

和镜像斜坡,你这样做:

 y=x-slope.x+tileWidth/2 

你有基本的想法吗? 所以,角色越接近斜坡的右侧或左侧,角色的得分越高。 我发现这个方法比检查像素更可靠。 虽然这有一个问题,但你必须单独做出所有的角度。 不知道如果这是你的问题…

如果你还不明白,不要害怕问!