I've got a roughly 500x50 graphic of a lockpick that I need to be able to rotate very finely while doing pixel-perfect collision detection against the lock object.
There's no way to do pixel perfect collision detection in Flixel, so I'm using the Power Tools' FlxCollision class to accomplish this. The problem is that this class only works with rotated sprites if they were loaded with loadRotatedGraphic.
...the problem with that is that it only allows you to rotate to discrete angles. You pass it how many angles you need to be able to rotate to and it, I think, pre-prepares all the frames for you.
And the reason that's a problem is because I need such fine rotation. I need at least 128 different angle values, but when I do that I get Error 2015: Invalid Bitmap
, which I'm assuming is because the resulting 128 frames of a 500x50 lockpick results in a bitmap larger than AS3's limit. I can load the graphic using loadGraphic instead, which I think just calculates the rotated image real-time, but then FlxCollision won't notice that it's been rotated. Another problem is that with the pre-rotated graphics, you can't rotate about a specific point, and I need the lockpick to rotate around the tip of its handle.
...so how the heck do I do pixel perfect collision against a rotated sprite? I'm trying to mod FlxSprite so that FlxCollision will see the rotated sprites even when they're calculated in real time, and to do this I Ctrl+F'd through the class looking for appearances of "angle", the variable that you set to rotate a sprite, but all I can find is some obscure calculation in it's used to compute a frame number, and I can't find a single call to any function that looks like it's doing real-time bitmap rotating.
So, I was able to solve this problem. All FlxSprites hold the bitmap for their currently visible frame in an internal variable called framePixels. If you load a graphic using loadGraphic, then you can do real-time rotation: in this case, the draw() function rotate s framePixels "at the last minute", right before rendering it. Meaning the rotated bitmap is not stored, and FlxCollision has no way of seeing it. FlxCollision runs its collision checks against the unrotated bitmap.
So this is what need to be done:
- Get the sprite to store its rotated graphic somewhere rather than just sending it to the renderer and then abandoning it.
- Get FlxCollision to use that stored rotated graphic rather than framePixels.
This is summarized in the following diagram. Flixel's default logic is in black, my changes are in red.
I applied all of this in a sub-class of FlxSprite that I called PerfectCollisionSprite.