SFML 中的碰撞不是那么好,如何改进它?
The collision in SFML is not that good, how to improve it?
我最近一直在使用 C++ 和 SFML 最新版本开发一个简单的游戏,但我遇到了一个问题,即碰撞检测不是很好,例如即使敌人没有,玩家也会死亡触摸他,但只是靠近他。这是玩家 class 的代码,带有移动功能和碰撞检测代码以及敌人的移动 class:
`class PlayerA : public CircleShape
{
public:
//Constructor:
PlayerA(float xposition, float yposition, float radius, float s)
{
setRadius(radius);
setFillColor(Color::Yellow);
setOutlineColor(Color(00,80,00));
setOutlineThickness(-2);
setPointCount(3);
setSpeed(s);
setPosition(xposition,yposition);
}
//Movements of the player:
void up()
{
move(0,-10*speed);
}
void down()
{
move(0,10*speed);
}
void right()
{
move(10*speed,0);
}
void left()
{
move(-10*speed,0);
}
void checkA(ObsA *obs1=NULL,ObsA *obs2=NULL, ObsA *obs3=NULL, ObsA *obs4=NULL, ObsA *obs5=NULL)
{
if(obs2==NULL)
{
if(getGlobalBounds().intersects(obs1->getGlobalBounds()))
{
relevel();
}
}
private:
float speed=0.00;
void obs()
{
if(speed > 0)
{
rotate(0.5*speed);
}
else
{
rotate(0.5*speed);
}
}
private:
float speed = 0.00;
void obs()
{
if(speed > 0)
{
rotate(0.5*speed);
}
else
{
rotate(0.5*speed);
}
}
private:
float speed = 0.00;
代码有没有问题,如何解决,谢谢!
intersects
函数只是检查两个矩形是否相交。如果你想在 SFML 中进行像素完美碰撞检测,你必须自己编写。
基本上,从intersects
开始,如果为真,则获取相交矩形并检查两个原始矩形中的任何像素是否包含重叠的相关像素。
你用的是圆圈吗?如果我没记错的话,这个圆圈会有一个矩形的碰撞框。如果是这种情况,那么您可能会在不可见的矩形角之间发生碰撞。
如果您使用的是圆形,也许将 class 更改为正方形并查看碰撞是否正常。或者尝试直接在 x 或 y 轴上用你的圆测试碰撞;即让它们沿直线朝彼此移动,只改变 1 个轴。 (圆的边缘将与矩形的左、右、上、下部分的边缘相同)。
如果您需要更好的圆圈碰撞,SFML 中可能已经内置了一个。但我认为使用你的两个圆的半径、你的两个对象的中心以及中心之间的 角度 斜边来编写你自己的逻辑并不过分。
根据 Merlyn Morgan-Graham 的评论进行编辑。
您可以使用此功能来执行更好的碰撞detection.Its一个基本的但效果很好
bool circleTest(const sf::Sprite &first, const sf::Sprite &second)
{
sf::Vector2f firstRect(first.getTextureRect().width, first.getTextureRect().height);
firstRect.x *= first.getScale().x;
firstRect.y *= first.getScale().y;
sf::Vector2f secondRect(second.getTextureRect().width, second.getTextureRect().height);
secondRect.x *= second.getScale().x;
secondRect.y *= second.getScale().y;
float r1 = (firstRect.x + firstRect.y) / 4;
float r2 = (secondRect.x + secondRect.y) / 4;
float xd = first.getPosition().x - second.getPosition().x;
float yd = first.getPosition().y - second.getPosition().y;
return std::sqrt(xd * xd + yd * yd) <= r1 + r2;
}
我最近一直在使用 C++ 和 SFML 最新版本开发一个简单的游戏,但我遇到了一个问题,即碰撞检测不是很好,例如即使敌人没有,玩家也会死亡触摸他,但只是靠近他。这是玩家 class 的代码,带有移动功能和碰撞检测代码以及敌人的移动 class:
`class PlayerA : public CircleShape { public:
//Constructor:
PlayerA(float xposition, float yposition, float radius, float s)
{
setRadius(radius);
setFillColor(Color::Yellow);
setOutlineColor(Color(00,80,00));
setOutlineThickness(-2);
setPointCount(3);
setSpeed(s);
setPosition(xposition,yposition);
}
//Movements of the player:
void up()
{
move(0,-10*speed);
}
void down()
{
move(0,10*speed);
}
void right()
{
move(10*speed,0);
}
void left()
{
move(-10*speed,0);
}
void checkA(ObsA *obs1=NULL,ObsA *obs2=NULL, ObsA *obs3=NULL, ObsA *obs4=NULL, ObsA *obs5=NULL)
{
if(obs2==NULL)
{
if(getGlobalBounds().intersects(obs1->getGlobalBounds()))
{
relevel();
}
}
private:
float speed=0.00;
void obs()
{
if(speed > 0)
{
rotate(0.5*speed);
}
else
{
rotate(0.5*speed);
}
}
private:
float speed = 0.00;
void obs()
{
if(speed > 0)
{
rotate(0.5*speed);
}
else
{
rotate(0.5*speed);
}
}
private:
float speed = 0.00;
代码有没有问题,如何解决,谢谢!
intersects
函数只是检查两个矩形是否相交。如果你想在 SFML 中进行像素完美碰撞检测,你必须自己编写。
基本上,从intersects
开始,如果为真,则获取相交矩形并检查两个原始矩形中的任何像素是否包含重叠的相关像素。
你用的是圆圈吗?如果我没记错的话,这个圆圈会有一个矩形的碰撞框。如果是这种情况,那么您可能会在不可见的矩形角之间发生碰撞。
如果您使用的是圆形,也许将 class 更改为正方形并查看碰撞是否正常。或者尝试直接在 x 或 y 轴上用你的圆测试碰撞;即让它们沿直线朝彼此移动,只改变 1 个轴。 (圆的边缘将与矩形的左、右、上、下部分的边缘相同)。
如果您需要更好的圆圈碰撞,SFML 中可能已经内置了一个。但我认为使用你的两个圆的半径、你的两个对象的中心以及中心之间的 角度 斜边来编写你自己的逻辑并不过分。
根据 Merlyn Morgan-Graham 的评论进行编辑。
您可以使用此功能来执行更好的碰撞detection.Its一个基本的但效果很好
bool circleTest(const sf::Sprite &first, const sf::Sprite &second)
{
sf::Vector2f firstRect(first.getTextureRect().width, first.getTextureRect().height);
firstRect.x *= first.getScale().x;
firstRect.y *= first.getScale().y;
sf::Vector2f secondRect(second.getTextureRect().width, second.getTextureRect().height);
secondRect.x *= second.getScale().x;
secondRect.y *= second.getScale().y;
float r1 = (firstRect.x + firstRect.y) / 4;
float r2 = (secondRect.x + secondRect.y) / 4;
float xd = first.getPosition().x - second.getPosition().x;
float yd = first.getPosition().y - second.getPosition().y;
return std::sqrt(xd * xd + yd * yd) <= r1 + r2;
}