flixel
flixel copied to clipboard
Better way of handling button input
All button classes (FlxButton, FlxInputText, FlxSlider, etc.) check for mouse input during the update phase. There is a problem with this: if the user clicks where there are two sprites overlapping (for example, an opened FlxUIDropDownMenu list overlapping an FlxUIButton), both sprites will detect the mouse being pressed, even if the user only meant to press the one in front. I suggest there should be a better way of handling mouse input, and I've thought of two ways:
- Use FlxMouseEvents: The FlxMouseEventManager iterates through the added sprites from the last one added to the first one added (so there's priority to sprites in front), and by default if a sprite overlap is detected then no more overlaps will be accounted for. An instance of it is already added to the game automatically, but no Flixel classes use it. With this change, all the button classes would automatically add themselves to the manager along with the corresponding events, and remove themselves when they're destroyed. An option could be added to their constructors to prevent this so they can be manually added later if the programmer wishes.
-
Add a separate function to check for mouse input: FlxBasics will get a new function (for now let's call it
checkMouseInput
) which will returntrue
orfalse
, withtrue
signifying that mouse input was detected. For FlxGroup and by extension FlxState, it would look something like this:
override public function checkMouseInput():Bool
{
if (length == 0)
return false;
var i:Int = length - 1;
var basic:FlxBasic = null;
while (i >= 0)
{
basic = members[i--];
if (basic != null && basic.exists && basic.active && basic.checkMouseInput())
{
return true;
}
}
return false;
}
It goes through the group's members starting from the last added object, and if any checkMouseInput
calls return true
, then the function stops so no more sprites are checked. For FlxState, this would be called during tryUpdate
, right after the regular update
is called. A variable could be added to toggle if the function stops or keeps going after an overlap is detected, something like mouseChildren
.
I think I have an idea for doing it, I’ll create a pull request to do it.
tbh I think the best answer is "Use FlxMouseEvents", I don't think I want to implement a default "mouse-blocking" system for normal buttons because there's many different ways to do it with different trade-offs and enabling such a feature by default may break existing games that already implemented their own system, meaning it would have to wait for the next major version
Edit: I'm open to other solutions, but I expect them to be a breaking change