Tilemap Collision SFML C ++

时间:2014-02-04 20:00:39

标签: c++ map collision sfml tile

我花了很多令人沮丧的时间而且无法解决这个问题,我理解碰撞并让它工作直到我尝试实现重力,我似乎​​无法设置玩家位置在它击中瓷砖地图后,落在地面上我的问题,x轴以下代码的变化工作正常

if (background.colMap[tiles[i].y][tiles[i].x] == 1)
    {
        playerSpeed.y = -0.f;
        playerSprite.setPosition(playerSprite.getPosition().x, playerSprite.getPosition().y - 1);
        inAir = false;
    }

我通过将速度降低到0并将播放器恢复到1像素可以工作,但它所做的只是播放器精灵上下跳动

1 个答案:

答案 0 :(得分:2)

鉴于以上信息,我假设您正在进行横向滚动游戏,并且您的角色正在与拼图的顶部发生碰撞。

那就是说,你需要了解的第一件事就是你不应该在它移动之后但在它移动之前调整角色的位置。角色永远不应该处于游戏中“非法”的位置。即便只有几分之一秒。

你有能力看到未来(至少在你自己的游戏中),随意使用它!始终领先一步。

如何找到合适的地方?

基础代数!

情况就是这样。

Collision Algebra

这里的目标是找到绿色和红色虚线穿过小蓝色虚线(代表地面)的位置。

首先,我们需要找到我们的角色(黑点)轨迹的等式,它应该是:y = ax + b

斜率a = (Y2 - Y1)/(X2 - X1)b = y - ax

在我们的示例中,等式为y = -2x + 10。我们只需知道Y = 3时X的值是多少,我们可以使用x = (y - b) / a找到它,在我们的例子中,x = (3 - 10) / (-2) = 3.5

所以我们现在知道我们的角色将与(3.5, 3)处的地板相交,这就是我们将角色放置的位置。

您当前技术的缺陷

当你发生碰撞时,如果我理解你的代码,你就会把角色放在1个像素上。

想象一下,你的角色真的很快,在他的位置的一次更新中,他从有效位置变为无效位置,距离地面25个像素。使用您当前的技术,至少需要25次位置更新才能恢复原状,或者只有25次碰撞检测循环,但仍然不是很有效。

另一件事,你似乎在循环水平中的每个可能的瓷砖,所以这可能主要是空的瓷砖和/或全地(不可访问)瓷砖,这是你真正需要的一个很大的开销。

最好的选择是存储可碰撞瓷砖的坐标,然后迭代这些瓷砖。

如果您有一个屏幕,比方说50 x 50个瓷砖,并且只有25个可碰撞的瓷砖,您仍在检查50 * 50 - 25 = 2475个瓷砖,这些是2475个不必要的检查。但显然,这并不是你遇到麻烦的原因,即使那些2475次不必要的检查也不会破坏逻辑。

只是为了玩数字,因为我们的角色是25像素以下,我们将循环25次2500个瓷砖,这是62500次检查,而不是带有可碰撞瓷砖集合的25 * 25 = 625,或者仅25次检查用数学的东西。