2015-04-03 84 views
0

我正在LibGdx的遊戲中工作,我會切換屏幕很多,所以我想我會做我自己的小屏幕管理器。但是要設置屏幕,我需要參考LibGdx Game。我對現在的經理看起來並不滿意,我必須通過某種方式實現這一點,而無需發送兩次Game對象。Libgdx ScreenManager

我的代碼:

public static void setScreen(Screen screen, Game game){ 
     if(currentScreen != null){ 
      currentScreen.dispose(); 
      System.out.println("Screen disposed"); 
     } 
     currentScreen = screen; 
     game.setScreen(currentScreen); 
    } 

我們從另一個屏幕設置屏幕(例如從menuScreen設置gameScreen)身份證需要一個遊戲對象發送到屏幕的構造函數,像這樣:

ScreenManager.setScreen(new GameScreen(game), game);

在我的完美主義者希望能夠以這樣稱呼它:

ScreenManager.setScreen(new GameScreen(), game

ScreenManager.setScreen(new GameScreen(game)

任何人都可以想辦法做到這一點?或者我只是沉迷於我可能會做的事情?

+0

「SceneManager」必須是單身人士嗎?一種可能的解決方案可能是允許實例化它,並在構造函數中傳入你的'Game'對象,儘管還有一些感覺...... – lealand 2015-04-03 16:35:48

+0

還有一點評論,因爲我一直處於類似的情況。看起來你正在開發一系列依賴關係(我認爲)遊戲取決於場景管理器,場景管理器取決於遊戲。試着讓它只是一種方式,例如遊戲會告訴經理進行更新和渲染,並且經理會告訴當前場景進行更新和渲染。 – lealand 2015-04-03 16:45:27

+0

感謝您的意見:)這實際上是ScreenManager中的唯一方法。我不做任何渲染或類似的東西。我只是設置屏幕並處理舊的。我曾想過創建自己的抽象Screen類,而不是在LibGdx中實現這個類。也許我會這樣做,我不必參考'遊戲' – WEDEBE 2015-04-03 16:56:21

回答

4

您可以創建自己的屏幕類型,它將返回遊戲並實現屏幕方法。

package ***; 

import com.badlogic.gdx.Screen; 
import ***.GameCore; 

public class MyScreen implements Screen { 
    GameCore game; 
    public MyScreen(GameCore game) { 
     this.game = game; 
    } 

    public GameCore getGameCore(){ 
     return this.game; 
    } 
    /* 
    Methods implemented from Screen (render , hide , dispose etc...) 
    */ 
} 

然後創建將擴展自選畫面的屏幕類型。

package ***; 

import ***.GameCore; 

public class MenuScreen extends MyScreen{ 

    public MenuScreen (GameCore game) { 
     super(game);   
    } 
    /* 
    Methods implemented from Screen (render , hide , dispose etc...) 
    */ 
} 

在GameCore中創建MenuScreen的一個實例。

MenuScreen menuScreen = new MenuScreen(this); 

然後,你可以做你想要的技巧。

​​

然後,您可以自由設置你的屏幕的方式

ScreenManager.setScreen(new MenuScreen(game)); 

ScreenManager.setScreen(menuScreen);//if you have already created an instance of menu 
0

您可以使用Gdx.app.getApplicationListener()將其轉換爲遊戲來獲得遊戲實例。此外,你的代碼可以變得更清潔,改變setScreen方法:通過實施還我自己的Screen延伸Group

public static void setScreen(Screen screen){ 
    if(currentScreen != null){ 
     currentScreen.dispose(); 
     System.out.println("Screen disposed"); 
    } 
    currentScreen = screen; 
    Game game = (Game)Gdx.app.getApplicationListener(); 
    game.setScreen(currentScreen); 
} 
2

我實現我自己的ScreenManager。我使用的協議是爲最小物體實例化設計的:

  • 所有Screen對象應該是單件。我將它們的構造函數封裝爲私有的,只有ScreenManager可以直接實例化它們。它們存儲在哈希映射中。
  • 在實例化時只實例化一次您的Screen的對象,並將它們添加到Screen(因此我的所有組件也都延伸到Actor)。
  • 實現一個方法getInputProcessors(),該方法返回自定義Screen所使用的,不會由階段隱式觸發的自定義處理程序。 (其實我有一組類似的其他對象的功能,但在這裏去除清晰度。)
  • ScreenManager電話showhide當需要換出一個畫面,這實際上並不需要做什麼,但可以重寫定製行爲。

這種工作方式是,我的屏幕管理器有一個Stage。經理只需清除屏幕之間的舞臺對象並添加新舞臺,因爲它是一個Group(這是一個可包含更多演員的Actor)。如果不涉及太多的細節,這將涉及到在我的框架中解釋大量內部類,下面是一些抽象出的功能的一般過程,這些功能可能與您無關(並允許傳入外部Screen對象) :

private final AtomicReference<Screen> curScreen = ...; 
... 
public static boolean set(Screen nextScreen) 
{ 
    mutex.lock(); // prevent multi-threading issues 
    try 
    { 
    // ensure the provided screen is valid 
    final Screen cur = curScreen.get(); 
    if (null == nextScreen || nextScreen.equals(cur)) return false; 

    // atomically update the current screen reference 
    if (!curScreen.compareAndSet(cur, nextScreen)) return false; 

    // record the screen for back() operations and add it to the stage 
    if (null != cur) screenStack.push(cur); 
    stage.clear(); 
    stage.add(nextScreen); 

    // grab any custom input processors from the stage and build an input handler 
    final inputProcessors = nextScreen.getInputProcessors(); 
    final InputProcessor[] processors = inputProcessors.toArray(new InputProcessor[inputProcessors.size()+1]); 
    processors [inputProcessors.length-1] = stage; 

    // inform gdx of our new input target 
    Gdx.input.setInputProcessor(new InputMultiplexer(processors)); 

    return true; 
    } 
    catch (Throwable t) { Log.error(t); return false; } 
    finally { mutex.unlock(); } 
} 

請注意,使用AtomicReference定製Mutex對象,這是由於這裏的效率可以得到更復雜的情況。您可以將Mutex替換爲ReentrantLock,並將AtomicReference直接轉換爲Screen以獲得更簡單的應用程序。