I wrote a small chunk of code for my SFML game that (should) cycle through every entity and check if it collides with the given entity. If it finds a match, it returns the entity (pointer) and breaks from the loop.
However, this is not what happens. It ALWAYS returns a value, even if it's far away from any other entity. Here is the code:
[php]
TwoDEntity * GameManager::IsCollidingAny(TwoDEntity * ent,sf::Uint8 AlphaLimit)
{
int i;
for(i = 0; i < ulist.size(); i++)
{
if(ulist.at(i)->GetCanCollide())
{
TwoDEntity * check = dynamic_cast<TwoDEntity*>(ulist.at(i)); //uses dynamic_cast to get the key state //ulist.at(i);
if(IsColliding(ent->GetSprite(),check->GetSprite(),AlphaLimit))
{
//return check;
//return 0;
return check;
}
check = NULL;
delete check;
}
else
{
continue;
}
}
return NULL;
}
[/php]
The algorithim (Some SFML knowledge probably needed):
[php]
bool Collision::PixelPerfectTest(const sf::Sprite& Object1, const sf::Sprite& Object2, sf::Uint8 AlphaLimit)
{
//Get AABBs of the two sprites
sf::IntRect Object1AABB = GetAABB(Object1);
sf::IntRect Object2AABB = GetAABB(Object2);
sf::IntRect Intersection;
if (Object1AABB.Intersects(Object2AABB, &Intersection)) {
//We've got an intersection we need to process the pixels
//In that Rect.
//Bail out now if AlphaLimit = 0
if (AlphaLimit == 0) return true;
//There are a few hacks here, sometimes the TransformToLocal returns negative points
//Or Points outside the image. We need to check for these as they print to the error console
//which is slow, and then return black which registers as a hit.
sf::IntRect O1SubRect = Object1.GetSubRect();
sf::IntRect O2SubRect = Object2.GetSubRect();
sf::Vector2i O1SubRectSize(O1SubRect.GetWidth(), O1SubRect.GetHeight());
sf::Vector2i O2SubRectSize(O2SubRect.GetWidth(), O2SubRect.GetHeight());
sf::Vector2f o1v;
sf::Vector2f o2v;
//Loop through our pixels
for (int i = Intersection.Left; i < Intersection.Right; i++) {
for (int j = Intersection.Top; j < Intersection.Bottom; j++) {
o1v = Object1.TransformToLocal(sf::Vector2f(i, j)); //Creating Objects each loop :(
o2v = Object2.TransformToLocal(sf::Vector2f(i, j));
//Hack to make sure pixels fall withint the Sprite's Image
if (o1v.x > 0 && o1v.y > 0 && o2v.x > 0 && o2v.y > 0 &&
o1v.x < O1SubRectSize.x && o1v.y < O1SubRectSize.y &&
o2v.x < O2SubRectSize.x && o2v.y < O2SubRectSize.y) {
//If both sprites have opaque pixels at the same point we've got a hit
if ((Object1.GetPixel(static_cast<int> (o1v.x), static_cast<int> (o1v.y)).a > AlphaLimit) &&
(Object2.GetPixel(static_cast<int> (o2v.x), static_cast<int> (o2v.y)).a > AlphaLimit)) {
return true;
}
}
}
}
return false;
}
return false;
}
[/php]
Do you see anything that could falsely return a non-NULL value, O great programming gods?
...
You only have one return statement that can return a non-zero value. And it's only reached if IsColliding returns true, which is a function we can't see. We can't help you.
Regardless,
[cpp]
check = NULL;
delete check;
[/cpp]
You might wanna switch those two lines :)
Sorry, I've never been good at Programming posts. IsColliding is just a abstraction of another function, which is the algorithim. I'll post it.
To the best of my knowledge, it returns true if there is a collision and false if there isn't. Pretty simple.
Sorry, you need to Log In to post a reply to this thread.