【问题标题】:Proper collision in SFML (C++)SFML (C++) 中的正确碰撞
【发布时间】:2018-06-11 06:49:58
【问题描述】:

因此,我进行了一项测试,以了解碰撞在 SFML 中的运作方式。我已经做了这个sn-p的代码:

if (floor.getGlobalBounds().intersects(SuperMario.getGlobalBounds())) // Floor
    {
        SuperMario.setPosition(SuperMario.getPosition().x, floor.getPosition().y - SuperMario.getOrigin().y);
        IsTouching = true;
    }

正如代码所示,当马里奥接触到地板物体时,他会改变他的位置,并将传送到地板上方。

但是,这有以下副作用,如下图所示。

请注意,“绿色盒子”是我之前提到的地板对象。另外,请忽略图1中的“左”字,我的意思是“右”。

当然,这种行为是有意的(即不是错误),但它是不需要的。

所以我的问题是:如何消除这种“副作用”?我的意思是,我怎样才能修改我的代码,这样马里奥就不会在接触地板两侧时传送到地板上方(使平台工作像适当的平台一样工作)?我希望马里奥被盒子挡住,而不是被传送。

更新:所以现在,我有这个:

for (unsigned int i = 0; i <= solidObjects.size() - 1; i++)
    {
        if (solidObjects[i].getGlobalBounds().intersects(SuperMario.getGlobalBounds()))
        {
            if (SuperMario.getPosition().x - solidObjects[i].getPosition().x  < SuperMario.getPosition().y - solidObjects[i].getPosition().y)
            {
                SuperMario.setPosition(solidObjects[i].getPosition().x - SuperMario.getOrigin().x, SuperMario.getPosition().y);
                IsTouching = false;
            }
            else if (SuperMario.getPosition().y - solidObjects[i].getPosition().y < SuperMario.getPosition().x - solidObjects[i].getPosition().x)
            {
                SuperMario.setPosition(SuperMario.getPosition().x, solidObjects[i].getPosition().y - SuperMario.getOrigin().y);
                IsTouching = true;
            }
            else if (SuperMario.getPosition().x - solidObjects[i].getTextureRect().width < SuperMario.getPosition().y - solidObjects[i].getPosition().y)
            {
                SuperMario.setPosition(solidObjects[i].getTextureRect().width + SuperMario.getOrigin().x, SuperMario.getPosition().y);
                IsTouching = false;
            }
        }
        else
        {
            IsTouching = false;
        }
    }

但是,有一个问题。当马里奥接触到地板的两侧时,他会粘在地板上,这意味着他无法向右移动。

如果我不够清楚,请说明我应该补充什么或进一步澄清。

【问题讨论】:

  • 您想要避免的具体行为是什么?传送?想被盒子拦住吗?
  • 是的!我正是想要那个!
  • 通过比较 x/y 位置和宽度/高度,您可以确定哪个方向需要最少的移动量才能让马里奥离开地板矩形。这就是您要移动马里奥的方向。
  • @super 但是,什么命令可以让 mario 停止移动呢?我是否实现了相同的SuperMario.setPosition(SuperMario.getPosition().x, floor.getPosition().y - SuperMario.getOrigin().y);sn-p,但根据每个轴进行了修改?
  • 是的,类似的。根据您需要的复杂碰撞检测,OBB 与 OBB 或 SAT 碰撞可能是值得阅读的好东西。

标签: c++ collision sfml


【解决方案1】:

这感觉很奇怪,因为您通常会定义实心区域而不是玩家可以走进的区域。毕竟你会希望你的玩家跳起来,而不是让他们粘在地上。

剩下的就很简单了:

  • 遍历所有实体对象并确定玩家和实体矩形是否重叠。
  • 如果有,请确定哪个距离更小(x 或 y)。这让您可以确定移动播放器的轴。
  • 确定玩家更快离开实体区域的方向,即推动玩家的方向。
  • 将玩家推向计算好的方向并重复检查。

根据您的地图复杂性,这可能会变得相当复杂,因此您很可能需要一些排序/空间化来减少比较次数(例如,跳过检查不可能/遥远的形状)。

【讨论】:

  • @ToadTheMushroomCoder 你上面定义函数的方式他应该是粘的,但这可能取决于你如何实现跳跃。
  • 我有最后一个问题。如何准确地迭代实体对象?
  • @ToadTheMushroomCoder 你会把它们放在像std::vector这样的容器中。
  • 好的,所以我已经完成了所有正常工作的碰撞(我的代码在我的问题的更新部分中),但马里奥在触摸它们时会粘在地板的两侧。这是为什么呢?
  • @ToadTheMushroomCoder 不是 100% 确定你的意思,但基本的想法是在 Y 检查之上进行 X 检查,以避免它们在地面上触发(即在你的瓷砖或物体上) '站在上面)。如果这不是你的意思,我建议你打开一个新问题,如果可能的话,发布一个简短的视频片段来展示你的问题。
猜你喜欢
  • 2014-02-28
  • 2017-07-25
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 2012-09-23
  • 1970-01-01
相关资源
最近更新 更多