What is the proper way of completely disposing of a screen in Libgdx? Currently If I click where a button was on my previous screen the button still does what it would of done if I were on that screen. Should I be .dispose()-ing everything I can in the dispose() method? or is there a simpler way to dispose of everything on screen?
Unfortunately there is no easier way. These classes do not share any kind of common "Disposable" interface, or anything like that, to do it automatically. Everything that has a dispose() method needs to be disposed manually when it's not needed anymore.
This is also valid for the Screens themselves. When switching Screens they do not get disposed automatically, but you need to do that yourself (before calling Game.setScreen()).
On the other hand, this is not a big deal. Just look through everything in your Screen and check whether it has to be disposed or not. If there is a dispose method, call it in dispose() of the Screen.
BUT this does not explain your behaviour about invisible buttons from the last Screen. I suppose you use a Stage and used Gdx.input.setInputProcessor(stage);. This setting will not be changed when you change the screen and you have to set the input processor to the Stage of your current Screen, or to whatever that handles the input in your current Screen. That way the "old" stage will not catch any inputs anymore.
I can confirm that this issue is not passing the inpur processor a new stage. this will result in "ghost" buttons as described.
Unfortunately LibGDX API documentation says
Note that dispose() is not called automatically.
So what I do is disposing all disposables (such as Stage, Skin, Texture ... etc) inside the hide() method in the Screen because hide() is called automatically and it works very well!
example:
public class GameScreen implements Screen {
...
#Override
public void hide() {
mainStage.dispose();
playGroundStage.dispose();
controller.dispose();
labelActor.dispose();
}
...
}
Related
In libgdx, screen.setScreen() doesn't call dispose automatically right. Inside a overridden setScreen, do I have to call screen.dispose first and then call super.setScreen or call the later first?
I know this may seem like duplicate question but still I wanted to know because super.setScreen calls screen.hide. Is calling hide after dispose run-time safe?
Is it a bad practice?
I am making a 3D game based on this and this example .
Here I am extending GameName class by Game and trying to override setScreen so as to call dispose if screen is not null and then call super.setScreen .
screen.dispose() is never called by LibGDX. You must do it manually yourself before dropping the reference to your screen. If you don't plan to reuse the Screen instance, having screen.hide() call screen.dispose() is the perfect place to do it.
screen.hide() is never called in response to Android events.
I don't recommend overriding game.setScreen() to dispose of screens unless you know for sure you never want to reuse any screen instances. In most simple games, you do want to reuse them rather than waste time unloading and reloading assets repeatedly.
Two type of disposable assets(SpriteBatch, Texture, Stage, ...), one is shared on different screen and another one is specific for particular screen.
Shared Assets should be disposed from Game's dispose() method.
Screen specific assets should be disposed through dispose() method of Screen but screen's dispose() never called so you need to call it explicitly.
When you change your screen hide() method of Screen called so you should call dispose() method from hide() method.
Working with libGDX, and in this particular project we are using Dialog to have a box popup when the user clicks a certain button.
What I want is to be able to dismiss the Dialog by clicking outside of it.
At other times, I have used two tables, a background table and a menu table, and added a transparent background to the background table that when clicked will remove both of those tables from the Stage.
I have tried making a class that has a both a Dialog and a background table like the one mentioned above, but the background table never receives any actions.
I have also tried simply adding this background table to the stage before creating the dialog box, but this does not work either.
Finally, I have also tried to subclass Dialog, the idea being to override the show(stage) method to change its behavior, but I don't know how to do this one, and I'm not sure if it would work, anyway.
I believe the problem is that dialog.show(stage) changes the situation in the stage to only accept clicks inside the Window of the dialog box. I have seen this question about adding a close button to a dialog box, but playing with the clipping settings is not working to fix this problem.
There is also the possibility that when show() calls the pack() method and does its layout thing that something is happening that is making what I am trying to do impossible. I think that the solution will be overriding show() or overriding pack(), or both, but I don't know how to do this.
I can post code if need be, but this should be a pretty complete description of what I have tried and what I need to accomplish.
I know this is an old question but for those like me that searched the entire web for an answer only to find it inside libGDX code, the answer to .close() a libGDX dialog by code is simply to call the method
dialog.hide();
EDIT (added from the comments below):
so all he needs to do is register a global touch down event and see if
the touch has happened inside the Rectangle of his dialog, if not,
close it
Let's say I have a screen A with Skin that was loaded in memory by asset manager:
private Skin skin;
...
skin = (Skin)MyGame.ResourceManager.getAsset(AssetEnum.UISkin);
//UISkin("Menu/UISkin.json", Skin.class),
I need to load the next screen B that also refers to AssetEnum.UISkin. The simple way is
dispose screen A
unload resources of screen A
load resources of screen B
initialize screen B
But I want to show some loading wheel on the screen A while resources of screen B are still loading. With this extension steps look like
load resources of screen B
initialise and set screen B
dispose screen A
unload resources of screen A
The problem is when I call dispose on third step, skin.dispose() removes texture of previous screen that I also need on current. And this situation appears every time when "dispose screen A" is after "load resources of screen B". Does anyone have any suggestions? Please help
You can create a separate static class that loads your assets and keep it until you don't need it anymore.
Lets call this class AssetLoader.
I assume that you know how java works and how libgdx works.
Within the class, AssetLoader, you create 2 methods
Public static void load() {}
and
Public static void dispose() {}
Also declare your skin as a static member
Public static Skin skin;
Within your load() method do the loading of your skin, and within your dispose() method you write your disposal method.
When your want to want to load your assets, call
AssetLoader.load();
the methods are all static you don't need to initialize AssetLoader in your entire code. Just call it.
When you want to use the skin (for example, your Screen1() method)
UISkin("Menu/UISkin.json", AsssetLoader.Skin.class);
Finally when your game ends, you call
Assetoader.dispose();
You can literally put anything in the AssetLoader that is static. Such as textures and soundtracks. The benefit is that you only need to call the load() method once in your entire code and you can use it for the entire duration of your game. Just remember to dispose it when you don't need it anymore.
EDIT: Another thing you can do is to use AssetManager
More details here
I am coding newly in android libgdx framework.
I got a basic doubt if i navigate from one screen to another will the old screen be disposed or wait in paused or hide state??
please help me out with this doubt.
From https://code.google.com/p/libgdx-users/wiki/ScreenAndGameClasses:
Note that Screen's dispose() method is never called automatically- when ApplicationListener's dispose() method is called, Game calls screen.hide() instead.
It depends on you, if you are move from one screen to another screen and if you used finish() method with intent then first screen will be disposed otherwise it will be in paused state.
With ur approach it wont.All the graphics and objects will be there in memory untill u dispose them explicitly.
If u dispose them then make sure to load them again
How can I do to create a loading jframe without title bar like Eclipse in the image...
I used setUndecorate() to remove the title bar and a thread to wait 3 seconds then open the main window but it wouldn't work ...
I'm not thinking to use a progressbar...
How can I do??
Thanks in advance.
Best rgards,
Ali
See the SplashScreen class.
It includes the createGraphics() method that returns a Graphics2D object that can be written to. You would need to draw the progress bar to the graphics object.
Java Web Start also offers splash screen functionality, configured in the launch file. But the graphics object of the JWS splash screen are not available to the app. (so no 'progress bar').
Another way could be what you already thought of: display an undecorated JFrame when the application starts, then instead of just waiting for a few seconds (you could do that as well, if you want users to read some info) just keep initializing the application. When initialization is finished, close the "splash screen" (undecorated JFrame) and open the actual application JFrame.
This would enable you to display dynamic information (like a progress bar if you later want to, some text etc.). If all you need is a static splash screen, go for Andrew's advice and use the built in splash screen functionality.