libgdx Screen 切换

我们一般在开发时,都会分成多个Screen去实现不同的功能,比如:

MenuScreen用于菜单界面显示,GameScreen主游戏界面,HelpScreen游戏帮助界面。

直接使用game.setScreen就可以完成场景的切换。不过这样略显生硬,另外,在内存占用方面有可能出现瞬时内存占用太大的问题,可能导致游戏退出什么的。

跟cocos2dx的道理一样,一个ScreenOne在切换的ScreenTwo时,是这样一个过程:

1. ScreenOne在运行中,它已加载资源。

2. 实例化ScreenTwo,加载ScreenTwo的资源(这时One和Two的资源都在内存中

3. 将显示切换到ScreenTwo,也就是game.setScreen(ScreenTwo)

4. ScreenOne销毁释放它的资源。

如果这两个Screen都加载很多资源的话,程序很容易出现问题。

比如iOS限定单个app最大10M内存(具体多少我忘了,我只是比方,请查文档),而ScreenOne和ScreenTwo分别占用8M,切换瞬间会有16M,这时就有问题啦。

以前在玩2dx的时候,哥们告诉我了一种方法,就是中间加个过渡的切换专用Screen,当然它的占用应该很小。

然后切换过程就变成了这样:

1. ScreenOne在运行中,它已加载资源。

2. 实例化TransScreen,加载TransScreen的资源,当然也可以不用资源,就是个黑屏

3. 将显示切换到TransScreen,也就是game.setScreen(TransScreen)

4. ScreenOne销毁释放它的资源。

5. 实例化ScreenTwo,加载ScreenTwo的资源

6. 将显示切换到ScreenTwo,也就是game.setScreen(ScreenTwo)

7. TransScreen销毁释放它的资源。

这样我们就把大量的资源占用错开了。

上代码

  1 public class ScreenTrans implements Screen {
  2     private ScreenType next;
  3     private Game game;//在需要切换场景的时候直接game.setScreen
  4     private Stage stage;
  5     private static final Logger LOGGER = new Logger(ScreenTrans.class.getName(), Application.LOG_DEBUG);
  6     private static final float DURATION=0.5f;
  7     private Texture logoTexture;
  8     private Skin skin;
  9     private ProgressBar bar;
 10     private GameTimer timer;
 11
 12     public enum ScreenType{
 13         SCREEN_ONE,SCREEN_TWO
 14     }
 15
 16     public ScreenTrans(Game game,ScreenType next) {
 17         LOGGER.debug("init");
 18         this.game = game;
 19         this.next = next;
 20
 21         stage = new Stage();
 22         //Gdx.input.setInputProcessor(null);
 23
 24         logoTexture = new Texture(Gdx.files.internal("badlogic.jpg"));
 25         Image logo = new Image(logoTexture);
 26         logo.setCenterPosition(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
 27         stage.addActor(logo);
 28
 29         skin = new Skin();
 30         Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
 31         pixmap.setColor(Color.WHITE);
 32         pixmap.fill();
 33         skin.add("white", new Texture(pixmap));
 34
 35         ProgressBar.ProgressBarStyle style = new ProgressBar.ProgressBarStyle();
 36         style.knob = skin.newDrawable("white",Color.GREEN);
 37         style.knobBefore = skin.newDrawable("white", Color.GREEN);
 38         style.knobAfter = skin.newDrawable("white",Color.GRAY);
 39         style.background = skin.newDrawable("white",Color.RED);
 40
 41         style.knob.setMinHeight(10);
 42         style.knobBefore.setMinHeight(10);
 43         style.knobAfter.setMinHeight(10);
 44
 45         bar = new ProgressBar(0,100,1,false,style);
 46         bar.setWidth(logo.getWidth());
 47         bar.setCenterPosition(Gdx.graphics.getWidth()/2,(Gdx.graphics.getHeight()-logo.getHeight())/2-5);
 48         stage.addActor(bar);
 49
 50         timer = new GameTimer(DURATION);
 51     }
 52
 53     @Override
 54     public void render(float delta) {
 55         Gdx.gl.glClearColor(0, 0, 0, 1);
 56         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
 57
 58         float d = CommonUtils.getDelta(delta);
 59         timer.update(d);
 60         if(timer.isFinished()){
 61             this.trans();
 62         }
 63         bar.setValue(timer.getLiveTime()*100/DURATION);
 64         stage.act(delta);
 65         stage.draw();
 66     }
 67
 68     private void trans(){
 69         Screen nextScreen = null;
 70         switch (next){
 71             case SCREEN_ONE:
 72                 nextScreen = new ScreenOne(this.game);
 73             break;
 74             case SCREEN_TWO:
 75                 nextScreen = new ScreenTwo(this.game);
 76                 break;
 77         }
 78         this.game.setScreen(nextScreen);
 79         this.dispose();
 80     }
 81
 82     @Override
 83     public void resize(int width, int height) {
 84         stage.getViewport().update(width,height,true);
 85     }
 86
 87     @Override
 88     public void show() {
 89         LOGGER.debug("show");
 90     }
 91
 92     @Override
 93     public void hide() {
 94
 95     }
 96
 97     @Override
 98     public void pause() {
 99
100     }
101
102     @Override
103     public void resume() {
104
105     }
106
107     @Override
108     public void dispose() {
109         LOGGER.debug("dispose");
110         stage.dispose();
111         logoTexture.dispose();
112         skin.dispose();
113     }
114 }

以上代码中使用了枚举的场景类型用以区分下一步是哪个,当然也可以用int或者更高级一点用Class<? extends Screen>,然后用class.newInstance等。

GameTimer是个特别简单的计时器。

这个过渡屏我加入了一个假的加载进度条,当然是假的,这时候next的Screen还没实例化呢。其实是个计时条=。=

还有一个image。加入这些,我就是为了感受一下切换是否生硬。

以下是效果图:

以下是调试信息:

com.tide.g2d.screeneffect.two.ScreenOne: init
com.tide.g2d.screeneffect.two.ScreenOne: show
com.tide.g2d.screeneffect.ScreenTrans: init
com.tide.g2d.screeneffect.ScreenTrans: show
com.tide.g2d.screeneffect.two.ScreenOne: dispose

-----这时正在展示过渡屏
com.tide.g2d.screeneffect.two.ScreenTwo: init
com.tide.g2d.screeneffect.two.ScreenTwo: show
com.tide.g2d.screeneffect.ScreenTrans: dispose
com.tide.g2d.screeneffect.ScreenTrans: init
com.tide.g2d.screeneffect.ScreenTrans: show
com.tide.g2d.screeneffect.two.ScreenTwo: dispose

-----这时正在展示过渡屏
com.tide.g2d.screeneffect.two.ScreenOne: init
com.tide.g2d.screeneffect.two.ScreenOne: show
com.tide.g2d.screeneffect.ScreenTrans: dispose
com.tide.g2d.screeneffect.ScreenTrans: init
com.tide.g2d.screeneffect.ScreenTrans: show
com.tide.g2d.screeneffect.two.ScreenOne: dispose

-----这时正在展示过渡屏
com.tide.g2d.screeneffect.two.ScreenTwo: init
com.tide.g2d.screeneffect.two.ScreenTwo: show
com.tide.g2d.screeneffect.ScreenTrans: dispose

时间: 2024-07-28 16:35:55

libgdx Screen 切换的相关文章

libgdx Screen 场景切换

直接摆代码: 1 public class MainGame extends Game{ 2 @Override 3 public void create() { 4 this.setScreen(new ScreenOne()); 5 } 6 } 代码中ScreenOne实现com.badlogic.gdx.Screen接口. 当需要切换场景的时候,调用game的setScreen方法即可,奏是这么简单 当然多个场景的情况下,Screen的实现类里最好持有game的引用,或者是game直接写成

列表屏幕(List Screen)

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4292407.html 列表屏幕(List Screen). 205 生成列表屏幕... 205 复杂LIST. 206 标准LIST. 206 standard page header. 206 自定义LIST. 207 自定义Page H

Libgdx 触摸事件解析

1.如何让Stage接受到触摸事件: // 注册监听器 InputMultiplexer inputMultiplexer = new InputMultiplexer(getStage(),new GestureDetector(this)); Gdx.input.setInputProcessor(inputMultiplexer); 此处第二个为手势的监测.(滑动,缩放等) 2.这里特殊说明一下,所有事件的处理都是绘制之前的. Gdx.input.justTouched() Gdx.inp

Windows 键盘快捷键概述

在 Windows 中工作时,利用快捷键代替鼠标.可以利用键盘快捷键打开.关闭和导航"开始"菜单.桌面.菜单.对话框以及网页.键盘还可以让您更简单地与计算机交互.  单击一个标题或按 TAB 键可以突出显示这个标题,然后按 ENTER 键. 常规键盘快捷键 请按 目的  Ctrl + C 复制.  Ctrl + X 剪切.  Ctrl + V 粘贴.  Ctrl + Z 撤消.  DELETE 删除.  Shift + Delete 永久删除所选项,而不将它放到"回收站&qu

电脑快捷键大全

这个就是电脑上键盘所有键的功能. CTRL组合键Ctrl + A 全选Ctrl + B 整理 收藏夹Ctrl + C 复制Ctrl + D 删除/添加收藏 (在Word中是修改选定字符格式,在IE及傲游中是保存为收藏)Ctrl + E 搜索助理 在Word中是段落居中Ctrl + F 查找Ctrl+ G 在Word中是定位Ctrl + H 历史记录 在Word中是替换Ctrl + I 收藏夹Ctrl + J IE7.0里的源Ctrl + K 在Word中是插入链接Ctrl + L =Ctrl+O

windows快捷键使用

快捷方式 编辑 F1 显示当前程序或者windows的帮助内容. F2 当你选中一个文件的话,这意味着"重命名" F3 当你在桌面上的时候是打开"查找:所有文件" 对话框 F5 刷新 F10或ALT 激活当前程序的菜单栏 F11当你在打开网页时,是隐藏侧边栏 F12在编辑好Excel 或Word文档,可"另存为" Backspace 如果在"另存为"或"打开"对话框中选中了某个文件夹,则打开上一级文件夹 E

Linux(CentOS)下安装git

上个月把VPS迁到budgetVM,终于不用再受digitalOcean的气了,入手很方便,重点是支持支付宝付款——paypal的界面真是不习惯,开通速度挺快的,1G的内存够我折腾一段时间了~,额外送了俩IP,过段时间再研究下把我那几个二级域名也绑定过来 今天刚把主站部署好,发现CentOS默认没有git工具,Git官网 提示可以通过yum安装 yum install git 敲下命令,过了几分钟提示 Setting up Install Process No package git avail

【转】如何用快捷键快速调出我的电脑,网上邻居和控制面板

单独按Windows:显示或隐藏 "开始"功能表 Windows+BREAK:显示"系统属性" 对话框 Windows+D:显示桌面 Windows+M:最小化所有窗口 Windows+Shift+M:还原最小化的窗口 Windows+E:开启"资源管理器" Windows+F:查找文件或文件夹 Windows+CTRL+ F:查找电脑 Windows+F1:显示 Windows "帮助" Windows+R:开启"

Linux下终端利器tmux(转)

“君子生非异也,善假于物也” .–语出<荀子·劝学> 如果记得没错的话,<荀子·劝学>我们这一代高中的时候应该都读过这篇文章.原意大概是君子的资质与一般人没有什么区别,君子之所以高于一般人,是因为他能善于利用外物.对于技术人来说,好工具的选择和使用往往可以省去很多不必要的麻烦,好的开源工具很多,看你如何去使用.对于终端复用工具这里推荐使用tmux,当然此类工具比较好的还有screen,不过相对screen 这里我更倾向于推荐tmux[强悍的分屏等]. 如果仅仅只是多标签的功能,那么