2014-02-05 4 views
4

В настоящее время я пытаюсь реализовать простую игру, используя libgdx для платформы Android. Я реализовал игру, но не знаю, как сделать паузу и возобновить игру на основе пользовательского ввода. Изначально предлагайте идею, а также некоторый практический код для реализации того же. Я использую простой игровой код, продемонстрированный в библиотеке libgdx. Спасибо.Пауза/Резюме простой игры Libgdx для android

Вот код:

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

ответ

10

Самая простая вещь, что вы добавляете Enum:

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

И изменить ваш 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; 
    } 
} 

Используйте обратный вызов от андроид тоже. Например использовать обратные вызовы из 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; 
} 
+0

Кажется, вы опоздали на несколько секунд, не заметили до сегодняшнего дня: p – Lestat

+0

Да, я сожалею: D – BennX

+0

thanx @BennX: Я могу приостановить, но движущиеся текстуры все еще мигают. Не останавливайтесь и не останавливаетесь полностью. Все предложения? –

5

Вы можете использовать состояние, с перечислениями или константами. и обновляется только в состоянии «Запуск». Что-то вроде этого:

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 
} 
+0

thanx @ Lestat: Я могу приостановить, но движущиеся текстуры все еще мигают. Не останавливайтесь и не останавливаетесь полностью. Все предложения? –

+0

Ведро и капля дождя все еще мерцают. –

1

У меня нет ответа, чтобы ответить на комментарии, но мерцание предметов - это то, с чем я столкнулся раньше.

Вы уже не очищаете экран и не перерисовываете спрайты в рендеринге, когда его приостановили право? Если я не ошибаюсь, если вы glClear и перерисовываете srpites в каждом рендере, я думаю, что он остановится

+0

Спасибо за rplying. Не могли бы вы предоставить какой-то код, чтобы четко объяснить? –

+0

Возможно, немного поздно, чтобы помочь человеку, который спросил. Вам необходимо остановить код, который заставляет их менять позицию, но вам нужно продолжать рисовать их. В вашем исходном цикле рендеринга вы просто положили if (! Pause) вокруг всего после того, как закончите рассылку спрайтов – witnessmenow

0

Я попытался использовать этот подход: Я сделал 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

Еще более простой, смотрите здесь: https://github.com/libgdx/libgdx/wiki/Continuous-&-non-continuous-rendering

В вашем методе ApplicationListener создают, просто поставить

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

рендер метод в настоящее время приостановлена ​​/ возобновлена.

Смежные вопросы