tween - libGDX game stuck on screen show() - hide() loop -
i creating first game in libgdx , splash screen, making use of universal tween engine. using aurelien ribon
's demo except own images. problem occurs when splash screen ends, gives call launcher
, there on, call various classes extending test
class. found no clean way of giving control levelselector
class implements screen , uses stage rendering. whenever control goes class, calls show()
, without entering render(), calls hide()
. continues till application stopped. while app
class (i.e. main class) render() continues called continuosly. have figured out work around causes memory problems , making game slow. can please tell me how stop rendering of app
& transfer control class?
my workaround works follows :
- when click on play (extends
test
), in initialize static flag of app : inplay set. - in app render(), if isplay set, setscreen levelselector.
- in levelselector, if click on level, set static flag of app : inlevel.
- in app render(), if inlevel set, setscreen level.
this works, levelselector render, app render & level render being called when after screen set level causes delays , memory problems in app,
is there solution problem without using work around?
my 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 && 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 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()); (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(); (int i=0; i<dots.size(); i++) dots.get(i).draw(batch); (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]; (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; (int l =0; l < 5; l++) { table levels = new table().pad(50); levels.defaults().pad(20, 40, 20, 40); (int y = 0; y <3; y++) { levels.row(); (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 button represent level * * @param level * @return button use level */ public button getlevelbutton(int level) { button button = new button(skin); buttonstyle style = button.getstyle(); style.up = style.down = null; // create label show level number label label = new label(integer.tostring(level), skin); label.setfontscale(2f); label.setalignment(align.center); // stack image , label @ top of our button button.stack(new image(skin.getdrawable("top")), label).expand().fill(); // randomize number of stars earned demonstration purposes int stars = rank; startable = new table(); int j=level; startable.defaults().pad(5); if (utils.prefs.getinteger("rank"+j) >= 0) { (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 click - in real life, we'd go 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 level want 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()); } }
i found out problem in code. overriding render()
method of class extending game cause render called ahead of each screen's render. cause plenty of memory issues @ time 3 render methods being called : 1>game class 2>test class 3>screen extending test class.
i solved problem creating new mainscreen
class extends screen , in performed tasks being done in class extending game.
now @ given time, 1 render method gets called , game runs lot faster. reduced code longer have setscreen in game's render can follow normal flow.
game class
import com.badlogic.gdx.game; public class packetjourney extends game { @override public void create() { setscreen(new mainscreen(this)); } }
mainscreen class
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 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(); } }
Comments
Post a Comment