在LibGDX';s`scene2d`API是否在多个阶段中具有相同的Actor实例?

在LibGDX';s`scene2d`API是否在多个阶段中具有相同的Actor实例?,libgdx,scene2d,Libgdx,Scene2d,我正在使用惊人的libGDX+API制作一个程序,我将其结构如下: 我有一个MyGame实例,持有一个PolygonSpriteBatch实例 有一个抽象的MyScreen类,持有一个MyStage类(见下文) 然后有许多不同的屏幕类继承自MyScreen,并可以随意实例化彼此 (在所有情况下,删除“My”都会给出它扩展的相应库类的名称) 这个模型工作得很好,直到我在使用Action系统在屏幕之间执行操作时遇到一些问题。我当时决定,最好有一个属于MyGame的omnipresentator,

我正在使用惊人的
libGDX
+API制作一个程序,我将其结构如下:

  • 我有一个
    MyGame
    实例,持有一个
    PolygonSpriteBatch
    实例
  • 有一个抽象的
    MyScreen
    类,持有一个
    MyStage
    类(见下文)
  • 然后有许多不同的屏幕类继承自
    MyScreen
    ,并可以随意实例化彼此
(在所有情况下,删除“
My
”都会给出它扩展的相应库类的名称)

这个模型工作得很好,直到我在使用
Action
系统在屏幕之间执行操作时遇到一些问题。我当时决定,最好有一个属于
MyGame
omnipresentator
,正如名字所说,它存在于每个场景中。因此,我修改了MyStage,使其看起来或多或少像这样:

public class MyStage extends Stage {
public MyStage(MyGame g) {
    super(new FitViewport(MyGame.WIDTH, MyGame.HEIGHT), g.batch);
    addActor(game.omnipresentInvisibleActor);
}

@Override
public void clear() {
    unfocusAll();
    getRoot().clearActions();
    getRoot().clearListeners();
    removeActorsButNotListenersNorActions();
}

public void removeActorsButNotListenersNorActions() {
    for (Actor a : getActors()) if (a.getClass()!= OmnipresentInvisibleActor.class) a.remove();
}
它经历了一个痛苦的调试阶段,直到我发现:

public PresentationScreen(MyGame g) {
    // super() call and other irrelevant/already debugged code
    System.out.println("PRINT_BEFORE: "+ stage.getActors().toString()); // OmnipresentActor is there
    mainMenuScreen = new MainMenuScreen(game);
    System.out.println("PRINT_AFTER: "+ stage.getActors().toString()); // OmnipresentActor is not there anymore, but was added to the mainMenuScreen
if (watchingTemp && !watchActorTemp.hasActions()) {
        watchingTemp = false;
        stage.addAction(actionTemp);
    }
“PRINT_BEFORE”
语句显示
阶段
保存了
OmniPresentator
。在
“PRINT_AFTER”
中,它不再存在,而
mainMenuScreen
确实保存着它。所以我的问题,现在更准确地说:

场景2D是否阻止了这种情况的发生,或者我在这里做错了什么?


非常感谢您的回答!干杯

演员只能是一个舞台的成员:感谢@Tenfour04的确认。做了一点调查后,解释就很清楚了:

Stage.addActor()
如下所示:

(这里是的github代码)

而root只是在Stage构造函数中初始化为一个组:
root=newgroup()

Group.addActor()
看起来像这样:

(这里是的github代码)

}

因此,在树中,第一行是答案:当创建新阶段时,如果要添加的参与者已经有一个父级,它将从当前父级中删除。因此,对于我所说的问题,有两种可能的解决方案:

解决方案1:Override
addActor
删除if语句或库的任何其他更改,我不确定它是否有效。我认为这可能是非常有问题的,例如,它可能会阻止阶段正确处理

解决方案2:更改设计,这样您就不需要无所不在的参与者,也不需要更改/重新实现库。目前这是我根据答案所做的,它不是很干净,但到目前为止仍然有效:

1) 在
MyScreen
类中添加了以下字段:

private boolean watchingTemp;
private Actor watchActorTemp;
private Action actionTemp;
2) 然后添加了此方法:

public void addActionOnStageAfterActorEndsHisActions(Actor actor, Action action) {
    watchActorTemp = actor;
    actionTemp = action;
    watchingTemp = true;
}
3) 然后在
render
方法中,我添加了以下内容:

