当前位置: 首页 > 知识库问答 >
问题:

如何管理屏幕

堵乐
2023-03-14

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

我试图为游戏打下基础:

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

在加载屏幕中,我喜欢做一些类似龙珠的事情,当加载屏幕允许我们让悟空吃米饭时,暂停屏幕需要绘制一些统计数据和选项,比如《超级英雄》或《恶魔城》,当玩家触摸按钮时,菜单会做一些事情像移动相机或打开一扇门,或移动到另一个“场景”,显示另一个选项,屏幕上的游戏需要预先给玩家机会赢得一些生命,以免输掉游戏。

我试着用这种形式来表达:

我有一个带有构造html" target="_blank">函数的游戏主类,以及覆盖的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是singleton,并且

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

其他类是菜单屏幕、游戏屏幕和加载屏幕。

加载屏幕:

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个答案

东方河
2023-03-14

正如@铁猴所回答的,没有“正确”的方式。

我只使用了一个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);
   }
}

首先,这非常节省资源,因为在游戏开始时只创建一次所需的状态。其次,因为您从不破坏状态,只需更改它们并调用enter/exit,它们始终完美地保留其当前状态,即变量、对象和所有内容。当您返回到某个状态时,它与离开前完全相同。

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();
}
李奕
2023-03-14

管理屏幕的正确方法不止一种。力比多给你自由,让你随心所欲。您可以扩展Screen类,根据项目的不同需要制作屏幕。您可以将屏幕作为状态进行管理,并使用状态管理器进行管理。

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

您可以切换到专用屏幕,也可以在游戏状态/屏幕中设置暂停和游戏结束状态,并在游戏仍在后台时在游戏屏幕顶部显示暂停/游戏结束元素

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

以下是一些启示:

皮克斯游戏。com:如何管理屏幕

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

 类似资料:
  • 使用指南 - 账户管理 - 屏蔽管理 为您详细介绍百度统计的账户结构,包括账户、站点、报告间的层级关系,报告或者消费数据的账户权限问题,以及假如您拥有多个账户,需要实现多账户授权管理的操作方法。 屏蔽管理 如何屏蔽IP和访客 屏蔽IP及访客标识码的效果

  • web3j除了实现最基本的标准JSON-RPC API,以太坊客户端,如Geth和Parity,通过JSON-RPC提供额外的管理API。 它们提供的一个关键的通用功能是创建和解锁在网络上交易的以太坊帐户的能力。在Geth和Parity中,这是在它们的私有模块中实现的,其中的细节可在下面得到: Parity Geth 在web3j中对这些私有模块的提供支持。这些方法对于Geth和Parity都是通

  • 人员管理-访客-可删除/邀请访客

  • 使用咨询师,但不要依赖他们。他们是神奇的人,非常值得尊敬。因为他们看过许多不同的工程,他们通常比你知道更多具体技术,甚至是编程技术。最好的使用他们的方式是像家教那样用例子教学。 然而,他们通常不能像正常员工那样用相同的感觉融入团队,可能仅仅是因为你没有足够的时间去学习他们的优点和缺点。他们的工资更低。他们更容易离开。如果公司做得好,他们可能得到的更少。有些可能是好的,有些可能与平均水平一致,有些可

  • 内存是一种你不可以耗尽的珍贵资源。在一段时期里,你可以无视它,但最终你必须决定如何管理内存。 堆内存是在单一子程序范围外,需要持续(保留)的空间。一大块内存,在没有东西指向它的时候,是无用的,因此被称为垃圾。根据你所使用的系统的不同,你可能需要自己显式释放将要变成垃圾的内存。更多时候你可能使用一个有垃圾回收器的系统。一个垃圾回收器会自己注意到垃圾的存在并且在不需要程序员做任何事情的情况下释放它的内

  • 神话这个词有时候意味着虚构。但这有着更深层的内涵。它也意味着一些宗教内容来解释宇宙和人类与之的关系。管理者倾向于忘记他们作为一个程序员时学到的东西,并且相信某种传说。试着让他们相信这种传说是错的,正如让一个虔诚的宗教信徒从他们的信仰中醒悟过来一样粗鲁而失败。因此,你应该认可这些信仰: 文档越多越好。(他们需要文档,但他们不会想要你在这些东西上花时间。) 程序员是平等的。(程序员可以按重要程度分类。