Libgdx передает действия актера другому актеру - PullRequest
0 голосов
/ 26 апреля 2018

Хорошо, поэтому я пытаюсь украсить класс актера Libgdx другими действиями

 public Shake(Button buttonToBeDecorated) extends ButtonDecorator {
      super(buttonToBeDecorated);
      Array<Action> actions = buttonToBeDecorated.getActions();

      for (Action action : actions)
            addAction(action);

      addAction(Actions.forever(new SequenceAction(
             Actions.moveBy(10, 0, 0.5f),
             Actions.moveBy(-10, 0, 0.5f)))
      );

 }

однако действия из класса toBeDecorated (которые также заключены в SequenceAction) не применяются к экземпляру Shake. Я уверен, что действия пройдены правильно, потому что я могу их распечатать. Но я не получаю комбинированный эффект, может быть, некоторые из вас знают, почему? Спасибо

РЕДАКТИРОВАТЬ: (на основе нового ответа от @DHa)

Мне кажется, я понял этот обходной путь для группы, который вы представили. Однако я все еще не могу заставить это работать. Для этого примера давайте предположим, что мы украшаем объект кнопки с помощью действия Shake, а затем с помощью действия FadeOut (оба этих класса имеют переменную «Group», расширенную от родительского класса ButtonDecorator). Таким образом, создание этого типа объекта будет выглядеть так:

Button button = new Decorators.FadeOut(new Decorators.Shake(new Buttons.PlayButton()));

И классы:

//Shake class - we just simply add Shake actor to group and then add a specific action
//this works perfectly fine by itself - new Decorators.Shake(new Buttons.PlayButton())
public static class Shake extends ButtonDecorator {
    public Shake(Button buttonToBeDecorated) {
        super(buttonToBeDecorated);
        group.addActor(this);
        group.addAction(Actions.forever(new SequenceAction(
                Actions.moveBy(10, 0, 0.5f),
                Actions.moveBy(-10, 0, 0.5f))));

    }
}

//In FadeOut we are trying to decorate Shake object with another Action
public static class FadeOut extends ButtonDecorator {
    public FadeOut(Button buttonToBeDecorated) {
        super(buttonToBeDecorated);
        Array<Action> actions = buttonToBeDecorated.group.getActions(); //getting actions from Shake
        group.addActor(buttonToBeDecorated);
       /* I'm guessing that the whole workaround is in this line. We are adding
          Shake-actor to FadeOut group so Shake-actions should no longer apply
          to Shake-object and can be applied to our new FadeOut button */

        group.addActor(this); //Adding FadeOut to it's own group
        for (Action action : actions) 
            group.addAction(Actions.parallel(action,new SequenceAction(Actions.fadeOut(3), Actions.fadeIn(3)))) 
            //besides adding shake actions to FadeOut object we are also adding parallel fadeout action



    }
}

Я не знаю, почему, но все же только одно действие (затухание) применяется к созданному объекту

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Используйте группового актера, чтобы объединить нескольких актеров. Действия, примененные к этой группе, будут применены ко всем участникам группы.

Group group = new Group();

group.addActor(actor1);
group.addActor(actor2);

group.addAction(...);

Однако один актер может быть только частью одной группы, поэтому вы не можете смешивать и сопоставлять действия между разными актерами.

Например:

Group group1 = new Group();

group1.addActor(actor1);
group1.addActor(actor2);

Group group = new Group();

group2.addActor(actor2);
group2.addActor(actor3);

group1.addAction(...); // will only apply to actor1 since actor2 left group1 when joining group2

Я придумал гораздо лучший ответ, чем мой предыдущий, другой ответ все еще технически верен, поэтому я тоже буду его держать.

0 голосов
/ 26 апреля 2018

Каждое действие имеет одну цель субъекта, поэтому не должно быть возможности назначить одно и то же действие нескольким субъектам. Вам нужно будет скопировать действия для достижения желаемого эффекта.

Что должно произойти, когда вы назначаете действие второму действующему субъекту, так это то, что цель действия переключается на второго действующего лица, а не оба актера, которые теперь являются целью действия.

Актер

public void addAction (Action action) {
    action.setActor(this);

Действие

public void setActor (Actor actor) {
    this.actor = actor;
    if (target == null) setTarget(actor);

MoveByAction (тот, который вы используете)

protected void updateRelative (float percentDelta) {
    target.moveBy(amountX * percentDelta, amountY * percentDelta);
}

Ответ на редактирование:

Новое решение оборачивает действие, а не копирует его, оно не будет иметь большого значения по сравнению с оригиналом, действия не могут быть использованы более чем для одной цели одновременно. Основная проблема в том, что у актеров нет действий (кроме бухгалтерии), у действий есть особые цели, на которые они действуют.

Я вижу некоторые способы обойти это (в порядке моей рекомендации):

  1. Если действия не должны быть точными копиями, создайте их копии фабричным методом
  2. Создать актера среднего уровня, который может содержать несколько целей, а затем переадресовывать все вызовы, которые действия совершают, на все его цели (в конкретном случае он будет получать вызовы moveBy)
  3. Сделайте мягкую копию действия, используя установщики / получатели действия
  4. Сделайте бумажную копию действия, прежде чем переназначить его: объекты глубокого копирования
...