I create a Libgdx game and I want to know if it is possible to call the override pause method lifecycle with Libgdx?
Here is my pause method lifecycle in my class:
public class MyGdxGame extends ApplicationAdapter {
#Override
public void pause() {
super.pause();
chrono.pause();
//Display a pause menu
}
}
And I want to call the lifecycle method when I click on the pause image:
imagePause = new Image(new Texture(Gdx.files.internal("pause.png")));
imagePause.setSize(pauseSize, pauseSize);
imagePause.setPosition(width - pauseSize, height - pauseSize);
imagePause.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
//Something like this? :
Gdx.app.pause(); //Doesn't exist
//I don't want to call manually the pause method like this
//because it doesn't pause Libgdx lifecycle ...
pause();
}
});
stage.addActor(imagePause);
Any idea?
If your goal is to stop the render:
To stop the render:
Gdx.graphics.setContinuousRendering(false);
To put it back on:
Gdx.graphics.setContinuousRendering(true);
To trigger render when the rendering is stop:
Gdx.graphics.requestRendering();
Documentation: https://github.com/libgdx/libgdx/wiki/Continuous-&-non-continuous-rendering
Hope it will help you.
Related
i am newbie for libgdx,
How to create very simple pause/resume game in libgdx??
I'm trying to implement simple game using libgdx. I have want to create pause the game but don't know how to pause and resume game based on user input.Kindly suggest idea as well as some practical code to implement the same.I am using simple game code demonstrated in libgdx library. Thank you.
public class MyGdxGame extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
float x;
float y;
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
x= x+4;
if(Gdx.input.isKeyPressed(Input.Keys.P)){
// pause
}
batch.begin();
batch.draw(img, x, y);
batch.end();
}
#Override
public void dispose () {
batch.dispose();
img.dispose();
}
}
Press P key to press the game
if(Gdx.input.isKeyPressed(Input.Keys.P)){
// if(game.pause()){
game.resume();
}else{
game.pause();
}
}
any idea??? thanks
Your render method is called repeatable and what "paused" means is up to you. You have to implement your logic that handles "paused" state because that doesn't mean anything to libGDX.
If you want everything to freeze when game is paused but still to be drawn best way is (IMHO) to fully separate drawing from calculating (movements and stuff). So i.e. when your render method is called you will call your drawing method once (to draw the graphics) but you will also calculate how many times your calculation method should be call (to have same game speed independently on frame rate) and call it that many times.
Then when your game is paused you will just skip calling your calculation method and call only drawing method. So nothing will move and until you end your pause the same graphics will be drawn.
And to keep paused state you can have some boolean variable. Every time p key is pressed you should invert it, like:
if(Gdx.input.isKeyPressed(Input.Keys.P)){
paused = !paused;
}
or something (as #Tenfour04 suggested).
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 want my button to appear whenever an object reaches a certain position, that object is a sprite that is generated every second:
public void create() {
if(spritePosition>700) {
buttonObj.createButton();
}
}
public void render() {
if (condition==true) {
stage.draw();
}
}
The problem is that when the games starts no Sprite is generated yet, so the result is an error. I'm also thinking of calling the createButton() method on the render method but it would generate a new button every frame because it's called constantly.
A simple way to let your button "disappear" is to just set its position to some position outside of the visible screen area.
For example something like:
buttonObj.setPosition(-1000, -1000);
To make it visible again you can just set the real coordinates again!
How about:
public void create() {
buttonObj.createButton();
buttonObj.setVisible(false);
}
public void render() {
if (condition==true) {
buttonObj.setVisible(true);
}
}
All actors in Scene2d have the setVisible method. simply try :
yourButton.setVisible(true)
or
yourButton.setVisible(false);
I'm using AndEngine and Box2d in android application.
How can I have just one event, attached to the "Game Scene", from where I can find out what is pressed, instead of putting an event on every button in "GameHud" and how to detect the hold of the buttons?
public class GameScene extends Scene{
public GameScene(){
GameHud hud = new GameHud(this,activity);
camera.setHUD(hud);
}
//catch the touch event here
}
public class GameHud extends HUD{
public GameHud(Scene scene, GameActivity activity){
Sprite leftArrow = new Sprite(75,75,leftArrowRegion,activity.getVertexBufferObjectManager())
{
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
//...
return true;
}
};
scene.registerTouchArea(this.leftArrow);
Sprite rightArrow = new Sprite(200, 75, rightArrowRegion, activity.getVertexBufferObjectManager())
{
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
//...
return true;
}
};
scene.registerTouchArea(this.rightArrow);
}
}
You can listen for touch events in the Scene with this:
setOnSceneTouchListener(new IOnSceneTouchListener() {
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
// do something with the touch event
return true; // or false if not handled
}
});
However, doing it this way will require you to calculate which, if any, button was clicked based on the (x, y) coordinates of the touch event. If you feel that this is a better approach rather than registering events on each button you are more than welcome to do that, but you will be redoing a lot of the logic that is already embedded in the engine.
If it is the logic of the touch events that you want to share between buttons, you can have each registered event call the same method with an id or something to differentiate the buttons. That will allow you to centralize the action logic and not have to repeat it for each button being pressed.
If neither of these approaches are what you are looking for, feel free to leave a comment on what is missing and I'll do my best to help you achieve it.
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.