7

How do I get an actor by name in libgdx?

I currently have the following ChangeListener:

    ChangeListener colorPickerListener = new ChangeListener()
    {
        public void changed(ChangeEvent event, Actor actor)
        {
            //Popup Window
            toolboxStage.addActor(blockWindow);
            //toolboxStage.getRoot().removeActor(blockWindow);
            Gdx.app.log("LevelEditorScreen", "Color Picker Selected");
            Gdx.app.log("LevelEditorScreen", "HUD Width: " + HUD_WIDTH);

            Gdx.input.setInputProcessor(toolboxStage);
        }
    };

The actor that is above is the actor that has been touched. Once this particular actor has been touched I need to change the color of another actor. How exactly do I go about getting that actor by its name?

joshmmo
  • 1,062
  • 2
  • 13
  • 28

3 Answers3

22

I would like to point out that there is already a method which finds an Actor by name.

It works like this: stage.getRoot().findActor(name).

No need to implement it yourself. :)

noone
  • 19,520
  • 5
  • 61
  • 76
  • 2
    Every time I forget this and remember the correct search terms to find this question again I'm sad that this wasn't marked as the answer. Thank you! – James Skemp Jun 21 '15 at 18:49
5

First you need to set a name for your Actor: (Actor#setName)

myactor.setName("myactor");

Then you can get all the Actors in the Stage this is in, like this: (Stage#getActors)

Array<Actor> stageActors = mystage.getActors();

Then, you can use Actor#getName to check all the Actors for that name:

int len = stageActors.size;
for(i=0; i<len; i++){
    Actor a = stageActors.get(i);
    if(a.getName().equals("myactor")){
        //a is your Actor!
        break;
    }
}

But it would be easier and more performant if you kept a reference to all your Actors and use it instead.

Daahrien
  • 10,190
  • 6
  • 39
  • 71
1

I would recoment to use the already given functionality of the Group. Every Stage has an root Group and this implements the lookup for an actor by name. The code for it is more secure than the given inside of the answer in case you use the Grouping system.

The code of the Group looks like this and is more secure because it also looks inside of a group if you add a group to the stage.

    /** Returns the first actor found with the specified name. Note this recursively compares the name of every actor in the group. */
    public Actor findActor (String name) {
            Array<Actor> children = this.children;
            for (int i = 0, n = children.size; i < n; i++)
                    if (name.equals(children.get(i).getName())) return children.get(i);
            for (int i = 0, n = children.size; i < n; i++) {
                    Actor child = children.get(i);
                    if (child instanceof Group) {
                            Actor actor = ((Group)child).findActor(name);
                            if (actor != null) return actor;
                    }
            }
            return null;
    }

Link to Group Class

If you need to search alot of times to hold an refrence of the Actor. If not just use the serch method.

bemeyer
  • 6,154
  • 4
  • 36
  • 86
  • 1
    I don't think it is more secure, because `stage.getActors()` should also contain *all* actors. Iterating through that list might even be more performant. But I'd still go with the already existing API. I just don't see how your answer contains any value to the two answers which were already given before. – noone Jan 18 '14 at 11:26
  • @noone "`stage.getActors()` should also contain all actors." I don't know man, if you put a `Group` in that `Stage`, and put 10 `Actor`s inside the group `stage.getActors()` will only return the `Group` actor, it won't return the 10 actors inside that `Group`. I think this is what he meant when he said "Grouping System". – centenond Jun 18 '20 at 03:38