【问题标题】:Libgdx passing actions of an actor to another actorLibgdx 将一个演员的动作传递给另一个演员
【发布时间】:2018-04-26 17:32:11
【问题描述】:

好的,基本上我正在尝试用其他操作来装饰 Libgdx Actor 类

 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 的新回复)

我相信我已经理解了您提出的这个 Group-Workaround。但是我仍然无法使其工作。对于这个实例,假设我们先用 Shake 动作装饰按钮对象,然后用 FadeOut 动作装饰(这两个类都有从父类 ButtonDecorator 扩展的“Group”变量)。所以创建这种类型的对象看起来像这样:

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



    }
}

我不知道为什么,但仍然只有一个动作(淡出)应用于创建的对象

【问题讨论】:

  • 您的新版本不会复制 Action 对象。它将引用复制到同一个 Action 对象。由于 Action 类没有复制构造函数,因此复制它们的唯一方法是从头开始创建一个新的并手动复制每个参数。
  • 我没有关注你的问题。复制方法是什么意思?听起来您似乎还不熟悉一些面向对象编程的基础知识,因此您可能需要阅读 Sun 网站上的 Java 教程。

标签: java design-patterns libgdx decorator


【解决方案1】:

使用 Group Actor 组合多个 Actor。应用于该组的操作将应用于该组中的所有参与者。

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

我想出了一个比我以前更好的答案,另一个答案在技术上仍然是正确的,所以我也会保留它。

【讨论】:

  • 我根据您的回复添加了另一个编辑。有空请看一下
  • @user3713267 如果使用 Actions.parallel(action1, action2) 您的新解决方案可能会起作用,因为默认情况下,添加到演员的多个动作将按顺序使用,而不是并行使用
  • 不幸的是它没有。也许我做错了什么,但即使我并行添加动作,它仍然只应用第二个动作。我已经相应地编辑了代码
【解决方案2】:

每个动作都有一个演员目标,因此不可能将一个相同的动作分配给多个演员。您必须复制操作才能达到预期效果。

当您将一个动作分配给第二个演员时,应该发生的是动作目标切换到第二个演员,而不是两个演员现在都是动作的目标。

演员

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. 创建一个可以包含多个目标的中间人 Actor,然后将所有对它的调用操作转发到它的所有目标(在特定情况下它会接收 moveBy 调用)
  3. 使用动作的 setter/getter 制作动作的软拷贝
  4. 在重新分配操作之前制作一个硬拷贝:deep copying objects

【讨论】:

  • 您好,根据您的回复,我已在帖子中添加了编辑段,请查看
  • 再想一想,我认为为给定的动作设置一个新的演员正是我想要的。我想用不同的动作来装饰按钮,这意味着向一个演员添加更多的动作,这意味着为不同的动作设置一个相同的演员。我希望将所有动作目标设置为一个特定的按钮演员,以便 new Shaking(new Fading(new Button())) 将从 Fading 装饰器中采取行动并将其目标设置为也具有 Shaking 动作的按钮。那么我的第一个解决方案不应该这样工作吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
  • 2022-11-07
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
相关资源
最近更新 更多