title: libGDX game stuck on screen show() - hide() loop
body: <p>I am creating my first game in LibGDX and for my splash screen, I am making use of Universal tween engine. I am using <code>Aurelien Ribon</code>'s <a href="http://www.aurelienribon.com/blog/projects/universal-tween-engine/" rel="nofollow">demo</a> except for my own images. The problem occurs when the splash screen ends, it Gives a call to <code>Launcher</code> and from there on, it call the various classes extending the <code>Test</code> class. I found no clean way of giving the control to my <code>LevelSelector</code> class which implements screen and uses stage for rendering. Whenever the control goes to my class, it calls its <code>show()</code> and without entering the render(), it calls <code>hide()</code> . This continues till application is stopped. All the while the <code>App</code> class (i.e. the main class) render() continues to be called continuosly. i have figured out a work around for this but it causes memory problems and is making the game slow. can anyone please tell me how to stop the rendering of <code>App</code> &amp; transfer control to my class?</p>
  
  <p>My workaround works as follows :</p>
  
  <ol>
  <li>When click on Play (extends <code>test</code>), in its initialize static flag of App : inPlay is set.</li>
  <li>in App render(), if isPlay is set, setScreen as LevelSelector.</li>
  <li>in LevelSelector, if click on any level, set static flag of App : inLevel.</li>
  <li>in App render(), if inLevel is set, setscreen to that level.</li>
  </ol>
  
  <p>this works, but LevelSelector render, App render &amp; level render are all being called even when after screen is set to a level which causes delays and memory problems in my app,</p>
  
  <p>Is there a solution to this problem without using the work around?</p>
  
  <p>My Code :</p>
  
  <pre><code>//APP class
  
  import aurelienribon.tweenengine.BaseTween;
  import aurelienribon.tweenengine.Tween;
  import aurelienribon.tweenengine.TweenCallback;
  
  import com.badlogic.gdx.Game;
  import com.badlogic.gdx.Gdx;
  import com.badlogic.gdx.Screen;
  import com.badlogic.gdx.graphics.g2d.BitmapFont;
  import com.badlogic.gdx.graphics.g2d.Sprite;
  import com.badlogic.gdx.graphics.g2d.TextureAtlas;
  
  /**
   * @author Aurelien Ribon | http://www.aurelienribon.com/
   */
  public class App extends Game {
  private SplashScreen splashScreen;
  private Launcher launcherScreen;
  private boolean isLoaded = false;
  static boolean inPlay = false;
  static boolean levelStarted = false;
  static int levelIndex;
  LevelSelector ls;
  Screen screen;
  Level level;
  
  @Override
  public void create() {
      System.out.println("********App create********");
      Tween.setWaypointsLimit(10);
      Tween.setCombinedAttributesLimit(3);
      Tween.registerAccessor(Sprite.class, new SpriteAccessor());
  
      Assets.inst().load("data/splash/pack", TextureAtlas.class);
      Assets.inst().load("data/launcher/pack", TextureAtlas.class);
      Assets.inst().load("data/test/pack", TextureAtlas.class);
      Assets.inst().load("data/arial-16.fnt", BitmapFont.class);
      Assets.inst().load("data/arial-18.fnt", BitmapFont.class);
      Assets.inst().load("data/arial-20.fnt", BitmapFont.class);
      Assets.inst().load("data/arial-24.fnt", BitmapFont.class);
  
  }
  
  @Override
  public void dispose() {
      Assets.inst().dispose();
      if (splashScreen != null) splashScreen.dispose();
      if (launcherScreen != null) launcherScreen.dispose();
      if(screen != null) screen.dispose();
  }
  
  @Override
  public void render() {
  
      if (isLoaded) {
          screen = null;
          if (splashScreen != null) splashScreen.render();
         if(inPlay &amp;&amp; levelStarted==false){
  
              splashScreen = null;
              launcherScreen = null;
              Gdx.graphics.setContinuousRendering(false);
              Gdx.input.setInputProcessor(pspt.stage);
              this.setScreen(ls);
          }
          else if(inPlay &amp;&amp; levelStarted)
          {
              level.setLevelIndex(levelIndex);
              screen = level.getLevelScreen();
              if(screen != null)
              {
                  splashScreen = null;
                  launcherScreen = null;
                  Gdx.graphics.setContinuousRendering(false);
                  this.setScreen(screen);
              }
          }
          if (launcherScreen != null) launcherScreen.render();
  
      } else {
          if (Assets.inst().getProgress() &lt; 1) {
              Assets.inst().update();  //update returns true when asset manager finishes loading all assets
          } else {
              launch();
              isLoaded = true;
              inPlay = false;
          }
      }
  }
  
  @Override public void resize(int width, int height) {}
  @Override public void pause() {}
  @Override public void resume() {}
  
  private void launch() {
      System.out.println("********App Launch********");
      ls = new LevelSelector(this);
      screen = null;
      level = new Level();
      splashScreen = new SplashScreen(new TweenCallback() {
          @Override public void onEvent(int type, BaseTween source) {
              Test[] tests = new Test[] {
                      new Info(),
                      new Help(),
                      new PlayScreen()
              };
  
              splashScreen.dispose();
              splashScreen = null;
              launcherScreen = new Launcher(tests);
          }
      });
  }
  }
  
  
  //TEST class
  
  public abstract class Test {
  private final TweenManager tweenManager = new TweenManager();
  private final TextureAtlas atlas;
  private final Sprite background;
  private final Sprite veil;
  private final Sprite infoBack;
  private final List&lt;Sprite&gt; dots = new ArrayList&lt;Sprite&gt;(50);
  private boolean[] useDots;
  private Callback callback;
  
  protected final OrthographicCamera camera = new OrthographicCamera();
  protected final SpriteBatch batch = new SpriteBatch();
  protected final Random rand = new Random();
  protected final BitmapFont font;
  protected final float wpw = 10;
  protected final float wph = 10 * Gdx.graphics.getHeight() / Gdx.graphics.getWidth();
  protected Sprite[] sprites;
  
  public Test() {
      System.out.println("********Test Constructor********");
      atlas = Assets.inst().get("data/test/pack", TextureAtlas.class);
      background = atlas.createSprite("background");
      veil = atlas.createSprite("white");
      infoBack = atlas.createSprite("white");
  
      int w = Gdx.graphics.getWidth();
      if (w &gt; 600) font = Assets.inst().get("data/arial-24.fnt", BitmapFont.class);
      else font = Assets.inst().get("data/arial-16.fnt", BitmapFont.class);
  }
  
  // -------------------------------------------------------------------------
  // Abstract API
  // -------------------------------------------------------------------------
  
  public abstract String getTitle();
  public abstract String getInfo();
  public abstract String getImageName();
  public abstract InputProcessor getInput();
  protected abstract void initializeOverride();
  protected abstract void disposeOverride();
  protected abstract void renderOverride();
  
  // -------------------------------------------------------------------------
  // Public API
  // -------------------------------------------------------------------------
  
  public static interface Callback {
      public void closeRequested(Test source);
  }
  
  public void setCallback(Callback callback) {
      System.out.println("********Test setCallback********");
      this.callback = callback;
  }
  
  public void initialize() {
      System.out.println("********Test initialize********");
      if (isCustomDisplay()) {
          initializeOverride();
          return;
      }
  
      camera.viewportWidth = wpw;
      camera.viewportHeight = wph;
      camera.update();
  
      background.setSize(wpw, wpw * background.getHeight() / background.getWidth());
      background.setPosition(-wpw/2, -background.getHeight()/2);
  
      veil.setSize(wpw, wph);
      veil.setPosition(-wpw/2, -wph/2);
  
      infoBack.setColor(0, 0, 0, 0.3f);
      infoBack.setPosition(0, 0);
  
      initializeOverride();
  
      Tween.set(veil, SpriteAccessor.OPACITY).target(1).start(tweenManager);
      Tween.to(veil, SpriteAccessor.OPACITY, 0.5f).target(0).start(tweenManager);
  }
  
  public void dispose() {
      System.out.println("###Test dispose###");
      tweenManager.killAll();
      dots.clear();
      sprites = null;
      useDots = null;
  
      disposeOverride();
  }
  
  public void render() {
      System.out.println("********Test render********");
      if(App.inPlay == false)
      {
          if (isCustomDisplay()) {
              System.out.println("CustomDisplay : True");
              renderOverride();
              return;
          }    
          // update
  
          tweenManager.update(Gdx.graphics.getDeltaTime());
  
          for (int i=0; i&lt;dots.size(); i++) {
              if (dots.get(i).getScaleX() &lt; 0.1f) {
                  dots.remove(i);
              }
          }
  
          // render
          GLCommon gl = Gdx.gl;
          gl.glClearColor(1, 1, 1, 1);
          gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
          gl.glEnable(GL10.GL_BLEND);
          gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
  
          int w = Gdx.graphics.getWidth();
          int h = Gdx.graphics.getHeight();
  
          batch.setProjectionMatrix(camera.combined);
          batch.begin();
          batch.disableBlending();
          background.draw(batch);
          batch.enableBlending();
          for (int i=0; i&lt;dots.size(); i++) dots.get(i).draw(batch);
          for (int i=0; i&lt;sprites.length; i++) sprites[i].draw(batch);
          batch.end();
          System.out.println("********Test call renderOverride********");
          renderOverride();
  
          if (getInfo() != null) {
              int padding = 15;
              BitmapFont.TextBounds bs = font.getWrappedBounds(getInfo(), w - padding*2);
              infoBack.setSize(w, bs.height + padding*2);
              font.setColor(Color.WHITE);
  
              batch.getProjectionMatrix().setToOrtho2D(0, 0, w, h);
              batch.begin();
              infoBack.draw(batch);
              font.drawWrapped(batch, getInfo(), padding, bs.height + padding, w - padding*2);
              batch.end();
          }
  
          if (veil.getColor().a &gt; 0.1f) {
              batch.setProjectionMatrix(camera.combined);
              batch.begin();
              veil.draw(batch);
              batch.end();
          }
      }
  }
  
  // -------------------------------------------------------------------------
  // Helpers
  // -------------------------------------------------------------------------
  
  protected boolean isCustomDisplay() {
      return false;
  }
  
  protected void forceClose() {
      System.out.println("#######Test forceClose########");
      if (callback != null) callback.closeRequested(this);
  }
  
  protected void createSprites(int cnt) {
      System.out.println("********Test create Sprites : "+cnt+"********");
      sprites = new Sprite[cnt];
      useDots = new boolean[cnt];
  
      for (int i=0; i&lt;cnt; i++) {
          int idx = rand.nextInt(400)/100 + 1;
          sprites[i] = atlas.createSprite("sprite" + idx);
          sprites[i].setSize(1f, 1f * sprites[i].getHeight() / sprites[i].getWidth());
          sprites[i].setOrigin(sprites[i].getWidth()/2, sprites[i].getHeight()/2);
          useDots[i] = false;
      }
  }
  
  protected void center(Sprite sp, float x, float y) {
      sp.setPosition(x - sp.getWidth()/2, y - sp.getHeight()/2);
  }
  
  protected void enableDots(int spriteId) {
      useDots[spriteId] = true;
  
      Tween.call(dotCallback)
      .delay(0.02f)
      .repeat(-1, 0.02f)
      .setUserData(spriteId)
      .start(tweenManager);
  }
  
  protected void disableDots(int spriteId) {
      useDots[spriteId] = false;
  }
  
  private final Vector2 v2 = new Vector2();
  private final Vector3 v3 = new Vector3();
  protected Vector2 touch2world(int x, int y) {
      v3.set(x, y, 0);
      camera.unproject(v3);
      return v2.set(v3.x, v3.y);
  }
  
  // -------------------------------------------------------------------------
  // Helpers
  // -------------------------------------------------------------------------
  
  private final TweenCallback dotCallback = new TweenCallback() {
      @Override
      public void onEvent(int type, BaseTween source) {
          System.out.println("********Test dotCallback : onEvent********");
          int spriteId = (Integer) source.getUserData();
  
          if (useDots[spriteId] == false) source.kill();
          Sprite sp = sprites[spriteId];
  
          Sprite dot = atlas.createSprite("dot");
          dot.setSize(0.2f, 0.2f);
          dot.setOrigin(0.1f, 0.1f);
          dot.setPosition(sp.getX(), sp.getY());
          dot.translate(sp.getWidth()/2, sp.getHeight()/2);
          dot.translate(-dot.getWidth()/2, -dot.getHeight()/2);
          dots.add(dot);
          Tween.to(dot, SpriteAccessor.SCALE_XY, 1.0f).target(0, 0).start(tweenManager);
      }
  };
  
  // -------------------------------------------------------------------------
  // Dummy
  // -------------------------------------------------------------------------
  
  public static final Test dummy = new Test() {
      @Override public String getTitle() {
          System.out.println("********Test dummy getTitle********");
          return "Dummy test";}
      @Override public String getInfo() {
          System.out.println("********Test dummy getInfo********");
          return null;}
      @Override public String getImageName() {
          System.out.println("********Test dummy getImageName********");
          return null;}
      @Override public InputProcessor getInput() {
          System.out.println("********Test dummy getInput********");
          return null;}
      @Override protected void initializeOverride() {System.out.println("********Test dummy initOverride********");}
      @Override protected void disposeOverride() {System.out.println("********Test dummy disposeOverride********");}
      @Override protected void renderOverride() {System.out.println("********Test dummy renderOverride********");}
  };
  }
  
  
  //LevelSelector
  
  public class LevelSelector implements Screen {
  
  private Skin skin;
  Stage stage;
  private Table container;
  Game game;
  //  Level_1_1 level1;
  PagedScrollPane scroll ;
  int rank=0,leveldone;
  Table starTable;
  Utils Utils;
  
  public LevelSelector(Game game){
      //      System.out.println("########In pagedScrollPaneTest construct (App)##########");
      Gdx.input.setInputProcessor(stage);
      this.game = game;
      Utils = new Utils();
  
      stage = new Stage(0, 0, false);
      skin = new Skin(Gdx.files.internal("data/uiskin.json"));
      skin.add("top", skin.newDrawable("default-round", Color.RED), Drawable.class);
      skin.add("star-filled", skin.newDrawable("white", Color.YELLOW), Drawable.class); 
      skin.add("star-unfilled", skin.newDrawable("white", Color.GRAY), Drawable.class);
  
      Gdx.input.setInputProcessor(stage);
  
      container = new Table();
      stage.addActor(container);
      container.setFillParent(true);
  
      scroll= new PagedScrollPane();
      scroll.setFlingTime(0.1f);
      scroll.setPageSpacing(25);
      int c = 1;
      for (int l =0; l &lt; 5; l++) {
          Table levels = new Table().pad(50);
          levels.defaults().pad(20, 40, 20, 40);
          for (int y = 0; y &lt;3; y++) {
              levels.row();
              for (int x = 0; x &lt; 1; x++) {
                  levels.add(getLevelButton(c++)).expand().fill();
              }
          }
          scroll.addPage(levels);
      }
      container.add(scroll).expand().fill();
  
  }
  
  public void resize (int width, int height) {
      stage.setViewport(width, height, true);
  }
  
  public void dispose () {
      System.out.println("In selector dispose ####");
      Gdx.input.setInputProcessor(null);
      stage.dispose();
      skin.dispose();
  }
  
  public boolean needsGL20 () {
      return false;
  }
  
  /**
   * Creates a button to represent the level
   * 
   * @param level
   * @return The button to use for the level
   */
  public Button getLevelButton(int level) {
      Button button = new Button(skin);
      ButtonStyle style = button.getStyle();
      style.up =  style.down = null;
  
      // Create the label to show the level number
      Label label = new Label(Integer.toString(level), skin);
      label.setFontScale(2f);
      label.setAlignment(Align.center);       
  
      // Stack the image and the label at the top of our button
      button.stack(new Image(skin.getDrawable("top")), label).expand().fill();
  
      // Randomize the number of stars earned for demonstration purposes
      int stars = rank;
      starTable = new Table();
      int j=level;
      starTable.defaults().pad(5);
  
      if (Utils.prefs.getInteger("rank"+j) &gt;= 0) {
          for (int star = 0; star &lt; 3; star++) {
              if (Utils.prefs.getInteger("rank"+j) &gt; star &amp;&amp; level== Utils.prefs.getInteger("level"+j)) {
                  System.out.println("\n\nHAd saved option Level:: "+Utils.prefs.getInteger("level"+j));
                  System.out.println("HAd saved option Rank :: "+Utils.prefs.getInteger("rank"+j));
                  starTable.add(new Image(skin.getDrawable("star-filled"))).width(20).height(20);
              } 
              else {
                  starTable.add(new Image(skin.getDrawable("star-unfilled"))).width(20).height(20);
              }
          }           
      }
  
      button.row();
      button.add(starTable).height(30);
  
      button.setName("level" + Integer.toString(level));
      button.addListener(levelClickListener);
      return button;
  }
  
  /**
   * Handle the click - in real life, we'd go to the level
   */
  public ClickListener levelClickListener = new ClickListener() {
      @Override
      public void clicked (InputEvent event, float x, float y) {
          System.out.println("Click: " + event.getListenerActor().getName());
          String levelSelected = event.getListenerActor().getName();
          if(levelSelected.equalsIgnoreCase("level1"))
          {
              App.levelStarted = true;
              game.dispose();
              App.whichLevel = levelSelected;
              App.levelIndex = 1;
          }
          if(levelSelected.equalsIgnoreCase("level2"))
          {
              App.levelStarted = true;
              game.dispose();
              App.whichLevel = levelSelected;
              App.levelIndex = 2;
          }
      }
  };
  
  
  @Override
  public void show() {
      System.out.println("########In pagedScrollPaneTest show##########");
      render(Gdx.graphics.getDeltaTime());
  }
  
  @Override
  public void hide() {
      System.out.println("########In pagedScrollPaneTest hide##########");
  }
  
  @Override
  public void render(float delta) {
      GLCommon gl = Gdx.gl;
      gl.glClearColor(1, 1, 1, 1);
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
      Gdx.input.setInputProcessor(stage);
      //      System.out.println("########In pagedScrollPaneTest renderer(float)##########");
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  
      stage.act();
      stage.act(Gdx.graphics.getDeltaTime());
      stage.draw();
  
      Table.drawDebug(stage);
  }
  
  @Override
  public void pause() {}
  @Override
  public void resume() {}
  
  }
  
  //PlayScreen
  public class PlayScreen extends Test {
  private final TweenManager tweenManager = new TweenManager();
  
  @Override
  public String getTitle() {
      return "Play";
  }
  
  @Override
  public String getInfo() {
      return "Select which level you want to play.";
  }
  
  @Override
  public String getImageName() {
      return "tile-path";
  }
  
  @Override
  public InputProcessor getInput() {
      return null;
  }
  
  @Override
  protected void initializeOverride() {
      System.out.println("#####Play Screen#####");
      App.inPlay = true;
  }
  
  @Override
  protected void disposeOverride() {
      tweenManager.killAll();
      super.dispose();
  
  }
  
  @Override
  protected void renderOverride() {
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
      tweenManager.update(Gdx.graphics.getDeltaTime());
  }
  }
  </code></pre>