I just want to check that the power button is pressed or not in LibGDX and if it is pressed then exit/close the game or something else like change screen.
I used this code:
#Override
public void render(SpriteBatch sb) {
sb.begin();
if(Gdx.input.isKeyPressed(Input.Keys.POWER)){
Gdx.app.exit();
}
sb.end();
}
but this is not working. After I press the button screen turns off and when I turn it back on the game resumes from exactly where I left it.
I wanted to keep the screen on on power button press but I didn't find any solution on that.
Now I at least want to access the button and then do something on button press.
the same code works for volume up/down button.
Code:
#Override
public void render(SpriteBatch sb) {
sb.begin();
if(Gdx.input.isKeyPressed(Input.Keys.VOLUME_UP)){
Gdx.app.exit();
}
sb.end();
}
Please describe if I'm doing anything wrong and what shall I do.
You can do all saves in pause method that is available in Screen and ApplicationListener classes. It will be called when you exit the app or block device.
#Override
public void pause () {
// save here
}
Related
I'm new in android development and have now problem and can not understand why and solve it.
Sorry, here is my idea and hope it helps to understand my question:
I would like to develop an app for the kids. I have two car roads. On both roads drive different cars with a certain number (0-10). The cars drive from left to right with the help of animation. A question with a number is asked. The child has to click on a certain car with the number x.
Below I've imageview (imgCarUp1) and try to animate from left to right. During animation I want to make click-event on my image and should run some code.
`
imgCarUp1 = findViewById(R.id.imgCarUp_1);
imgCarUp1.setImageResource(vehicleUpStreetList.get(0).getResId());
imgCarUp1.setTag(vehicleUpStreetList.get(0).getResId());
imgNumberUp1.setOnClickListener(view -> {
Log.d(TAG, String.format("setOnClickListener Tag: %s", view.getTag()));
...
});
TranslateAnimation animation = new TranslateAnimation(0, width - 50, 0, 0);
Animation.AnimationListener animL = new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
LogUtils.i(TAG, "onAnimationEnd is stopped!");
}
};
animation.setAnimationListener(animL);
animation.setDuration(15000);
animation.setRepeatCount(5);
animation.setRepeatMode(1);
animation.setFillAfter(true);
imgNumberUp1.startAnimation(animation);
`
Aninmation is working well. But if I try to click on imageview (imgNumberUp1) nothing will work. But if I click on area where animation was started, setOnClickListener works. I should be able to make click during animation. What is here my problem? Can someone please help with code?
Thanks a lot for helping.
Tried to search in internet, without any solution yet.
You are using Translate animation. Translate Animation translates the views position to the animated positions and wont actually change the views original position.
So you will need to change X and Y value to change the original position and then handle clicks wherever the animation is currently positioned
you can do .
view.animate().X().y().start()
while x and y will have the params of where you want to animate
I am making a game in Android Studio using LibGDX, and I am attempting to add a pause button to the top corner of the main game screen. My game has been pausing fine thus far, but I have only been pausing when a key was pressed. Now I want to add a button, and I got the button to render in the top right corner, but when I press it it only works once. The first time I press it, my game pauses fine. But every time I try and pause it after that, it doesn't work. I have used extensive log statements and debugging and have found out that after pressing it once, the Listener doesn't even detect the button being pressed at all, so I am lead to believe that is where my issue is.
This is how I create my button in my HUD class, which is the class that prints the score onscreen at all times:
TextureAtlas buttonAtlas = new TextureAtlas(Gdx.files.internal("Buttons.pack"));
Skin skin = new Skin();
skin.addRegions(buttonAtlas);
ImageButton.ImageButtonStyle style = new ImageButton.ImageButtonStyle();
style.imageUp = skin.getDrawable("PauseButton");
style.imageDown = skin.getDrawable("PauseButton");
style.imageChecked = skin.getDrawable("PauseButton");
button = new ImageButton(style);
I then added a Listener to check if the button is clicked:
button.addListener(new ClickListener()
{
#Override
public void clicked(InputEvent event, float x, float y)
{
Gdx.app.log("","Button was pressed");
pauseGame();
}
});
The method pauseGame() that is called after the Listener detects the button being clicked:
public void pauseGame()
{
Gdx.app.log("","Game should be pausing");
screen.pauseGame();
}
screen is a class called PlayScreen that is the main game screen for my game, and its pauseGame() method works perfectly. The game before you press the pause button is as follows(You can see the pause button in the top right corner, please excuse the graphics, they are simply placeholders until I make and add my own graphics):
Game before pause
In my main PlayScreen class, this is my pauseGame method:
public void pauseGame()
{
gamePaused = true;
if(music.isPlaying())
{
musicType = type.NORMAL;
music.pause();
}
else if(barrageMusic.isPlaying())
{
musicType = type.BARRAGE;
barrageMusic.pause();
}
createPauseWindow();
}
And then in my render method, I call another method called update. In this method, I update my viewport, my HUD, and create new enemies. This is the only method that stops being called when gamePaused is true. The rest of my rendering and other necessary updates still take place. I have been trying to fix this problem for a long time but no matter how many different ways I rewrite the code to pause the game or make different listeners, the pause button only works one time and then never again.
Have you ever tried with touchDown method?
It might works.
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pause();
event.handle();
return true;
}
});
And try to change to a global variable base, a variable that is checked inside your render method and if it is true call the pause method. That to avoid call complex actions like pause from a listener, something like this:
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pause = true;
event.handle();
return true;
}
});
...
public void render(){
if (pause == true){
pauseGame();
}
...
}
It simplifies your listener and let you find easily your error.
I have a splash screen and a menu screen class that loads all my texture atlases and skins for the menu and processes lots of stuff. If I put the constructor for the menu screen in the SplashScreen constructor or in the create() method of my main game class (MyGame class) then it would pass a lot of time with no splash screen render image on the phone while the whole stuff loads so I have delayed the loading of the menu class to the second frame render (gets called in the SplashScreen render method in the second frame); I simply check if I passed the first frame then I call a method on the main game class that loads the menus.
It all works fine , as expected , but only if the SplashScreen load process is not interrupted. If I get a call or I simple press the HOME button of the mobile and then I re-enter the game by clicking the icon on the home screen I get an AndroidGraphics error : "waiting for pause synchronization took too long: assuming dead lock and killing"; this is just after I can see the splash screen on the screen for about a second;
I tried to dispose the MyGame in the hide() and pause() methods of both the main game class and the splash screen class so it's terminated if I press the HOME button but they never get called.
How can I fix this? It would be annoying to get a call while loading the game and after you finish the call and try to re-enter the game it crashes.
public class MyGame extends Game{
...
public MainMenu menu;
...
#Override
public void create(){
this.screen_type == SCREEN_TYPE.SPLASH;
splashScreen = new SplashScreen();
setScreen(splashScreen);
}
...
#Override
public void pause(){
//never gets called if I press the HOME button in middle of splash screen
if(this.screen_type == SCREEN_TYPE.SPLASH)
{
this.dispose();
}
}
...
public void LoadMenuTimeConsumingConstructor(){
//load all menus and process data
main_menu = new MainMenu();
loaded_menu = true;
}
}
public class SplashScreen implements InputProcessor, Screen{
public MyGame main_game;
...
public SplashScreen(MyGame game){
this.main_game = game;
}
#Override
public void pause(){
//never gets called if I press the HOME button in middle of splash screen
if(main_game.screen_type == SCREEN_TYPE.SPLASH)
{
main_game.dispose();
}
}
#Override
public void hide(){
//never gets called if I press the HOME button in middle of splash screen
if(main_game.screen_type == SCREEN_TYPE.SPLASH)
{
main_game.dispose();
}
}
#Override
public void render(delta float){
...
//wait 1.5 sec
if(TimeUtils.millis() - startTime > 1500){
{
if(main_game.loaded_menu = true){
main_game.setScreen(main_game.main_menu);
}
}
...
if(is_this_second_frame){ // we start loading menus in the second frame so we already have the splash onscreen
main_game.LoadMenuTimeConsumingConstructor();
}
...
}
}
I do not understand your question very well, but if you are not using AssetManger Class, I think this read can help, I hope so.
If this response is not valid or not useful to you, tell me, and delete
wiki LibGDX
https://github.com/libgdx/libgdx/wiki/Managing-your-assets
video on YouTUBE
https://www.youtube.com/watch?v=JXThbQir2gU
other example in GitHub
https://github.com/Matsemann/libgdx-loading-screen
NEW look this:
Proper way to dispose screens in Libgdx
What's the right place to dispose a libgdx Screen
It can help you decide if you need to call dipose, and how, I hope it will help.
Hello I am working out a game and I wonder how to dispose resources as I am experiencing memory problems.
I have something like this:
public SplashScreen implements Screen {
#Override
public void render(float delta) {
}
#Override
public void dispose() {
if (batch != null)
batch.dispose();
batch = null;
}
}
public MapScreen implements Screen {
#Override
public void render(float delta) {
}
#Override
public void show() {
splashScreenInstance.dispose();
}
#Override
public void dispose() {
if (mesh != null)
mesh.dispose();
mesh = null;
}
}
And I am disposing the splash screen as soon as the show method of MapScreen is called. Previously I'd settled the screen to the MapScree. Still the render method of the splashScreenInstance is called and I'd received null pointer exceptions. Why this is so?
I'd expect that once I set another screen, the previous one is no longer rendered. This is not seemingly so. I'd tried disposing right after setting the screen using the game instance, right after the hide method is called on the screen I want to dispose and finally on the show method of the next screen. All of these cases still renders the previous screen a few times before rendering the current one.
I really need to recover memory and also I don't want to test each time (On the render method) for null pointers as this has performance penalties.
Any suggestions?
Thanks
This is how I usually handle this problem:
public SplashScreen implements Screen {
#Override
public void render(float delta) {
// I assume that you have a reference to the game somewhere to switch the screen
game.setScreen(new MapScreen());
dispose();
return;
}
}
I first set the new Screen, then dispose() the current one and then immediately stop any further execution of the current screen via return. This way the current render cycle should be stopped and in the next cycle the render() of your next screen will be called.
Another approach might be to call dispose() in your hide() method of the Screens, because that is going to be the last method being called before the Game will use the next screen. This is especially useful when there could be several different next screens. In that case there will still be only a single place of dispose() and that will be in the hide() method.
Where are you calling setScreen? Since everything should be happening in the rendering thread (even InputListeners) you should be able to call setScreen in your first Screen and then return from the render method. The Game instance will automatically call hide on your first Screen which is where you can call dispose.
Simplified code
play = new PushButton("Play");
play.getUpFace().setImage(new Image(pathToImages+offImage));
play.getUpHoveringFace().setImage(new Image(pathToImages+hoverImage));
play.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
//This event is captured
}
});
I require a keyboard button as a shortcut to play button accordingly I have added
Event.addNativePreviewHandler(new NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event)
{ //Call the functionality of play button for the approriate key press
}
});
But once I click the play button using mouse the above nativePreviewHandler does not capture the key press event from keyboard.
So I added a keyDownHandler to the play button
play.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
//This event is never fired
}
});
But the above onKeyDown() method is never called.
Only after I click at some other place on screen is the key press event captured by the nativePreviewHandler.
Just as additional info, I tried following without success
Added DomHandler to the play button instead of keyDownHandler
Removed the images set to the play button
Tried to unfocus the play button every time it is pressed using play.setFocus(false);
Any possible solutions or suggestions are appreciated.
The play button need to have the focus in order to be able to catch the keyDownEvent.
Could you check this ?
If you can't set the focus on that button: check this answer. You need to set a keyDownHandler to a container and ensure it is focused at all time in order to catch the events even if your button is not focused.
This will work:
Event.addNativePreviewHandler(new NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getNativeEvent().getType().equals("keydown")) {
Window.alert("Code: " + Integer.toString(event.getNativeEvent().getKeyCode()));
}
}
});