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 be static:

    	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 and frameIndex instead of doing some crazy behavior there.

    Also Variables.people should be a FlxSpriteGroup or even a FlxTypedSpriteGroup<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() function static 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!


Log in to reply
 

Looks like your connection to HaxeFlixel was lost, please wait while we try to reconnect.