如何管理屏幕

时间:2016-10-06 02:56:45

标签: java android libgdx

我正在用libgdx制作游戏,但我是新手,我不知道我的代码是正确的形式还是最好的方法。

我正试图打造游戏的基础:

  • 用于实现菜单的屏幕管理器,
  • 选项屏幕
  • 加载屏幕
  • 游戏画面
  • 暂停Screem
  • 屏幕上的游戏

在加载屏幕上我喜欢像龙珠这样的东西,当加载屏幕允许我们让悟空吃米饭时,暂停屏幕需要绘制一些统计数据和选项,如Megaman或Castlevania,菜单做什么时候播放器触摸按钮,例如移动相机或打开一扇门,或移动到显示另一个选项的另一个“场景”,并且屏幕上的游戏需要先前让玩家有机会赢得一些生命而不会失去游戏。

我尝试以这种形式制作:

我有构造函数的游戏主类,以及重写的metods create(),render(),resize()和dispose(),摄像机的变量,视口,Spritebatch,int到存储当前屏幕,以及屏幕管理器。

public class BOS_Project extends Game {
    OrthographicCamera camera;
    Viewport viewport;
    SpriteBatch batch;
    AssetManager manager = new AssetManager();
    int actualScreen = 0;

    public BOS_Project(){
        camera = new OrthographicCamera();
        camera.setToOrtho(false, screenWidth, screenHeight);
        viewport = new FitViewport(screenWidth, screenHeight);
    }

    @Override
    public void create(){
        batch = new SpriteBatch();
    }

    @Override
    public void render(){
        actualScreen = 1;
        ScreenManager.getInstance().showScreen(1, this);
        super.render();
    }

    @Override
    public void resize(int width, int height){
        viewport.update(width, height);
    }

    @Override
    public void dispose(){
        batch.dispose();
    }
}

类ScreenManager也是单例,

public class ScreenManager{
   private static ScreenManager instance;
   private Game game;
   Screen screen;

private ScreenManager(){
    super();
}

public static ScreenManager getInstance(){
    if(instance == null){
        instance = new ScreenManager();
    }
    return instance;
}

public void initialize(Game game){
    this.game = game;
}

public void showScreen(int currentscreen, BOS_Project game){
    if(currentscreen == 1){
        if(screen!=null)
            screen.dispose();
        screen = new LoadingScreen(game, game.actualScreen);
        game.setScreen(screen);
    }else if(currentscreen == 2){
        if(screen!=null)
            screen.dispose();
        screen = new GameScreen(game);
        game.setScreen(screen);
    }else{
        if(screen!=null)
            screen.dispose();
        screen = new MenuScreen(game);
        game.setScreen(screen);
    }
}

其他类是MenuScreen,GameScreen和Loading Screen。

载入画面:

public LoadingScreen(BOS_Project game2, int screen2){
    game = game2;
    screen = screen2;
    game.manager.load("button.png", Texture.class);
    game.manager.finishLoadingAsset("button.png");
    sprite1 = new Sprite(game.manager.get("button.png", Texture.class));
    sprite1.setPosition(0, 0);
    //This is a method to load the assets for the especific screen
    game.load(screen);
}

@Override
public void render(float delta){
    if(game.manager.getProgress()==1) {
        if (time < 3) {
            Gdx.app.log("Loading: ", "90.0");
        }
    }else {
        Gdx.app.log("Loading: ", String.valueOf(game.manager.getProgress() * 100));
    }
    game.manager.update();
    batch = game.batch;
    Gdx.gl.glClearColor(0, 0, 0, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    sprite1.draw(batch);
    if(game.manager.getProgress()==1 && time > 3){
        if(screen==1) {
            ScreenManager.getInstance().showScreen(2, game);
        }else{
            ScreenManager.getInstance().showScreen(3, game);
        }
    }else{
        time += delta;
    }
    batch.end();
    super.render(delta);
}

菜单和游戏类与加载类似,只调用资源并在渲染方法上绘制一些精灵。

此代码可以很好地更改屏幕,但我不知道是否是正确的格式,另一个大问题是如何管理暂停屏幕,因为我管理这个只存储变量如果变量暂停渲染方法画一些东西,如果没有绘制正常游戏,但如果我想改变暂停的选项和图像,我需要检查变量以了解暂停需要绘制的内容。

 if(pause){
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        spritePause.draw(batch);
        batch.end();
    }else if(game){
        batch.begin();
        spriteGame.draw(batch);
        batch.end();
    }

所以,我做得对吗?或者你会推荐我什么?一些示例或可能是实现此目的的特定教程将是很好的。

2 个答案:

答案 0 :(得分:1)

管理屏幕不仅有一种正确的方法。 Libido让您可以自由地按照自己喜欢的方式行事。您可以扩展Screen类,以根据项目的不同需求制作屏幕。您可以将屏幕作为状态进行管理,并通过州经理进行管理。

关于暂停和游戏结束屏幕,您也可以通过不同方式执行此操作。

您可以使用专用屏幕切换到,或者您可以在游戏状态/屏幕中拥有暂停和GameOver状态,并在游戏仍处于后台时在游戏屏幕上显示暂停/ GameOver元素。

所以没有一种正确的方法可以做到这一点。正确的方法是适合你的游戏。

获得一些灵感:

pixnbgames.com : How to manage screens

Brent Aureli : Game State Manager

答案 1 :(得分:0)

正如@IronMonkey所回答的那样,没有“正确”的方法。

我只使用一个GameScreen类,并且在GameScreen类中有很多不同的状态。 GameScreen类非常简单和简短(100-200 LOC),负责在状态之间切换。状态类似于GameScreen类,但可以在不需要实例化新对象的情况下输入和退出它们。

class GameScreen extends ScreenAdapter implements Disposable {
   GameState menuState;
   GameState playState;

   GameState currentState;

   public GameScreen(final MyGame game) {
      menuState = new MenuState(this);
      playState = new PlayState(this);
   }

   public void setState(GameState state) {
      if(currentState == state) return;

      // states have a method 'exit' where you can pause them or finalize something
      if(currentState != null) 
         currentState.exit();

      currentState = state;

      // also states have 'enter' where you can unpause or init something when entering
      currentState.enter();
   }

   public void render(float delta) {
      currentState.render(delta);
   }
}

首先,这非常节省资源,因为在游戏开始时只需创建一次所需的状态。其次,因为你永远不会破坏状态,只是改变它们并调用进入/退出,它们总是保持完美的当前状态,即变量,对象和一切,当你回到状态时,它就像你离开之前一样。

GameState是界面,您可以随意实现它。

public interface GameState 
{
    public void enter();
    public void exit();
    public void update(float delta);
    public void render(SpriteBatch batch, float delta);
    public String toString();
    public void dispose();
}