Pause / Resume a Simple Libgdx Game for Android

I'm currently trying to implement a simple game using libgdx for the Android platform. I implemented the game, but I don’t know how to pause and resume the game based on user input. Initially offer an idea, as well as some practical code to implement the same. I use simple game code demonstrated in the libgdx library. Thanks.

Here is the code:

public class Drop implements ApplicationListener {
   Texture dropImage;
   Texture bucketImage;
   Sound dropSound;
   Music rainMusic;
   SpriteBatch batch;
   OrthographicCamera camera;
   Rectangle bucket;
   Array<Rectangle> raindrops;
   long lastDropTime;

   @Override
   public void create() {
      // load the images for the droplet and the bucket, 64x64 pixels each
      dropImage = new Texture(Gdx.files.internal("droplet.png"));
      bucketImage = new Texture(Gdx.files.internal("bucket.png"));

      // load the drop sound effect and the rain background "music"
      dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
      rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));

      // start the playback of the background music immediately
      rainMusic.setLooping(true);
      rainMusic.play();

      // create the camera and the SpriteBatch
      camera = new OrthographicCamera();
      camera.setToOrtho(false, 800, 480);
      batch = new SpriteBatch();

      // create a Rectangle to logically represent the bucket
      bucket = new Rectangle();
      bucket.x = 800 / 2 - 64 / 2; // center the bucket horizontally
      bucket.y = 20; // bottom left corner of the bucket is 20 pixels above the bottom screen edge
      bucket.width = 64;
      bucket.height = 64;

      // create the raindrops array and spawn the first raindrop
      raindrops = new Array<Rectangle>();
      spawnRaindrop();
   }

   private void spawnRaindrop() {
      Rectangle raindrop = new Rectangle();
      raindrop.x = MathUtils.random(0, 800-64);
      raindrop.y = 480;
      raindrop.width = 64;
      raindrop.height = 64;
      raindrops.add(raindrop);
      lastDropTime = TimeUtils.nanoTime();
   }

   @Override
   public void render() {
      // clear the screen with a dark blue color. The
      // arguments to glClearColor are the red, green
      // blue and alpha component in the range [0,1]
      // of the color to be used to clear the screen.
      Gdx.gl.glClearColor(0, 0, 0.2f, 1);
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

      // tell the camera to update its matrices.
      camera.update();

      // tell the SpriteBatch to render in the
      // coordinate system specified by the camera.
      batch.setProjectionMatrix(camera.combined);

      // begin a new batch and draw the bucket and
      // all drops
      batch.begin();
      batch.draw(bucketImage, bucket.x, bucket.y);
      for(Rectangle raindrop: raindrops) {
         batch.draw(dropImage, raindrop.x, raindrop.y);
      }
      batch.end();

      // process user input
      if(Gdx.input.isTouched()) {
         Vector3 touchPos = new Vector3();
         touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
         camera.unproject(touchPos);
         bucket.x = touchPos.x - 64 / 2;
      }
      if(Gdx.input.isKeyPressed(Keys.LEFT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime();
      if(Gdx.input.isKeyPressed(Keys.RIGHT)) bucket.x += 200 * Gdx.graphics.getDeltaTime();

      // make sure the bucket stays within the screen bounds
      if(bucket.x < 0) bucket.x = 0;
      if(bucket.x > 800 - 64) bucket.x = 800 - 64;

      // check if we need to create a new raindrop
      if(TimeUtils.nanoTime() - lastDropTime > 1000000000) spawnRaindrop();

      // move the raindrops, remove any that are beneath the bottom edge of
      // the screen or that hit the bucket. In the later case we play back
      // a sound effect as well.
      Iterator<Rectangle> iter = raindrops.iterator();
      while(iter.hasNext()) {
         Rectangle raindrop = iter.next();
         raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
         if(raindrop.y + 64 < 0) iter.remove();
         if(raindrop.overlaps(bucket)) {
            dropSound.play();
            iter.remove();
         }
      }
   }

   @Override
   public void dispose() {
      // dispose of all the native resources
      dropImage.dispose();
      bucketImage.dispose();
      dropSound.dispose();
      rainMusic.dispose();
      batch.dispose();
   }

   @Override
   public void resize(int width, int height) {
   }

   @Override
   public void pause() {
   }

   @Override
   public void resume() {
   }
}
+4
source share
5 answers

The simplest thing you add is Enum:

public enum State
{
    PAUSE,
    RUN,
    RESUME,
    STOPPED
}

And change your rendermethod

private State state = State.RUN;

@Override
public void render()
{
    switch (state)
    {
    case RUN:
//do suff here
        break;
    case PAUSE:
//do stuff here

        break;
    case RESUME:

        break;

    default:
        break;
    }
}

Use callback with Android too. For example, use callbacks from libgdx to change state:

@Override
public void pause()
{
    this.state = State.PAUSE;
}

@Override
public void resume()
{
    this.state = State.RESUME;
}

- setMethod , userevent.

public void setGameState(State s){
    this.state = s;
}
+10

. "". - :

public enum State{
    Running, Paused
}

State state = State.Running;

@Override
public void render(){
    switch(state){
        case Running:
            update();
            break;
        case Paused:
            //don't update
            break;
    }
    draw();
}

public void update(){
    //your update code
}
public void draw(){
    //your render code
}
+5

, , - , .

, ? , glClear srpites , ,

+1

: GAME_PAUSED , , . .

boolean GAME_PAUSED = false;


    if (GAME_PAUSED) {
    //Do not update camera
        batch.begin();
        resumeButton.draw(batch);
        batch.end();
    } else {
    //Update Camera
    Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    world.step(1/60f, 8, 3);
    camera.update();
    debugRenderer.render(world, camera.combined);
    //Do your game running
    }
0

Even simpler: see here https://github.com/libgdx/libgdx/wiki/Continuous-&-non-continuous-rendering

In your method of creating ApplicationListener just put

Gdx.graphics.setContinuousRendering(false);
Gdx.graphics.requestRendering(); 

Configure boolean

public boolean paused = false;

Then, for example, the button listener to pause / resume on the button, press

 buttonPause.addListener(new ChangeListener() {
            public void changed (ChangeEvent event, Actor actor) {

            // set paused true or false here

            }
        });

Then, right at the end of your rendering method, simply add:

if (!paused) {
            Gdx.graphics.requestRendering();
        }

Now the rendering method is paused / resumed.

0
source

Source: https://habr.com/ru/post/1525401/


All Articles