SFML community forums
Help => Graphics => Topic started by: Mashandar on April 29, 2009, 05:46:44 pm
-
Hello,
I finally got my pixel-perfect collision detection working but It's acting
funky after using FlipX(true) on a sprite. when I check GetPixel to see
what's going on, it's reporting that pixels are there, when, visually
nothing is seen, so the pixels shouldn't be there (the alpha values
of these pixels is 255).
I have uploaded the image to imagebin and a sample test
code to pastebin which shows this.
Code: http://pastebin.com/m53275387
Image: http://imagebin.ca/view/5qzsUj5.html
I'm rather baffled, so I'm hoping someone can help.
EDIT: in the given example, if compiled, you'll see the flipped sprites (top sprites) colliding permaturely (stopping before reaching the other sprite)
and the unflipped sprites (bottom sprites) colliding as they should.
-
Are you indexing inverse coordinates in the GetPixel reader? If FlipX(True) works the way I think it works, it just sets a negative scale factor when blitting to the screen. The image itself remains unaffected in memory.
--Edit--
After looking at your source code, you need to make the GetPixel check the coordinates backwards relative to the center position on one or both images depending on whether they are flipped or not.
-
Oh, ok.
I'll try that when I get the chance.
-
Sprite::GetPixel already takes FlipX/FlipY flags in account.
-
Well, I'm still stumped. I tried some different things, like getting pixels from the source image itself while taking the flipping into account (I kinda knew it wouldn't work but thought it couldn't hurt to give it a go.) with no luck still.
I would really like to get this working, so if anyone has any suggestions, please let me know.
-
Mashandar: Your code (from pastebin) seems ok.
Sprite::GetPixel already takes FlipX/FlipY flags in account.
The function has a bug.
////////////////////////////////////////////////////////////
/// Get the color of a given pixel in the sprite
/// (point is in local coordinates)
////////////////////////////////////////////////////////////
Color Sprite::GetPixel(unsigned int X, unsigned int Y) const
{
if (myImage)
{
unsigned int ImageX = mySubRect.Left + X;
unsigned int ImageY = mySubRect.Top + Y;
if (myIsFlippedX) ImageX = mySubRect.GetWidth() - ImageX;
if (myIsFlippedY) ImageY = mySubRect.GetHeight() - ImageY;
return myImage->GetPixel(ImageX, ImageY) * GetColor();
}
else
{
return GetColor();
}
}
if (myIsFlippedX) ImageX = mySubRect.GetWidth() - ImageX;
if (myIsFlippedY) ImageY = mySubRect.GetHeight() - ImageY;
should be
if (myIsFlippedX) ImageX = mySubRect.GetWidth() - ImageX - 1;
if (myIsFlippedY) ImageY = mySubRect.GetHeight() - ImageY - 1;
You could wait for this to be fixed or do a getpixel on the image like this:
if(sprite.IsFlippedX()) pxX=image.GetWidth()-pxX-1;
if(sprite.IsFlippedY()) pxY=image.GetHeight()-pxY-1;
Good luck!
-Martín
-
Aha!
Thanks, that worked perfectly!
I recompiled SFML on my machine with that for now, hopefully it'll be fixed in future SFML releases too, as that bug had me confused for a week. (I assumed it was my code's fault....as it tends to be most of the time)
-
I usually think that too, but your code was ok and I had the SFML source opened so I checked on that just in case.
One recommendation: Before the per-pixel collisions, you could check if the sprites' rects intersect. This will save you a lot of CPU.
if(!s1.Intersects(s2))
return false;
This is not valid for rotation thou, but Sprite::GetPixel doesn't work with rotation/scaling anyway.
Good luck!
-Martín
-
I already check a rect intersection in my game, I don't have it in my sample code to keep things simple.
as for the GetPixel not handling rotation and scaling, isn't that what
TransformToLocal is for? I've been using sprites of many different
scales and (after this fix), have been running/colliding perfectly.
-
The function has a bug.
It's fixed, thanks for your help :)
-
Hooray! :D
-
as for the GetPixel not handling rotation and scaling, isn't that what
TransformToLocal is for? I've been using sprites of many different
scales and (after this fix), have been running/colliding perfectly.
You're absolutely right!
Thanks for the clarification.
-Martín