首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何管理屏幕

如何管理屏幕
EN

Stack Overflow用户
提问于 2016-10-06 02:56:44
回答 2查看 283关注 0票数 1

我正在用libgdx做一个游戏,但我是新来的,我不知道我的代码是正确的形式还是最好的方式。

我试着为这个游戏奠定基础:

  • 一个实现菜单的屏幕管理器,
  • 选项屏幕
  • 装载屏幕
  • 游戏屏幕
  • 停顿的尖叫
  • 屏幕上的游戏

在加载屏幕上,我喜欢做一些类似龙珠的事情,当加载屏幕允许我们让小悟空吃米饭时,暂停屏幕需要绘制一些统计数据和选项--比如Megaman或Castlevania;当玩家按下按钮时,菜单就会做一些事情--比如移动摄像机或打开门,或者移动到另一个显示其他选项的“场景”,而屏幕上的游戏需要先前给玩家机会赢得一些生命而不会输掉游戏。

我试着用这种形式来做这个:

我有游戏的主类和构造函数,overriden metods创建()、呈现()、调整大小()和dispose()、照相机的变量、视口、Sprite批处理、存储当前屏幕的int和屏幕管理器。

代码语言:javascript
复制
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是单例的,并且

代码语言:javascript
复制
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和加载屏幕。

装载屏幕:

代码语言:javascript
复制
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);
}

菜单和游戏类类似于加载,只调用资产并在呈现方法上绘制一些sprite。

这段代码可以很好地改变屏幕,但我不知道是否是正确的形式,而另一个大的问题是如何管理暂停屏幕,因为我只存储一个变量,如果变量是暂停,呈现方法会绘制一些东西,如果不是绘制正常的游戏,但是如果我想改变暂停的选项和图像,我需要检查变量来知道暂停需要绘制什么。

代码语言:javascript
复制
 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();
    }

我做得对吗?或者你会推荐我什么?为了实现这一点,一些例子或者可能是特定的教程将是很棒的。

EN

回答 2

Stack Overflow用户

发布于 2016-10-06 08:40:52

管理屏幕不仅有一种正确的方法。性欲让你有自由去做你喜欢做的事情。您可以扩展Screen类,以使屏幕满足项目的不同需求。您可以将屏幕管理为状态,并使用状态管理器管理它们。

关于暂停和游戏在屏幕上,你可以用不同的方式做。

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

因此,没有一种正确的方法可以这样做。正确的方法是什么对你的游戏有效。

为了获得一些启示:

pixnbgames.com :如何管理屏幕

布伦特·奥雷利:游戏州经理

票数 1
EN

Stack Overflow用户

发布于 2016-10-07 21:18:59

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

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

代码语言:javascript
复制
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);
   }
}

首先,这非常节省资源,因为在游戏开始时只创建了一次所需的状态。第二,因为您从不破坏状态,而只需更改它们并调用enter/exit,它们总是完全保持其当前状态,即变量、对象和一切,当您回到状态时,它与您离开状态之前的状态完全相同。

GameState是接口,您可以随意实现它。

代码语言:javascript
复制
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();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39886796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档