2014-03-24 112 views
0

我在LibGDX中創建我的第一個遊戲,併爲我的啓動畫面使用通用補間引擎。我使用Aurelien Ribondemo,除了我自己的圖像。問題發生在啓動畫面結束時,它給予Launcher的呼叫,然後從那裏呼叫擴展Test類的各個類。我發現沒有乾淨的方式給予我的LevelSelector類實現屏幕和使用階段進行渲染的控制。每當控制權進入我的課程時,它將調用其show(),並且不輸入render(),則調用hide()。這一直持續到應用程序停止。一直以來,App類(即主類)render()繼續被稱爲連續的。我已經找到了解決這個問題的方法,但它會導致內存問題,並使遊戲變得緩慢。任何人都可以請告訴我如何停止渲染App &傳輸控制到我的班級?libGDX遊戲卡在屏幕上顯示() - 隱藏()循環

我的解決方法的工作原理如下:

  1. 當點擊播放(延伸test),在應用程序中的初始化靜態標誌:inPlay設置。
  2. 在App render()中,如果設置isPlay,setScreen爲LevelSelector。
  3. 在LevelSelector中,如果點擊任何級別,設置App:inLevel的靜態標誌。
  4. 在App render()中,如果設置了inLevel,則將screenscreen設置爲該級別。

這個工作,但LevelSelector渲染,應用渲染&級別渲染甚至在屏幕後設置爲這會導致我的應用程序的延遲和存儲問題的程度都被調用,

是否有一個解決方案這個問題沒有使用周圍的工作?

我的代碼:

//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 && levelStarted==false){ 

      splashScreen = null; 
      launcherScreen = null; 
      Gdx.graphics.setContinuousRendering(false); 
      Gdx.input.setInputProcessor(pspt.stage); 
      this.setScreen(ls); 
     } 
     else if(inPlay && 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() < 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<Sprite> dots = new ArrayList<Sprite>(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 > 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<dots.size(); i++) { 
      if (dots.get(i).getScaleX() < 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<dots.size(); i++) dots.get(i).draw(batch); 
     for (int i=0; i<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 > 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<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 < 5; l++) { 
     Table levels = new Table().pad(50); 
     levels.defaults().pad(20, 40, 20, 40); 
     for (int y = 0; y <3; y++) { 
      levels.row(); 
      for (int x = 0; x < 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) >= 0) { 
     for (int star = 0; star < 3; star++) { 
      if (Utils.prefs.getInteger("rank"+j) > star && 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()); 
} 
} 
+2

我的水晶球說....沒什麼,因爲即使它不能幫助這裏沒有任何代碼... – noone

+0

你必須告訴我們你的show()方法的代碼,它進入循環。沒有這個代碼,我們不能告訴你什麼是錯的 – Springrbua

+0

所有類的代碼 –

回答

1

我發現在我的代碼的問題。重寫類擴展遊戲的render()方法會導致在每個屏幕的渲染之前調用渲染。這也會導致大量的內存問題,因爲一次調用3個渲染方法: 1>遊戲類別 2>測試類別 3>屏幕擴展測試類。

我解決了這個問題,我創建了一個新的MainScreen類,它擴展了Screen並在其中執行了所有正在擴展Game類的任務。

現在在任何給定的時間,只有1個渲染方法被調用,並且遊戲運行得更快。 這也減少了我的代碼,因爲我現在不得不在遊戲渲染中設置畫面,但可以遵循正常流程。

Game類

import com.badlogic.gdx.Game; 

public class PacketJourney extends Game { 

    @Override 
    public void create() 
    { 
     setScreen(new MainScreen(this)); 
    } 
} 

MainScreen類

import aurelienribon.tweenengine.BaseTween; 
import aurelienribon.tweenengine.Tween; 
import aurelienribon.tweenengine.TweenCallback;

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;

public class MainScreen implements Screen { private SplashScreen splashScreen; private ScreenLauncher launcherScreen; Utils utils;

private boolean isLoaded = false; public MainScreen() { utils = new Utils(null); } public MainScreen(PacketJourney game) { utils = new Utils(game); } @Override public void render(float delta) { if (isLoaded) { if (splashScreen != null) splashScreen.render(); if (launcherScreen != null) launcherScreen.render(); } else { if (Assets.inst().getProgress() < 1) { Assets.inst().update(); //update returns true when asset manager finishes loading all assets } else { launch(); isLoaded = true; } } } @Override public void resize(int width, int height) { } @Override public void show() { 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/launcher/screenLauncher", 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 hide() { } @Override public void pause() { } @Override public void resume() { } private void launch() { splashScreen = new SplashScreen(new TweenCallback() { @Override public void onEvent(int type, BaseTween source) { String str= ""; switch(type) { case TweenCallback.BEGIN : str = "BEGIN"; break; case TweenCallback.COMPLETE : str = "COMPLETE"; break; case TweenCallback.END : str = "END"; break; case TweenCallback.ANY : str = "ANY"; break; } splashScreen.dispose(); splashScreen = null; if(utils.game != null) launcherScreen = new ScreenLauncher(utils.screens,utils.spriteNames,utils); } }); } @Override public void dispose() { Assets.inst().dispose(); if (splashScreen != null) splashScreen.dispose(); if (launcherScreen != null) launcherScreen.dispose(); } }