flixel icon indicating copy to clipboard operation
flixel copied to clipboard

Toggling FlxSpriteGroup visibility resets visibility of all sprites in it

Open arm32x opened this issue 4 years ago • 4 comments

  • Haxe version: 4.2.3
  • Flixel version: 4.9.0
  • OpenFL version: 9.1.0
  • Lime version: 7.9.0
  • Affected targets: Tested on Linux and HTML5, probably affects others

Code snippet reproducing the issue:

package;

import flixel.FlxSprite;
import flixel.group.FlxSpriteGroup;
import flixel.FlxState;

class PlayState extends FlxState
{
	override public function create()
	{
		super.create();
		
		// Create an FlxSpriteGroup
		var group = new FlxSpriteGroup(50, 50);
		add(group);
		
		// Add sprites to the group
		var red = new FlxSprite(0, 0).makeGraphic(100, 100, 0xFFFF0000);
		group.add(red);
		var green = new FlxSprite(50, 50).makeGraphic(100, 100, 0xFF00FF00);
		group.add(green);
		
		// Make one invisible
		green.visible = false;
		
		// Toggle the visiblilty of the group
		group.visible = false;
		group.visible = true;
	}
}

Observed behavior: Both sprites are visible at the end of create().

Expected behavior: The green sprite stays invisible, even when the visibility of the FlxSpriteGroup is toggled off and on.

arm32x avatar Sep 11 '21 22:09 arm32x

I think the "bug" makes sense, when you are toggling the group visibility to false it means all objects of the group will not be visible without changing the objects of the group visibility to false, when changing the group to visible again, if the group object visibility was true it will be visible, what if the group object visibility was false it will remain invisible, in my theory

To fix this you could use the forEach method from the FlxGroup

group.forEach(function(object:FlxSprite)) {
  object.visible = true;
}

TheHENOOB avatar Sep 12 '21 00:09 TheHENOOB

I think you've mixed up the observed and expected behaviours in my report.

Currently, when you do group.visible = true, it acts like your forEach call and sets all sprites' visibility to true. I would expect it to work as you described, with the sprite remaining invisible if its visibility was false before changing the group's visibility.

arm32x avatar Sep 12 '21 00:09 arm32x

I think you've mixed up the observed and expected behaviours in my report.

Currently, when you do group.visible = true, it acts like your forEach call and sets all sprites' visibility to true. I would expect it to work as you described, with the sprite remaining invisible if its visibility was false before changing the group's visibility.

Ish, my bad for that one

TheHENOOB avatar Sep 12 '21 00:09 TheHENOOB

FlxSpriteGroups are nasty, I always extend them to remove dumb caveats like the one you mentioned, for example:

typedef SpriteGroup = TypedSpriteGroup<FlxSprite>;

class TypedSpriteGroup<T:FlxSprite> extends FlxSpriteGroup<T>
{
	// Don't set children's exist
	override function set_exists(value:Bool):Bool
	{
		return exists = value;
	}
	
	// Don't set children's visible
	override function set_visible(value:Bool):Bool
	{
		return visible = value;
	}
	
	// similar to super but doesn't check exists
	override function set_x(value:Float):Float
	{
		if (!_skipTransformChildren && x != value)
		{
			var offset:Float = value - x;
			transformChildren(xTransform, offset);
		}
		
		return x = value;
	}
	
	// similar to super but doesn't check exists
	override function set_y(value:Float):Float
	{
		if (!_skipTransformChildren && y != value)
		{
			var offset:Float = value - y;
			transformChildren(yTransform, offset);
		}
		
		return y = value;
	}
}

Geokureli avatar Sep 15 '21 19:09 Geokureli