flixel
flixel copied to clipboard
Collision overlap flags and separation
I've run into an issue with the way collision flags and separation are handled.
Here's the issue:
I have a handful of objects that all have custom collision code that depends on knowing: which 'side' they are colliding with (FLOOR, CEILING, etc), AND their velocity at the time of collision.
Trying to handle this within the current logic is not working.
If I just try to do FlxG.collide with a callback: FlxG.collide(objectsA, objectsB, callback);, then when FlxObject.separate is called, before my callback, it's changing the velocity of my objects, so I can't reliably handle their collsion.
If I try to use FlxG.overlap, and use the notifier: FlxG.overlap(objectsA, objectsB, callback, notifier);
And I setup my notifier like this:
private function notifier(A:FlxObject, B:FlxObject):Bool
{
A.specialCollisionLogic();
return FlxObject.separate(A, B);
}
Then the collision flags have not been set yet, so I don't know what side is colliding...
I came up with a solution that does work, but it creates performance issues since it's checking everything twice as often:
private function notifier(A:FlxObject, B:FlxObject):Bool
{
FlxObject.updateTouchingFlags(A, B);
A.specialCollisionLogic();
return FlxObject.separate(A, B);
}
This does pretty much exactly what I want it to do, except it's basically calling computeOverlapX and computeOverlapY twice per update, and it's killing my performance.
So, I think there needs to be someway to easily insert some kind of behavior into the FlxObject.separate routine in order to sort of 'pre-collide' after the collision flags have been set.
I'm not sure what the best implementation would be... maybe add a new parameter for a function to call in separate? Ideas?
I guess something like shouldSeparate:FlxObject->FlxObject->Bool as a paramter for separate might work? Basically an additional condition that has to return true for separation to occur. Even that might not be flexible enough if you want to handle x and y separation separately though?
This would change FlxG.collide() to:
public static inline function collide(?ObjectOrGroup1:FlxBasic, ?ObjectOrGroup2:FlxBasic, ?NotifyCallback:Dynamic->Dynamic->Void, ?ShouldSeparate:FlxObject->FlxObject->Bool):Bool
{
return overlap(ObjectOrGroup1, ObjectOrGroup2, NotifyCallback, FlxObject.separate.bind(_, _, ShouldSeparate));
}
I'm not sure if bind() has any performance implications here, which could be relevant as this code is executed every frame...
Doesn't feel very elegant either, but that might just be caused by inflexible flixel's collision system is in general.
So, I DO want separate to occur, I just want to intercept it between setting the collision flags and actually messing with my velocity.
The issue is that I CAN produce 'correct' results by calling updateCollisionFlags, then doing my stuff, and then calling FlxObject.separate, but this creates a ton of lag/performance issues...
The way the collision currently works is:
separate calls separateX, and then separateY.
In separateX, it calls updateCollisionFlagsX, and then in separateY it calls updateCollisonFlagsY.
Whereas, calling updateCollisionFlags calls updateCollisionFlagsX and updateCollisionFlagsY without separate being involved at all..
I think the 'correct' fix is to have them totally separated out somehow so that separateX calls updateCollisionFlagsX and then, optionally, allows you to call a function right then - or something?, before it does the rest of separateX's logic...
I can see where the problem is but it's hard to explain it... sorry...
I understood what you meant. ;) Perhaps I didn't make clear enough that shouldSeparate would be called halfway through separate / before the actual separation occurs.
Okay, but then I would still need to call separate - or somehow otherwise copy all of that logic to a new function to be called after my other logic kicks off... not ideal...
I mean, I can certainly handle making these changes - I don't know if it's really the way to go or not? The other thing to do is setup a function in FlxObject called preCollide maybe, that separateX/separateY calls? I'm not sure what makes sense...
Anything new on this?