0
\$\begingroup\$

Here is a code snippet of the relevant section in my render loop. My intention was to make the actor who was currently focused blinking, to indicate that it was the currently selected UI element. But after noticing that setting the condition of the if statement to == was giving me THE EXACT OPPOSITE of what I expected (namely: all elements that had previously had focus that were not the currently focused element of the stage were blinking), I changed it to the opposite and received the desired outcome.

QUESTION: What fundamental lesson of how Actions work am I missing? Why is this happening?

    Actor currentFocus = stage.getKeyboardFocus();

    if(currentFocus != gameVolumeSlider){
        gameVolumeSliderLabel.addAction(Actions.forever(Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
    }
    if(currentFocus != musicVolumeSlider){
        musicVolumeSliderLabel.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
    }
   if(currentFocus != backButton){
        backButton.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
    }

    stage.act(Gdx.graphics.getDeltaTime());
    stage.draw();
\$\endgroup\$
  • \$\begingroup\$ Where do you stop/remove the action when you no longer want it to be active? \$\endgroup\$ – DMGregory Dec 31 '18 at 18:59
  • \$\begingroup\$ That's the crazy thing! I was trying : Actions.removeActor(gameVolumeSliderLabel); Actions.removeActor(musicVolumeSliderLabel); And before that ex.: musicVolumeSlider.removeActions(); ... within the scope of the if statements. So, if I was trying to make the back button blink, I would removeActions() from the labels for the sliders... but they don't seem to be doing anything and leaving this as it is is producing the desired behavior. \$\endgroup\$ – cafeTechne Dec 31 '18 at 19:03
  • \$\begingroup\$ Want to show us that version? We might be able to spot the error there. I think it goes without saying that adding and adding and adding without ever removing is almost certainly not the way you want to solve this. \$\endgroup\$ – DMGregory Dec 31 '18 at 19:09
  • \$\begingroup\$ Here is a link to a post on the LIBGDX forums where I posted the entirety of the code. I'm just curious why it's doing this as it is right now. badlogicgames.com/forum/viewtopic.php?f=15&t=28629 \$\endgroup\$ – cafeTechne Dec 31 '18 at 19:10
  • \$\begingroup\$ The only functional difference was in setting the == to != in the if statements. When the headers were set to == every Actor BUT the one that was true would blink. What is the best way to dynamically add Actions like this? Meaning, what is the general solution to problems of this type using these libraries? \$\endgroup\$ – cafeTechne Dec 31 '18 at 19:51
0
\$\begingroup\$

@DMGregory was right: adding it over infinitely is NOT the correct way to handle this--so dealing with it in the render() method is NO-GO.

How I solved this is as follows. I checked for the position in the Input Handlers and then added/removed the blinking behavior in a procedural fashion:

 stage.setKeyboardFocus(gameVolumeSlider);

 gameVolumeSliderLabel.addAction(Actions.forever(Actions.sequence(fadeIn(.5f),fadeOut(.5f))));

 stage.addListener(new InputListener() {
        public boolean keyDown (InputEvent event, int keycode) {
            if (keycode == Keys.DOWN  || keycode == Keys.S) {
                if (buttonToggleState == 3) {
                    buttonToggleState = 1;
                } else {
                    buttonToggleState++;
                }
                System.out.println(buttonToggleState);

                if(buttonToggleState == 1){
                    gameVolumeSliderLabel.addAction(Actions.forever(Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
                    backButton.clearActions();
                    backButton.addAction(fadeIn(.5f));
                }
                if(buttonToggleState == 2){
                    musicVolumeSliderLabel.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
                    gameVolumeSliderLabel.clearActions();
                    gameVolumeSliderLabel.addAction(fadeIn(.5f));
                }
                if(buttonToggleState == 3){
                    backButton.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
                    musicVolumeSliderLabel.clearActions();
                    musicVolumeSliderLabel.addAction(fadeIn(.5f));
                }


            }

            if (keycode == Input.Keys.UP || keycode == Keys.W) {
                if (buttonToggleState == 1) {
                    buttonToggleState = 3;
                } else {
                    buttonToggleState--;
                }
                System.out.println(buttonToggleState);


                if(buttonToggleState == 1){
                    gameVolumeSliderLabel.addAction(Actions.forever(Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
                    musicVolumeSliderLabel.clearActions();
                    musicVolumeSliderLabel.addAction(fadeIn(.5f));
                }
                if(buttonToggleState == 2){
                    musicVolumeSliderLabel.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
                    backButton.clearActions();
                    backButton.addAction(fadeIn(.5f));
                }
                if(buttonToggleState == 3){
                    backButton.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.sequence(fadeIn(.5f),fadeOut(.5f))));
                    gameVolumeSliderLabel.clearActions();
                    gameVolumeSliderLabel.addAction(fadeIn(.5f));
                }


            }

So in conclusion it was doing the exact opposite because this was unintended behavior. The render loop was calling the if that was evaluating to true over and over and over again and I think it was keeping that method call from animating because it was constantly stuck in a loop re-adding those instructions(?) That's my theory, either way... this is how you solve it and add the desired blinking behavior to Actors on a Table on a Stage with keyboard input in LIBGDX.scene2d.ui.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.