2016-09-22 12 views
1

Ich mache ein Programm, um die erstaunliche libGDX + scene2d API und ich strukturiert es wie folgt:Ist es in LibGDX `scene2d` API möglich, die gleiche Actor Instanz in mehreren Stufen zu haben?

  • ich eine einzelne Instanz MyGame haben, eine einzelne Instanz PolygonSpriteBatch halten.
  • Es ist eine abstrakte MyScreen Klasse, eine MyStage Klasse halten (siehe unten)
  • Dann gibt es viele verschiedene Bildschirme Klassen, die von MyScreen erbt, und instanziiert sie nach Belieben.

(in allen Fällen das Entfernen des „My“ können Sie den Namen der jeweiligen Bibliotheksklasse gibt, dass es reicht)

Dieses Modell funktionierte gut, bis ich einige Probleme Aktionen zwischen den Bildschirmen auszuführen mit dem Action System. Ich entschied dann, dass es eine gute Idee wäre, eine einzige OmnipresentActor zu haben, die zu MyGame gehört, die, wie der Name sagt, in jeder Szene vorhanden ist. So modifizierte ich myStage wie diese mehr oder weniger suchen:

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(); 
} 

es eine schmerzliche Debug-Phase gefolgt, bis ich folgendes herausgefunden:

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 

die "PRINT_BEFORE" Aussage zeigt, dass die stage hält die omnipresentActor . In "PRINT_AFTER" ist es nicht mehr da, während mainMenuScreen es tatsächlich hält. Also meine Frage, jetzt präziser:

verhindert scene2d das passiert, oder mache ich hier etwas falsch?

Antworten sehr geschätzt! Prost

+1

Ein Schauspieler kann nur Mitglied einer Stufe sein. Aber Sie können es aus einem entfernen und es zu einem anderen hinzufügen, oder haben Sie eine omnipräsente Bühne für diesen Akteur, die nach jedem Bildschirm der jeweiligen Bühne gezeichnet wird. Ich nehme an, du könntest eine Nachfolge-Schauspieler-Klasse schreiben, die auf einen Schauspieler verweist, der sich in einer anderen Stufe befindet und zu seiner Zeichenmethode aufruft. – Tenfour04

+0

Ja, das dachte ich mir ... Ich werde den Ansatz dann ändern, kann ich mir nicht vorstellen dass die Bibliotheken ein solches Design fördern. Vielleicht kann mir das helfen: http://stackoverflow.com/a/28024327/4511978 Aber das ist eine andere Frage –

Antwort

0

Ein Schauspieler kann nur Mitglied einer Stufe sein: Danke an @ Tenfour04 für die Bestätigung. Die Erklärung ist ganz klar, nach ein wenig Forschung zu tun:

Stage.addActor() sieht wie folgt aus:

(hier der Github Code von Stage.java)

/** Adds an actor to the root of the stage. 
    * @see Group#addActor(Actor) */ 
    public void addActor (Actor actor) { 
     root.addActor(actor); 
} 

während Wurzel wird einfach als initialisiert Gruppe im Stage-Konstruktor: root = new Group();.

Und Group.addActor() sieht wie folgt aus:

(hier der Github Code von Group.java)

/** Adds an actor as a child of this group. The actor is first removed from its parent group, if any. */ 
public void addActor (Actor actor) { 
    if (actor.parent != null) actor.parent.removeActor(actor, false); 
    children.add(actor); 
    actor.setParent(this); 
    actor.setStage(getStage()); 
    childrenChanged(); 

}

So in den Baum ersten Zeilen ist die Antwort: wenn die neue Schaffung Stufe, wenn der hinzuzufügende Akteur bereits ein Elternteil hat, wird es von seinem aktuellen Elternteil entfernt. So gibt es zwei mögliche Lösungen für das Problem, das ich enounced:

LÖSUNG 1: Aufschalten addActor das Entfernen if-Anweisung oder jede andere Änderung der Bibliothek, die ich bin nicht sicher, ob es funktionieren würde. Ich denke eher, dass dies sehr problematisch sein könnte, zum Beispiel könnte es die Stufen davon abhalten, richtig zu entsorgen.

LÖSUNG 2: Ändern Sie den Entwurf, so dass Sie keinen allgegenwärtigen Akteur brauchen, noch die Bibliotheken ändern/neu implementieren. Im Moment ist dieses ist, was ich basierend auf this Antwort getan haben, ist es nicht sehr sauber, aber es funktioniert so weit:

private boolean watchingTemp; 
private Actor watchActorTemp; 
private Action actionTemp; 

:

1) In der MyScreen Klasse die folgenden Felder hinzugefügt 2) dann zugegeben diese Methode:

public void addActionOnStageAfterActorEndsHisActions(Actor actor, Action action) { 
    watchActorTemp = actor; 
    actionTemp = action; 
    watchingTemp = true; 
} 

3) dann in den render Verfahren, fügte ich folgende:

if (watchingTemp && !watchActorTemp.hasActions()) { 
     watchingTemp = false; 
     stage.addAction(actionTemp); 
    } 

4) schließlich, wenn eine Aktion auf einem Bildschirm Übergang ausführen möchten (und schließlich die erste Anordnung), können Sie etwas tun: Ich habe etwas ähnliches verwenden, wenn sie auf eine Tür zwischen den Bildschirmen klicken

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

Hoffe es hilft!

Verwandte Themen