Is it safe to call Screen.hide() after Screen.dispose() in LibGDX? - java

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.

Related

Why not called the cancel method on animatorset directly and what exactly is the animator?

I have three questions that I really need to clarify one them is in the code provided by the android developer at this link: http://developer.android.com/training/animation/zoom.html#animate (I didn't want to overwhelm you with the code so I didn't copy and paste the code here and the code is under the section called "Zoom the View")
1) So my question is why does the programmer do the following? mCurrentAnimator = set and then write
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
Let me quickly mention that mCurrentAnimator is an Animator object and set is an AnimatorSet object. My confusion lies in the fact that why does the developer feel the need to make the an Animator object = to a AnimatorSet object before calling the cancel() because from my perspective, since AnimatorSet extends Animator then shouldn't I be able to call the cancel method directly. Why feel the need to make a superclass = to the subclass to call a method when the subclass already can call that method?
2) My question is what exactly is an Animator because when I check at the documentation there are some method of this class such as public void setTarget (Object target) which made me confuse. What made me confuse was the fact that the description stated this method "Sets the target object whose property will be animated by this animation". Precisely how can an animator tells what property to animate just simply by providing a target?
3) Also, one of the animator method was public void setupStartValues () and the description stated "This method tells the object to use appropriate information to extract starting values for the animation. For example, a AnimatorSet object will pass this call to its child objects to tell them to set up the values." However, what I don't understand is how can a method be pass into a child object and how does the method tells the object to use what information to use so that it is appropriate??
For your first question, the main function of that example is to zoom the image thumbnail when the user clicks on it. You'll notice that the mCurrentAnimator.cancel() method is called at the very beginning of the onClick method, and mCurrentAnimator = set is at the end. What this is doing is, once an animation is created and started, the program is saving a reference to it. This is useful because what if, say, the user clicks the thumbnail, the image starts to animate, and while the animation is running, the user clicks the image again? the mCurrentAnimator will hold the reference to the animation currently in progress, and the mCurrentAnimator.cancel() stops that animation so that the onClick method can create another animator in response to the most recent click.
For the second question, simply put, an Animator is used to animate a given view by changing its properties. To address the confusion around the setTarget method, that method is not a constructor. If you want to create a new animator, you can use the ofFloat, ofArgb, or similar static methods from the ObjectAnimator class. You can read about them here. Using those methods, you tell the animator what properties it needs to change. The setTarget method is only to change what object you are animating in an existing animator, which can be useful if you would like to apply the same animator to multiple views.
Finally, an AnimatorSet is essentially a container to hold different animations you want to play either together or in sequence. Very simply, "passing the call" means that, when you call the setupStartValues() on the AnimatorSet, it calls the setupStartValues() method on each of the individual Animators belonging to that set.
I hope this helps!

How to reuse assets in libGDX?

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

On libgdx catching onClose window event

I am working on a libgdx game and I'd like to use the preferences for storing player's advances and preferences.
So far so good. In android there are nice events for updating the preferences and storing them into the file system.
I was wondering if something similar does exist on the desktop side. Namely, is there any way of adding a listener for whe user is closing the window?
That way I'll be able to flush data before application closes.
Or there are any other method?
Your main game implements ApplicationListener, which has the dispose() method. This method gets called, if you close your window or exit the game. So you can simply flush() your Preferences in the dispose() method.
But as #noone said you should also think, that your app could crash for some reason. If this happens dispose() won't be called. It won't be that big problem for Preferences like Soundoptions or Graphic settings, as you can easily set them next time, but if a Player looses his progress, he will be frustrated. So i would think about using one of the following methods:
flush() on every change. You can be sure everything is safed. For progress you can flush() on some special events/safepoints
flush() after some time. Lets say every 5 minutes?
flush() on a KeyEvent/Button press in the menu.

Proper way to dispose screens in Libgdx

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();
}
...
}

when a new Screen is called then will the old screen be disposed?

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

Categories