繁体   English   中英

SDL和C ++中的碰撞

[英]Collisions in SDL & C++

如何计算C ++和SDL中两个矩形之间的碰撞,以及如何使播放器无法通过该矩形(即确保一个矩形不能穿过另一个矩形)?

我知道停止播放器将是playeryvel = 0 ,使播放器的Y速度为0,因此他们无法通过它。 我的问题是,当我想停止通过其他矩形的移动时,这将停止所有垂直移动。

我当前的代码使用了一个名为check_collision(SDL_Rect, SDL_Rect)的函数。 这是我的用法代码和实际功能。

// This loops through a vector, containing rects.
for (int i=0; i<MAP::wall.size(); i++)
{
    std::cout << i << std::endl;
    cMap.FillCustomRect(MAP::wall.at(i), 0xFFFFFF);
    if (check_collision(cMap.wall.at(i), cDisplay.getPlayer(playerx, playery)))
    {
        exit(0); // It exits just as an example to show if there actually is a collision
    }
}


bool check_collision( SDL_Rect A, SDL_Rect B )
{
    //The sides of the rectangles
    int leftA, leftB;
    int rightA, rightB;
    int topA, topB;
    int bottomA, bottomB;

    //Calculate the sides of rect A
    leftA = A.x;
    rightA = A.x + A.w;
    topA = A.y;
    bottomA = A.y + A.h;

    //Calculate the sides of rect B
    leftB = B.x;
    rightB = B.x + B.w;
    topB = B.y;
    bottomB = B.y + B.h;

     //If any of the sides from A are outside of B
    if( bottomA <= topB )
    {
        return false;
    }

    if( topA >= bottomB )
    {
        return false;
    }

    if( rightA <= leftB )
    {
        return false;
    }

    if( leftA >= rightB )
    {
        return false;
    }

    //If none of the sides from A are outside B
    return true;
}

只需在每一帧中将播放器推离碰撞点即可。 您不需要布尔测试(是否发生碰撞),如果发生碰撞,则需要调整玩家位置。

  1. 更新玩家位置(位置+ =速度*时间);
  2. 如果发生碰撞,请将玩家推离碰撞点,以免发生碰撞。

这可以很好地起作用,因为您将能够沿墙壁“滑动”等。为此,您需要找到接触点,相交深度和相交方向(即,应将玩家推向哪个方向)离开)。

当然,您需要计算播放器的移动距离,但是在2D模式下,这非常容易做到。

您需要计算两个矩形有多少重叠。 然后,您沿重叠最多的方向(x或y)(仅在x或y方向,除非它们相等)推动玩家矩形。

我看到您使用了Lazyfoo代码。 我也是。我和你有同样的问题,但我解决了。 这是我的方法。

hero.move(true);   // hero is moved in some direction 
if (check_collision(hero.rect(),box.rect()))  // check for collision after movement 
{
    hero.move(false); // if collision happend , move hero back 
}

SDL_flip(screen);

看起来英雄已经​​停下来了,但实际上它将向前移动,如果发生碰撞,则向后移动。 此后,将显示他。 true和false参数用于告知函数英雄是否必须向前移动(x + =速度)或向后移动(x-=速度)。 如果您需要我的碰撞代码中的一些代码,请询问。

听起来您像是在事后才发现自己的碰撞。 您很可能会将播放器移到矩形中,因此后续的碰撞检查始终返回true。 有几种方法可以解决此问题,但我认为最简单的方法是在发生碰撞之前 (而不是在发生之后)捕获并防止它。

假设播放器跌倒了,而您每帧都更新了播放器的位置。 在移动玩家的位置之前,您需要检查新位置是否将与矩形相交。 如果新位置将与矩形相交,则要更改播放器的移动距离(我们将此距离称为step ),以使其接触矩形的边缘,但不相交。

在移动功能中添加检查大肠杆菌。 传递新位置(好像已移动)以检查大肠杆菌功能。 如果发生碰撞,则在move func中返回false,否则,则返回true。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM