【问题标题】:Pause/Resume a Simple Libgdx Game for android暂停/恢复一个简单的 Libgdx 安卓游戏
【发布时间】:2014-02-05 11:37:28
【问题描述】:

目前我正在尝试使用 libgdx for Android Platform 实现简单的游戏。我已经实现了游戏,但不知道如何根据用户输入暂停和恢复游戏。请提出想法以及一些实用代码来实现相同。我正在使用 libgdx 库中演示的简单游戏代码。谢谢。

代码如下:

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() {
   }
}

【问题讨论】:

    标签: android libgdx


    【解决方案1】:

    更简单,看这里:https://github.com/libgdx/libgdx/wiki/Continuous-&-non-continuous-rendering

    在你的ApplicationListener的create方法中,放

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

    设置一个布尔值

    public boolean paused = false;
    

    然后例如一个按钮监听器在按钮按下时暂停/恢复

     buttonPause.addListener(new ChangeListener() {
                public void changed (ChangeEvent event, Actor actor) {
    
                // set paused true or false here
    
                }
            });
    

    然后在你的渲染方法的最后,添加:

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

    渲染方法现在暂停/恢复。

    【讨论】:

      【解决方案2】:

      最简单的是,你添加一个枚举:

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

      并修改你的渲染方法

      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;
          }
      }
      

      也使用来自 android 的回调。例如使用来自 libgdx 的回调来改变状态:

      @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;
      }
      

      【讨论】:

      • 看来你比我早了几秒钟,直到今天才注意到:p
      • thanx @BennX:我可以暂停,但移动的纹理仍在闪烁。没有完全停止或暂停。有什么建议吗??
      • Bucket 和 Raindrop 还在闪烁。
      • @BennX 在 RESUME 切换状态下怎么办?
      • 你可以做一些事情,比如改变上面显示的状态或者重新加载等等。想想它什么时候被调用以及在那里做什么。可以从谷歌查看活动内容。 developer.android.com/reference/android/app/Activity.html
      【解决方案3】:

      您可以使用带有枚举常量的状态。并且仅在运行状态下更新。像这样的:

      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
      }
      

      【讨论】:

      • thanx @ Lestat :我可以暂停,但移动纹理仍在闪烁。没有完全停止或暂停。有什么建议吗??
      • Bucket 和 Raindrop 还在闪烁。
      【解决方案4】:

      我尝试使用这种方法: 我将 GAME_PAUSED 设为布尔值,如果为真,请不要更新您的屏幕或摄像头。否则更新 Camera 。

      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
          }
      

      【讨论】:

        【解决方案5】:

        我没有rep回复cmets,但是项目闪烁是我之前遇到过的。

        当渲染暂停时,您不再清除屏幕并在渲染中重绘精灵,对吧?如果我没有弄错,如果你 glClear 并在每次渲染中重绘 srpites 我认为它会停止

        【讨论】:

        • 感谢回复,能否提供一些代码解释清楚?
        • 帮助提问的人可能有点晚了。您需要停止使它们改变位置的代码,但您需要继续绘制它们。在您的原始渲染循环中,您只需在结束精灵批处理后在所有内容周围放置一个 if(!Pause)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-16
        • 1970-01-01
        • 2018-12-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多