码迷,mamicode.com
首页 > 其他好文 > 详细

libgdx Screen 切换

时间:2014-09-12 16:59:53      阅读:544      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   使用   ar   strong   

我们一般在开发时,都会分成多个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。加入这些,我就是为了感受一下切换是否生硬。

以下是效果图:

bubuko.com,布布扣

 

以下是调试信息:

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

 

libgdx Screen 切换

标签:style   blog   http   color   io   os   使用   ar   strong   

原文地址:http://www.cnblogs.com/hanhongmin/p/3968594.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!