What am I doing wrong here? FlxMouseEventManager, FlxGroup.forEachAlive, and animation state changes
-
Hi guys,
I've been stumped for a few days on a simple bug - When you click on a member of the Person class, it's supposed to become selected with a box around it, and all other Persons should become deselected. Problem is, the selection part works, but the deselection part does not - All Persons become selected and stay that way, forever. The two animations are single frames, the first being a deselected person, the second being a selected one.
I've verified via trace statements that "deselect" is being called as planned, but for some reason the image isn't changing back.
Any help would be much appreciated, please and thank you!
Code follows: (the unseen "Variables.people" is a FlxGroup containing the people)package com.spacecowboysoftware.voytek; import flixel.FlxG; import flixel.input.mouse.FlxMouseEventManager; import flixel.FlxSprite; import flixel.FlxBasic; class Person extends FlxSprite { var selected:Bool = false; public function new(X:Int, Y:Int) { super(X,Y); loadGraphic("src/data/person.png", true,29,42); FlxMouseEventManager.add(this, null, onMouseUp, null, null, false, true, true, null); animation.add("deselected", [0]); animation.add("selected", [1]); alive = true; } override public function update(elapsed):Void { super.update(elapsed); } override public function kill():Void { super.kill(); } private function onMouseUp(sprite:FlxSprite):Void { trace("onMouseUp"); FlxG.sound.play("assets/data/beep.mp3"); Variables.people.forEachAlive(deselect); selected = true; animation.play("selected"); } private function deselect(F:FlxBasic):Void { trace("Deselected"); if (alive) trace("Alive"); selected = false; animation.play("deselected"); } }
-
First, I recommend setting
animation.frameIndex
instead of adding 1 frame animation and playing it, like this:animation.frameIndex = 1; // instead of animation.play("selected");
So you can then remove these commented out lines in new():
public function new(X:Int, Y:Int) { super(X,Y); loadGraphic("src/data/person.png", true,29,42); FlxMouseEventManager.add(this, null, onMouseUp, null, null, false, true, true, null); //animation.add("deselected", [0]); //animation.add("selected", [1]); //alive = true; //alive is set to true by default }
Second, I think
deselect()
should bestatic
:private static function deselect(person:Person):Void { trace("Deselected"); if (person.alive) trace("Alive"); person.selected = false; person.animation.frameIndex = 0; // set to deselect frame }
Note that the function now has a parameter of Person and sets its
selected
andframeIndex
instead of doing some crazy behavior there.Also Variables.people should be a
FlxSpriteGroup
or even aFlxTypedSpriteGroup<Person>
but it doesn't really matter.
-
@DleanJeans
Thank you for your reply!
I tried the changes you suggested and it's had no effect on the issue so far - The traces still verify that deselect is being called as planned, but it won't switch back to the first frame, even calling the explicit frame index.
Is it possible that a behavior of the mouse click function is somehow re-calling the switch to the second frame? I've had issues in the past where mouse click functions can create strange behavior. (However, the trace statements from the "select" part of the code aren't being called multiple times, so it would have to be some really unexpected behavior if that's the case)
-
My bad! I didn't tell you to also make the
onMouseUp()
functionstatic
too.private static function onMouseUp(person: Person):Void { trace("onMouseUp"); FlxG.sound.play("assets/data/beep.mp3"); Variables.people.forEachAlive(deselect); person.selected = true; person.animation.play("selected"); }
Again, it's now just like
deselect()
. Passing non static function to those functions may yield unexpected behaviors and it could be the one you're experiencing. The reason I said that is because I couldn't guess what the code does from reading it.
-
@DleanJeans Thank you, I will give this a try and report back!