[英]Struggling with collision detection. How do I detect the collision correctly?
class ShapePlanet
{
public:
sf::CircleShape shape;
sf::Vector2f planetposition;
int radius = 45;
ShapePlanet()
{
float x = rand() % 1020; //invece che 1280
float y = rand() % 650; //invece che 720
this->shape.setFillColor(sf::Color::Green);
this->planetposition.x = x;
this->planetposition.y = y;
this->shape.setPosition(x, y);
}
};
struct Node_Planet
{
ShapePlanet Planet;
Node_Planet* next;
};
typedef Node_Planet* ptr_list;
class Planet
{
private:
ptr_list head;
public:
ptr_list create(int n)
{
ptr_list tmp = NULL;
for (int i = 0; i < n; i = i + 1)
{
{
tmp = new Node_Planet;
tmp->Planet = ShapePlanet();
tmp->next = head;
head = tmp;
}
return this->head;
}
void draw(sf::RenderWindow& window)
{
ptr_list p = this->head;
while (p != NULL)
{
window.draw(p->Planet.shape);
p = p->next;
}
}
void IsItOverLapped()
{
ptr_list p1 = this->head;
ptr_list p2 = this->head;
// bool collision = false;
sf::FloatRect shape1;
sf::FloatRect shape2;
float distance;
float dx;
float dy;
//float distance = std::sqrt((dx * dx) + (dy * dy));
while ((p1 != NULL))
{
//float distance = std::sqrt((dx * dx) + (dy * dy));
while (p2 != NULL)
{
shape1 = p1->Planet.shape.getGlobalBounds();
shape2 = p2->Planet.shape.getLocalBounds();
dx = (p1->Planet.shape.getPosition().x + (shape1.width / 2)) - (p2->Planet.shape.getPosition().x + (shape2.width / 2));
dy = (p1->Planet.shape.getPosition().y + (shape1.height / 2)) - (p2->Planet.shape.getPosition().y + (shape2.height / 2));
distance = std::sqrt((dx * dx) + (dy * dy));
if (distance <= (shape1.width / 2) + (shape2.width / 2))
//if (p2->Planet.shape.getGlobalBounds().intersects(p1->Planet.shape.getLocalBounds()))
{
std::cout << "Collision Detected" << std::endl;
//p2 = p2->next;
//collision = true;
}
else
{
std::cout << "No Collision Detected" << std::endl;
//collision = false;
}
/*if (p2->Planet.shape.getLocalBounds().intersects(p1->Planet.shape.getLocalBounds()))
std::cout << "collision";
std::cout <<'\n'; */
p2 = p2->next;
}
p1 = p1->next;
}
//return collision;
}
}
};
因此,我希望能够在屏幕上绘制形状。 问题是我难以检测形状的碰撞。 如果能够检测到碰撞,则可以更改重叠形状的位置。 但是我为此付出了很多努力。 我有一个对象列表。 而且它们在形状,位置等方面都有一些特点。我也尝试过使用if(object1.getLocalBounds.intersects(object2.getLocalbounds()){然后做点事},但是似乎代码没有我已经尝试了很多次,但我真的不知道该怎么处理了。
首先,除非您有充分的理由(或者,如果要明确地编写代码以了解指针和数据结构,否则,请不要构建自己的数据结构(例如ptr_list
)),但也许不要混合使用与碰撞)。 相反,请使用STL-已经不必担心的一件事了。 同时避免new
和delete
。
接下来,请确保您了解所使用的SFML函数。 getLocalRect()
和getGlobalRect()
会在两个不同的坐标系中返回矩形,您不能只是将它们相加/相减并得到有意义的结果。 请查阅SFML文档以获得更清晰的信息。 另外,您应该直接使用sf::Rect::intersects()
而不是自己构建。
您需要考虑的是SFML将对轴对齐的边界框进行相交检查, 而不检查实际的矩形是否相交。 这比正确的矩形检查更为简单和快捷,但是准确性较低。 我将从轴对齐的矩形开始,然后从那里开始。
还可以帮助分离检查重叠的代码( 碰撞检测 )和对其进行响应的代码( 碰撞响应 )。 第一个是不会修改任何状态的简单bool函数,第二个然后执行必要的操作。
p1 = head;
p2 = head;
while (p1)
{
while (p2)
{
// ...
p2 = p2->next;
}
(*)
p1 = p1->next;
}
当代码第一次到达(*)
时,在内部循环中将p2设置为nullptr
。 但是由于您没有在内部循环中将其重置,因此它将在所有其他循环运行中保持不变,从而将列表中的第二个行星与其他任何一个都不进行比较。
此外,当您最初将两个指针都设置为head时,您将比较第一个行星与其自身,这自然会导致碰撞。
解决两个问题的方法:
p1 = head;
while (p1)
{
p2 = p1->next;
// ^ avoid self-comparison
while (p2)
{
// ...
p2 = p2->next;
}
p1 = p1->next;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.