如何在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方向,除非它们相等)。
在move函数中添加检查冲突。将新位置(就像它被移动了一样)传递给检查碰撞功能。如果发生冲突,则在move func中返回false,如果没有move,则返回true。
我看到您使用了Lazyfo代码。我也是。我和你有同样的问题,但我解决了。以下是我的做法。
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。有几种方法可以解决这个问题,但我认为最简单的方法是在发生之前(而不是之后)捕获碰撞并防止它。
假设玩家摔倒了,你每帧都会更新玩家的位置。在你移动玩家的位置之前,你需要检查新的位置是否会与矩形相交。如果新位置将与矩形相交,则需要更改玩家移动的距离(我们将此距离称为步长),使其接触矩形的边缘,但不与矩形相交。