Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlxSpriteGroup alpha=0 problem #1353

Closed
Txori opened this issue Oct 29, 2014 · 16 comments
Closed

FlxSpriteGroup alpha=0 problem #1353

Txori opened this issue Oct 29, 2014 · 16 comments

Comments

@Txori
Copy link
Contributor

Txori commented Oct 29, 2014

Whenever you set the FlxSpriteGroup alpha to 0, it wont show up again when you change its alpha after that, unlike the FlxSprite...

Here's the snippet:

package;

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

class PlayState extends FlxState
{
   private var spriteGroup:FlxSpriteGroup;
   private var sprite:FlxSprite;
   private var t:Float = 0;

   override public function create():Void
   {
      super.create();

      spriteGroup = new FlxSpriteGroup(400, 100);
      spriteGroup.add(new FlxSprite().makeGraphic(100, 100, 0xFFFF0000));
      add(spriteGroup);

      sprite = new FlxSprite(400, 300).makeGraphic(100, 100, 0xFF00FF00);
      add(sprite);
   }

   override public function update(elapsed:Float):Void
   {
      super.update(elapsed);
      t += .01;
      sprite.alpha = spriteGroup.alpha = Math.abs(Math.floor(100 * Math.cos(t)) / 100);
      trace(sprite.alpha);
   } 
}

I've only tried on Flash and Neko.

And here's my halelib version:

actuate: [1.7.5]
flixel-addons: [1.1.0]
flixel-demos: [1.1.1]
flixel-templates: [1.0.2]
flixel-tools: [1.0.2]
flixel-ui: [1.0.2]
flixel: [3.3.5]
hxcpp: [3.1.39]
lime-tools: [1.5.7]
lime: [1.0.1]
openfl-samples: [1.3.0]
openfl: [2.0.1]
swf: [1.5.2]

@Txori
Copy link
Contributor Author

Txori commented Oct 29, 2014

I've found a solution here: #701

So in my example:

        sprite.alpha = Math.abs(Math.floor(100 * Math.cos(t)) / 100);
        spriteGroup.setAll("alpha", sprite.alpha);

is now working, but still it's a bit weird having to restore the FlsSpriteGroup alpha like that.

@sruloart
Copy link
Contributor

After reading the previous thread, I'm definitely with the "just document it" approach, that stuff is complicated.

@Gama11
Copy link
Member

Gama11 commented Oct 29, 2014

@Txori I recommend you use forEach() instead of setAll() (which uses Reflection and has been removed on the dev branch).

spriteGroup.forEach(function(s)
{
   s.alpha = sprite.alpha;
});

@Txori
Copy link
Contributor Author

Txori commented Oct 29, 2014

All right, thank you.

@MSGhero
Copy link
Member

MSGhero commented Oct 29, 2014

Would it make sense to include the for each in the spriteGroup.alpha setter?

@Txori
Copy link
Contributor Author

Txori commented Oct 31, 2014

Yes, I think that would be a good solution.
it would allow to simply change the alpha without getting the alpha = 0 bug and having to search for the forEach method in the doc... I tried to do it but I'm not sure how to override set_alpha in FlxSpriteGroup :)

@MSGhero
Copy link
Member

MSGhero commented Nov 7, 2014

I can do this tonight, but do we want the group's setter to set the child's alpha or be multiplied by its true alpha? The latter requires a separate trueAlpha var.

@Txori
Copy link
Contributor Author

Txori commented Nov 9, 2014

Sorry for the late response. I talked about it with a friend and we come to the conclusion that multiplied by its true alpha is the better solution. It would avoid errors like sprites in the group that becomes visible although they should not, because of their individual alpha settings.

@MSGhero
Copy link
Member

MSGhero commented Nov 9, 2014

Maybe something like

// FlxSpriteGroup.hx

inline function multAlphaTransform(...) {
   if (Alpha == 0) Sprite.oldAlpha = Sprite.alpha;
   Sprite.alpha *= Alpha;
}

inline function divAlphaTransform(...) {
   if (Alpha == 0) Sprite.alpha = Sprite.oldAlpha;
   else Sprite.alpha /= Alpha;
}

Where multAT is used in add and divAT in remove.

This directly sets the child sprite's alpha which I'm not a big fan of, but the alternative is to change every instance of sprite.alpha in the codebase to sprite.trueAlpha * sprite.alphaMult or something. Plus if you set the parent's alpha to 0 twice, it'll overwrite oldAlpha.

Suggestions?

@IBwWG
Copy link
Contributor

IBwWG commented Jun 16, 2016

OK, but what about cases like in #1870? For example, you fade out a flxspritegroup, and then go to fade it back in--nothing happens, because after fading out, all of its children were alpha=0. I think having a relative alpha would be a nice idea. Just like how the volume mixer on Windows works--as you raise/lower the master volume, all the other volumes move relative to it. But they don't suddenly stick at 0 just because you hit 0 with the master at one point.

@MSGhero
Copy link
Member

MSGhero commented Jun 16, 2016

If we end up having a relative alpha, would it make sense to also make position, rotation, etc that way? To where there's an internal _var and then a getter that looks like return _var + parent.var until parent is null.

The setter would have to just affect the internal var and also set the dirty flag on this and any children.

@IBwWG
Copy link
Contributor

IBwWG commented Jun 16, 2016

That'd be cool. Add .color to the list too :)

@DataRogue
Copy link

+1

When setting the alpha in a FlxSpriteGroup it should set each child's alpha to the same value in my opinion. Regardless the current interaction is weird and inconsistent as it allows FSGroup.alpha = 0 to work, but not FSGroup.alpha = 1.

@codingthat
Copy link

@MSGhero and actually it should be parent * child, not parent + child, I guess. The only problem is, FlxSprite has no notion of "parent," and a side effect of that is, there's nothing stopping a sprite from having multiple parent groups.

There was some discussion in another thread, IIRC, of merging the two concepts, so sprites were just nestable. That would make this issue a lot easier to solve.

@MSGhero
Copy link
Member

MSGhero commented Oct 8, 2017

The consensus in a random chat on Discord was that FSG should have some alphaHack property for when the alpha is set to 0. Something like

override public function set_alpha(f:Float):Float {
    if (f == 0) {
        alphaHack = true;
        f = 0.000000001;
        visible = false;
    }
    // etc
}

override public function get_alpha():Float {
    if (alphaHack) return 0;
    return _alpha;
}

@Jarrio
Copy link

Jarrio commented Oct 8, 2017

override public function set_alpha(value:Float):Float {
    if (value > 0) {
        visible = true;
        return this.alpha = value;
    }

    visible = false;
    return this.alpha = 0.001;
}

override public function get_alpha():Float {
    return this.alpha;
}

Given the current implementation, I think that's the cleanest solution. I don't know if it's worth creating an internal variable for this. If you really wanted to have the get return 0 then you could just use visible:

override public function get_alpha():Float {
    return (this.visible) ? this.alpha : 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants