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()){然后做点事},但似乎代码不在if方面。我已经尝试了很多次,但我确实不这样做再也不知道该如何处理了。
答案 0 :(得分:3)
首先,除非有充分的理由(或者,如果要明确地编写代码以了解指针和数据结构),否则不要构建自己的数据结构(例如ptr_list
),但是那么也许不要将其与碰撞混合使用)。相反,请使用STL-已经不必担心的一件事了。还有avoid new
and delete
。
接下来,请确保您了解所使用的SFML函数。 getLocalRect()
和getGlobalRect()
会在两个不同的坐标系中返回矩形,您不能只是将它们相加/相减并得到有意义的结果。请查阅SFML文档以获得更清晰的信息。另外,您应该直接使用sf::Rect::intersects()
而不是自己构建。
您需要考虑的是,SFML将对与轴对齐的边界框进行相交检查,而不检查实际矩形是否相交。这比正确的矩形检查更为简单和快捷,但是准确性较低。我将从对齐轴的矩形开始,然后从那里开始。
可能还有帮助的是,将检查重叠的代码(碰撞检测)和对其进行反应的代码(碰撞响应)分开。第一个是简单的布尔函数,它不会修改任何状态,第二个然后执行必要的操作。
答案 1 :(得分:0)
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;
}