我花了许多令人沮丧的时间,无法解决这个问题,我了解碰撞并使其起作用,直到我尝试实现重力,在碰到瓷砖 map 后,似乎无法设置玩家的位置,这是我的问题, 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个像素来工作,但它所做的只是播放器精灵上下反弹

最佳答案

鉴于以上信息,我假设您正在制作横向滚动游戏,并且您的角色正在与图块的顶部碰撞。

就是说,您需要了解的第一件事是,您不应在角色移动之后但在角色移动之前调整其位置。角色永远不会在游戏中处于“非法”位置。甚至不到一秒钟。

您有权查看 future (至少在您自己的游戏中),可以随意使用!始终领先一步。

如何找到合适的地方?

基本代数!

这是情况。

这里的目标是找到绿色和红色虚线与蓝色小虚线(代表地面)的交叉点。

首先,我们需要找到字符轨迹(黑点)的方程,该方程应类似于: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,或者使用数学 Material 进行25个检查。

关于c++ - Tilemap碰撞SFML C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21562181/

10-11 22:52
查看更多