2014-12-19 2 views
0

Я работаю над основанной на плитке игрой с Libgdx, которая перемещает карту с помощью WASD. Я использую функции scene2d для рисования экрана, и TiledMap, который я показываю, проявляется просто отлично. Но когда я пытаюсь вызвать stage.getCamera(). Translate (float x, float y, float z); метод перемещения области просмотра с помощью метода Gdx.Input.IsKeyPressed(), viewport не переводит. Метод вызывается, потому что «KEY PRESSS» выводится на консоль, но камера не переводит. Есть ли другой способ перемещения окна просмотра? Есть ли у класса Stage другой способ перемещения камеры?Libgdx: Перевод камеры Scene2d

Вот мой источник для экрана:

package com.BurntToast.SolidDiamond; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.Screen; 
import com.badlogic.gdx.Input.Keys; 
import com.badlogic.gdx.graphics.Color; 
import com.badlogic.gdx.graphics.GL20; 
import com.badlogic.gdx.graphics.OrthographicCamera; 
import com.badlogic.gdx.graphics.g2d.TextureRegion; 
import com.badlogic.gdx.maps.tiled.TiledMap; 
import com.badlogic.gdx.maps.tiled.TmxMapLoader; 
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; 
import com.badlogic.gdx.math.Rectangle; 
import com.badlogic.gdx.math.Vector2; 
import com.badlogic.gdx.math.Vector3; 
import com.badlogic.gdx.scenes.scene2d.Stage; 
import com.badlogic.gdx.utils.Array; 
import com.badlogic.gdx.utils.Pool; 
import com.badlogic.gdx.utils.viewport.FitViewport; 


public class PlayScreen implements Screen { 



private MainFrame mainFrame; 

    private OrthographicCamera camera; 
    private Vector3 touchCoord; 
    private TiledMap currentMap; 
    private OrthogonalTiledMapRenderer otmr; 

    private ConveyorActor convActor; 

    private Stage mapStage; 


    public PlayScreen(MainFrame passedGame){ 
     mainFrame = passedGame; 

     convActor = new ConveyorActor(mainFrame.conveyorFrames, 1, 0, 0); 
     mapStage = new Stage(); 
     mapStage.addActor(convActor); 
     currentMap = new TmxMapLoader().load("maps/MenuMap2.tmx"); 
     otmr = new OrthogonalTiledMapRenderer(currentMap); 
     otmr.setView((OrthographicCamera)mapStage.getCamera()); 

    } 
    @Override 
    public void render(float delta) { 
     // TODO Auto-generated method stub 
     //ERIC (erase, redraw, input, calculate) 
     //ERASE 
     Gdx.gl.glClearColor(1, 1, 1, 1); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

     //camera.update(); 

     //REDRAW 
     otmr.render(); 
     mapStage.draw(); 


     //INPUT/CALCULATE 
     mapStage.act(); 
     if(Gdx.input.isTouched()){ 

     }//end if touched 

     //MAP TRANSLATION INPUT HERE: 
     if(Gdx.input.isKeyPressed(Keys.W)){ 
      //heres the line of code but it won't translate. 
      mapStage.getCamera().translate(0, 10, 0); 
      mapStage.getCamera().update(); 
      System.out.println("KEY PRESSS"); 
     } 
     if(Gdx.input.isKeyPressed(Keys.A)){ 
      mapStage.getCamera().translate(-10, 0, 0); 
      mapStage.getCamera().update(); 
     } 
     if(Gdx.input.isKeyPressed(Keys.S)){ 
      mapStage.getCamera().translate(0, -10, 0); 
      mapStage.getCamera().update(); 
     } 
     if(Gdx.input.isKeyPressed(Keys.D)){ 
      mapStage.getCamera().translate(10, 0, 0); 
      mapStage.getCamera().update(); 
     } 
    } 



    @Override 
    public void resize(int width, int height) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void show() { 
     // TODO Auto-generated method stub 
     mapStage = new Stage(new FitViewport(mainFrame.SCREEN_WIDTH, mainFrame.SCREEN_HEIGHT)); 
    } 

    @Override 
    public void hide() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void pause() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void resume() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void dispose() { 
     // TODO Auto-generated method stub 
     currentMap.dispose(); 
    } 

ответ

1

В конструкторе экране воспроизведения, вы создать mapStage, который будет иметь свое собственное окно просмотра и камеры. Затем вы передаете эту камеру в обработчик изображения с черепицей.

Но затем в show() вы создаете новый mapStage, который заменит ссылку, созданную в конструкторе. Поэтому, когда вы меняете камеру в render(), это камера с новой ступени, а не старая камера, которую по-прежнему использует обработчик черепичной карты.

Вы хотите, чтобы избежать использования new Stage(...) в методе show в любом случае, потому что тогда вы будете создавать на новом этапе каждый раз, когда изменения экрана, который будет тратить время на создание нового спрайта партии (который занимает много память и компилирует шейдер каждый раз). И старая сцена, которую вы заменяете каждый раз, будет протекать, потому что она не вызывает dispose(), прежде чем ее ссылка будет потеряна.

Я не уверен в ваших ограничений, но одно решение было бы пересмотреть свой метод show к этому:

public void show() { 
    mapStage.setViewport(new FitViewport(mainFrame.SCREEN_WIDTH, mainFrame.SCREEN_HEIGHT)); 
    otmr.setView((OrthographicCamera)mapStage.getCamera()); 
} 

Несколько других вещей ... Вы должны распоряжаться вашей сцене в dispose() чтобы избежать потенциальных утечек (на этапе спрайта на сцене будет протекать шейдер, когда экран изменится, если вы этого не сделаете). И ваши движения камеры должны всегда включать умножение на delta, чтобы скорость движения была независимой от частоты кадров.

+0

У меня была новая Stage() в методе show, потому что, когда у меня было это в конструкторе, экран загрузки инициализировал экран, и я подумал, что экран загрузки каким-то образом выходил на сцену, поэтому я положил его в показать метод, чтобы он этого не сделал. Но оказывается, что я ошибся, а потом забыл вытащить ту, что была в конструкторе. Это хороший момент о том, как я тоже не должен ставить метод шоу. Обычно я думаю об этом. Это то, что я получаю за то, что не перестал XP. Еще раз спасибо за ответ. –