[英]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;
}
只需在每一帧中将播放器推离碰撞点即可。 您不需要布尔测试(是否发生碰撞),如果发生碰撞,则需要调整玩家位置。
这可以很好地起作用,因为您将能够沿墙壁“滑动”等。为此,您需要找到接触点,相交深度和相交方向(即,应将玩家推向哪个方向)离开)。
当然,您需要计算播放器的移动距离,但是在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.