我和我的团队正在开发一个带有C ++ / SDL / OpenGL的2D平台游戏,我们已经定义了一个碰撞系统,但我们在检查与tilemap的碰撞时遇到了问题。
tilemap的tile是32x32,所以我们尝试定义玩家的X和Y的最大速度小于32,因为在这种情况下我们发现了如果速度大于tile大小的问题,当检查碰撞时,它的位置会以超过32的速度进行更新,因此在这种情况下,位置会跳过一个会导致严重验证问题的磁贴,所以此时我们将X和Y速度限制为30,但是我们不知道如何使速度大于瓷砖尺寸,而不会失去完整的碰撞检测,可能会有一些可能被滑雪的瓷砖。
答案 0 :(得分:3)
基本上不是简单的盒子/盒子碰撞,而是需要检查固定水平几何盒子与移动盒子移动(位置)到(位置+速度)形成的形状之间的碰撞。
答案 1 :(得分:1)
你如何定义速度?让我们假设它是每秒的像素,然后为了允许更高的速度,你应该在一秒钟内多次检查碰撞。所以在伪代码中:
double time = GetElapsedTime();
player.updatePosition(speed * time);
现在它可能比那更复杂,但你明白了;要么做这样的事情,要么使用精确的碰撞检测(我曾经找到一篇很棒的文章,但似乎找不到它),它使用方程来“预测”物体何时何地碰撞。
答案 2 :(得分:1)
我用过的一种方法:
当移动(玩家,其他精灵......)时,确定它作为矩形传递的所有图块。
举例来说:
on tick:
player-box = (player.x, player.y) - (player.x + player.width, player.y + player.height)
player-delta.x = (player-speed.x × (now - last-updated))
player-delta.y = (player-speed.y × (now - last-updated))
player-end-box = player-box + player-delta
{ i.e. player-end-box = ( player-box.top-left.x + player-delta.x,
player-box.top-left.y + player-delta.y ) -
( player-box.bottom-right.x + player-delta.x,
player-box.bottom-right.y + player-delta.y ) }
player-collided = ( min (player-box.top-left.x, player-end-box.top-left.x),
min (player-box.top-left.y, player-end-box.top-left.y) ) -
( max (player-box.bottom-right.x, player-end-box.bottom-right.x),
max (player-box.bottom-right.y, player-end-box.bottom-right.y) )
然后,您可以使用modulo 32
每个角落的player-collided
来确定玩家(或任何精灵)已经(试图)遮挡的图块。
通常情况下,您可能希望在播放器的实际大小上插入一个小的“边距”以避免1px或2px重叠...(即将起始框设置为比实际精灵小几px),具体取决于方式准确的你的球员的控制,以及精灵和一个瓦片之间的大小差异。
请注意,非常快(每次更新的许多图块)对角线移动使其无效,但它适用于非常快速的线性(水平或垂直)移动。如果你在对角线上移动“太快”,对于这种方法,请考虑将起始和结束矩形连接成一个多边形(不规则六边形),并测试每个图块是否包含该六边形的任何部分。
for each tile in (big rectangular area):
if tile is inside polygon (hexagon of movement):
add tile to list of collisions
这实际上是对常见2D情况的完整边界几何检查的优化。