Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SFML(C+;+;)中的正确碰撞_C++_Collision_Sfml - Fatal编程技术网

C++ SFML(C+;+;)中的正确碰撞

C++ SFML(C+;+;)中的正确碰撞,c++,collision,sfml,C++,Collision,Sfml,所以,我正在进行一个测试,以了解碰撞如何在SFML中运行。我制作了以下代码片段: if (floor.getGlobalBounds().intersects(SuperMario.getGlobalBounds())) // Floor { SuperMario.setPosition(SuperMario.getPosition().x, floor.getPosition().y - SuperMario.getOrigin().y); IsTouc

所以,我正在进行一个测试,以了解碰撞如何在SFML中运行。我制作了以下代码片段:

if (floor.getGlobalBounds().intersects(SuperMario.getGlobalBounds())) // Floor
    {
        SuperMario.setPosition(SuperMario.getPosition().x, floor.getPosition().y - SuperMario.getOrigin().y);
        IsTouching = true;
    }
正如代码所暗示的,马里奥会在接触地面物体时改变他的位置,并在地面上方进行远程传送

然而,这有以下副作用,如下图所示。

请注意,“绿色框”是我前面提到的地板对象。另外,忽略图片1中的“left”一词,我的意思是“right”

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

所以我的问题是:如何消除这种“副作用”?我的意思是,我怎样才能修改我的代码,这样马里奥就不会在地板上移动,当他接触到地板的侧面时(使平台像一个合适的平台一样工作)?我希望马里奥被关在箱子旁边,而不是被传送

更新:现在,我有了这个:


for(unsigned int i=0;i这感觉真的很奇怪,因为你通常会定义实心区域,而不是玩家可以走进去的区域。毕竟,你希望玩家跳跃,而不是让他们粘在地上

剩下的很简单:

  • 迭代所有实体对象并确定播放器和实体矩形是否重叠
  • 如果有,确定哪一个距离更小(x或y)。这可以让您确定移动播放器的轴
  • 确定球员更快离开实心区域的方向,即推球员的方向
  • 按计算出的方向推动播放器,并重复检查

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

你到底想避免什么样的行为?隐形传送?想被盒子挡住吗?是的!我就是想这样!通过比较x/y位置和宽度/高度,你可以确定哪一个方向需要最少的移动量才能让马里奥离开地板。这就是你想移动马里奥的方向。@super,什么命令可以使mario停止移动?我是否实现了相同的
SuperMario.setPosition(SuperMario.getPosition().x,floor.getPosition().y-SuperMario.getOrigin().y)
片段,但根据每个轴进行了修改?是的,类似于这样。根据您需要的碰撞检测的复杂程度,OBB与OBB或SAT碰撞可能是很好的读物。@ToadTheMushroomCoder您定义上述函数的方式应该是粘合的,但这可能取决于您实现跳跃的方式。我还有最后一个问题问题。我如何准确地迭代实体对象?@ToadTheMushroomCoder你会将它们放在一些容器中,比如
std::vector
。好的,我已经完成了所有正常工作的碰撞(我的代码在我问题的更新部分),但马里奥在触摸地板时会粘在地板的侧面。这是为什么?@ToadTheMushroomCoder不是100%确定你的意思,但基本想法是在Y检查的基础上进行X检查,以避免它们在地面上触发(即,在你站的瓷砖或物体上).如果你不是这个意思,我建议你提出一个新问题,如果可能的话,发布一个简短的视频短片,展示你的问题。
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;
        }
    }