public PresentationScreen(MyGame g) {
    // super() call and other irrelevant/already debugged code
    System.out.println("PRINT_BEFORE: "+ stage.getActors().toString()); // OmnipresentActor is there
    mainMenuScreen = new MainMenuScreen(game);
    System.out.println("PRINT_AFTER: "+ stage.getActors().toString()); // OmnipresentActor is not there anymore, but was added to the mainMenuScreen
if (watchingTemp && !watchActorTemp.hasActions()) {
        watchingTemp = false;
        stage.addAction(actionTemp);
    }
4) 最后,当希望在屏幕转换时执行操作(并最终处理第一个)时,您可以这样做:我在单击屏幕之间的门时使用类似的方法

public void movePlayerTHENgotoNewScreen(float xPos, float yPos, whatever else...) {
    game.player.walkToAnyPoint(xPos, yPos);
    yourFavoriteScreen.addActionOnStageAfterActorEndsHisActions(game.player, gotoNewScreen(wathever else...));
}

希望有帮助

演员只能是一个阶段的成员:感谢@Tenfour04的确认。做了一点调查后,解释就很清楚了:

Stage.addActor()
如下所示:

(这里是的github代码)

而root只是在Stage构造函数中初始化为一个组:
root=newgroup()

Group.addActor()
看起来像这样:

(这里是的github代码)

}

因此,在树中,第一行是答案:当创建新阶段时,如果要添加的参与者已经有一个父级,它将从当前父级中删除。因此,对于我所说的问题,有两种可能的解决方案:

解决方案1:Override
addActor
删除if语句或库的任何其他更改,我不确定它是否有效。我认为这可能是非常有问题的,例如,它可能会阻止阶段正确处理

解决方案2:更改设计,这样您就不需要无所不在的参与者,也不需要更改/重新实现库。目前这是我根据答案所做的,它不是很干净,但到目前为止仍然有效:

1) 在
MyScreen
类中添加了以下字段:

private boolean watchingTemp;
private Actor watchActorTemp;
private Action actionTemp;
2) 然后添加了此方法:

public void addActionOnStageAfterActorEndsHisActions(Actor actor, Action action) {
    watchActorTemp = actor;
    actionTemp = action;
    watchingTemp = true;
}
3) 然后在
render
方法中,我添加了以下内容:

public PresentationScreen(MyGame g) {
    // super() call and other irrelevant/already debugged code
    System.out.println("PRINT_BEFORE: "+ stage.getActors().toString()); // OmnipresentActor is there
    mainMenuScreen = new MainMenuScreen(game);
    System.out.println("PRINT_AFTER: "+ stage.getActors().toString()); // OmnipresentActor is not there anymore, but was added to the mainMenuScreen
if (watchingTemp && !watchActorTemp.hasActions()) {
        watchingTemp = false;
        stage.addAction(actionTemp);
    }
4) 最后,当希望在屏幕转换时执行操作(并最终处理第一个)时,您可以这样做:我在单击屏幕之间的门时使用类似的方法

public void movePlayerTHENgotoNewScreen(float xPos, float yPos, whatever else...) {
    game.player.walkToAnyPoint(xPos, yPos);
    yourFavoriteScreen.addActionOnStageAfterActorEndsHisActions(game.player, gotoNewScreen(wathever else...));
}

希望有帮助

演员只能是一个舞台的成员。但是你可以将它从一个屏幕上移除,然后添加到另一个屏幕上,或者在每个屏幕的相应阶段之后为这个演员绘制一个无所不在的舞台。我想你可以写一个follower-actor类,它引用另一个阶段的演员,并调用它的draw方法,等等。是的,我就是这么想的。。。我会改变方法,我无法想象图书馆会鼓励这样的设计。也许这能帮助我:但这是另一个问题演员只能是一个舞台的一员。但是你可以将它从一个屏幕上移除,然后添加到另一个屏幕上,或者在每个屏幕的相应阶段之后为这个演员绘制一个无所不在的舞台。我想你可以写一个follower-actor类,它引用另一个阶段的演员,并调用它的draw方法,等等。是的,我就是这么想的。。。我会改变方法,我无法想象图书馆会鼓励这样的设计。也许这能帮助我:但那是另一个问题