I understand that the show() method is used to bring the screen back to the front when the user re-opens the app or brings it to the foreground.
However, what should go here?
Lets say I have a bunch of objects, with textures attached and actively being rendered and constantly moving position.
If I say, hit the pause button, the hide() function gets called and I the initiate a new screen. Say I come back to the GameScreen, does libGDX/Box2d automatically take care of everything for me or do I have to make sure that I have some sort of code in the show() method?
Anything that needs to be stopped in hide() should be restarted if needed in show(). This could include music, background threads, etc. I use show() to refresh the data behind the screen, since I keep instances around to avoud garbage collection.
There's no need for you to do anything, unless you want to put here some specific initializations. For instance, show() method is a good place to start playing a background music for the recently showed scene.
Related
I wrote a fade in fade out method for views. It works perfectly, but, as I understand, each view's animation is handled by a separate thread in the background, tackled by the android system.
That is a problem, because, I want to blink and the same pace.
Is it possible to do that? I tried to put my blinking method in a runnable and restart it every time a new View starts its animation, but it is not working because 1. you cannot simply restart a thread, 2. even if you can, the Animation will be handled by the system with different threads each running independently anyway.
How should I do this?
Let me narrate my goal again: I tap on a view, it starts blinking, fade in fade out style, using a method I wrote. Then I tap on another, both blinking at the same pace, with the first one perhaps noticeably changes its original blinking pace to be in sync with the 2nd one. Then I tap on another, another... no matter how many I enable blinking animation on, these views all fade in and fade out at the same pace.
Can you offer any advice? Either a specific one or a general one.
Okay, so this problem has been plaguing me for the past few days. And before anyone comments about it, yes I have made the jframe visible and I have added all the components that I need to it. Also, all components are added well before the GUI is set to visible and activate() is called.
So I am trying to run a couple simeple lines of code.:
g.setVisible(true);
g.activate();
Simple enough. g is an object made from a class I made GUI which extends JFrame. and activate() is a method that runs an infinite loop that just does a bunch of things until the user tells it to exit. However, when the program gets to the g.setVisible() line it opens a JFrame that is the size I specified however is completely devoid of anything. Then it moves onto the g.activate(); which at the moment runs for a specific amount of iterations and stops. At which point it finally decides that it can go back and display my GUI. The issue with that is that the GUI is meant to be updated by the loop from active() and keep the user in the know of what is going on.
Any help is appreciated let me know if you need more detials and thank you in advance.
In many different UI frameworks, it's common for the methods you call to queue some work rather than perform it immediately. From your description, it seems like setVisible() may be creating a native window but then queuing the rendering of the components. Since this code is (presumably) running in the UI thread, it won't perform the work it queued until after running activate().
Long-running tasks should never be run on the UI thread. In Swing, you can use SwingWorker or explicitly create a background thread.
My game takes around a minute to load in android till the first screen appears. Till the time its loading, jmonkey’s input manager seems to queue all inputs which results in nasty behavior(automatic button clicks) as soon as my first nifty screen loads.
Same happens when the scene loads(which again takes a while on pressing the appropriate nifty button). This happens despite the fact that I set mappings and listeners in the last App State which loads.
Is there a way to flush all previous input which I can call just before and after adding listeners to input manager?
I dont do much work in update() and initialize of my appstates but some functions (reinitialize()) which I call on nifty's OnClick(), loads all the scene and models in the scene garph so it takes a while. Here is a pseudo code of my application
In Main.java {
// Nothing in SimpleUpdate()
// This app state contains
stateManager.attach(new MainMenuAppState());
}
In MainMenuAppState.java implements ScreenController {
initialize() {
niftyDisplay = new NiftyJmeDisplay(app.getAssetManager(), app.getInputManager(), app.getAudioRenderer(), app.getGuiViewPort());
// Create a new nifty GUI object
nifty = niftyDisplay.getNifty();
// attach a couple of more app states which also has nothing significant in update loop
// do some good computation
// attach 5 new APP STATES which does not have anything significant in update()
display the appropriate screen of nifty
}
onClick() {
nifty.gotoScreen(“loadScreen”);
// appstate previously attached. they dont have anything significant in update.
// They have significant initialize methods.
app.enqueue(
rgas.reInitialize(time,cameraLoc,cameraRot);
maes.reInitialize(qId); // loads all the scene and models on screen
nifty.gotoScreen(“hudScreen”);
nifty.getScreen(“hudScreen”).findElementByName(“ConfirmModuleButton”).setFocus();
ppes.reInitialize(); // this contains input mappings
);
}
}
If there is a way to do this it will be on the InputManager so you could check out the API for that. Your problem may be though that the queue isn't really a queue in the way you are thinking. Potentially it is not a queue of input events but a queue of actions being taken in response to the events. Since events don't process until the update loop runs them then if the upload loop is stalled they will keep building up.
You could simply not add the listeners until the application has finished loading, then any events will get ignored automatically. You could also try breaking the scene loading up using a queue or similar of your own to load things a bit at a time while not completely stalling the system.
You may get a better response on this question if you try the jME3 forums. There are more monkeys active there than here including people with more detailed knowledge of the input system than me :)
I guess what Tim B said is your best bet.
However you could try calling nifty.setIgnoreMouseEvents(true) and nifty.setIgnoreKeyboardEvents(true) at some appropriate time to shut-off handling of any events that might reach Nifty and enable it later again.
My app plays a coin sound every time a button is pressed.
coin_sound.start();
You can easily press faster than the coin sound. When this happens I want the coin sound to start from the beginning ever time the button is pressed.
if(coin_sound.isPlaying()){
coin_sound.reset();
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
}
coin_sound.start();
The problem with this is that loading a media file tiny as it may be is still a relatively slow process. When you start to click the button really fast the app lags hard.
Are there any solutions to my problem? The only idea I have is to do something with an array of coin_sounds, but this method seems like it will be messy and gross...
The other answer posted here is somewhat correct. You should not call create over and over.
The code in that answer has a problem, though. The reset method sends the MediaPlayer into the idle state, where it is illegal to call most other methods. If you were to go that route, you have to call methods in the following order:
coin_sound.reset();
coin_sound.setDataSource(...);
coin_sound.prepare();
coin_sound.start();
The difference between calling create and the previous sequence of method calls is simply the creation of a new instance. That, however, is not the quickest way to do what should be done.
You should simply call coin_sound.seekTo(0); when you want the current playing sound to restart. So do something like:
if (coin_sound.isPlaying()) coin_sound.seekTo(0);
else coin_sound.start();
That assumes you have left the MediaPlayer in the prepared state so start can be called. You can accomplish that by calling reset, setDataSource, and prepare in the onCompletion listener. Also, make sure to call release when the sound is no longer needed.
It is because you are initiating coin_sound in the button click event, try this
initiate this variable in your oncreate method
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
then make this your code for your button
if(coin_sound.isPlaying()){
coin_sound.reset();
}
coin_sound.start();
the problem is you are recreating a new media player each time the button is clicked so the new media player doesnt think there is a sound
and do you need to start it again with coin_sound.start();? doesnt restart stop then start the sound for you?
I'm currently in the process of making one of my first android games and have come into some difficulty understanding how to make the transitions between screens.. for example:
My game starts its main activity, which then loads TitleScreen surface view which initializes its own thread
on tap I start a new intent which loads a new activity which loads GameView surface view which initializes its own thread
This all works fine when testing on my device (Evo 3d) but crashes on tap on my test bed, I'm using android x86 in virtual box for quick testing. Is this likely to be a problem in my code or a problem with the simulator?
Also I'm wanting to add a level select screen in between the title screen and the game screen and figured i could do this by creating another activity/surface view/thread combo, Is this acceptable coding practice or is this a wasteful/process heavy method?
You could create a variety of methods that you call from your onDraw method. Each method would draw one screen (game, level, score). To start simple a switch case in the onDraw checks the screen and then calls the right thing to draw.
If you want to have different layers, you should use different acitvities so that the background (game) is being paused while the scoreboard is active. This only makes sense if you want the background to be still visible or need the acitivites for other reasons.
But you should never have more than one surface view active at the same time, android doesnt like that.
I think its not good to use more activities for single application. Try to use ViewFlipper with number of xml layout files. Here you can apply transition effects very easily.
I am suggesting you it for transition effects, but you also check it once. I am also thinking which one is good.