无法实现正确的相机和视口

时间:2019-01-06 08:15:46

标签: android libgdx

我正在开发用于Android的开源LibGDX游戏,并且尝试将像素坐标转换为世界坐标。 但是,由于显示仍以像素坐标显示,因此我无法通过使用正交摄影机和视口来获得所需的结果。

例如:我将世界的摄像头配置为100 x 100单位,但显示屏在任何设备上渲染100 x 100像素。

我曾尝试过更改视口,但我怀疑该问题与它有关。我在使用Gdx.graphics.getHeight [/ getWidth]

的任何地方也都使用过cam.viewport.height [/ width]

这是我的游戏状态类:

public class PlayState extends State {
private Stork stork;
private CollectibleOrbs orbs;
Array<Texture> textures = new Array<Texture>();
private ShapeRenderer shapeRenderer;
private BitmapFont font;
private Texture lifeTex;
private int score = 0;
private int lives = 5;

public PlayState(GameStateManager gsm, OrthographicCamera cam, Viewport viewport,Stage  stage) {
    super(gsm,cam,viewport,stage);

    Gdx.app.debug("Display",Gdx.graphics.getWidth() + " : " + Gdx.graphics.getHeight());
    Gdx.app.debug("CamViewport",cam.viewportWidth + " : " + cam.viewportHeight);

    stork = new Stork(0, 50);
    lifeTex = new Texture(Gdx.files.internal("lifes.png"));
    orbs = new CollectibleOrbs(cam);
    font = new BitmapFont(Gdx.files.internal("fonts/abel.fnt"),Gdx.files.internal("fonts/abel.png"),false);
    textures.add(new Texture("n0.png"));
    textures.get(textures.size - 1).setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.ClampToEdge);

    for(int i = 1; i <=4;i++) {
        textures.add(new Texture(i + ".png"));
        textures.get(textures.size - 1).setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
    }

    ParallaxBackground parallaxBackground = new ParallaxBackground(textures,cam);
    parallaxBackground.setSize(cam.viewportWidth,cam.viewportHeight);
    parallaxBackground.setSpeed(1);
    stage.addActor(parallaxBackground);
}

@Override
protected void handleInput() {
    if(Gdx.input.isTouched()){
        stork.fly();
        }
}

@Override
public void update(float dt) {
    cam.update();
    handleInput();
    stork.update(dt);
    orbs.update(dt);
    CollisionCheckMain();
}

@Override
public void render(SpriteBatch sb) {

    Gdx.app.debug("Stork", stork.getBoundingRectangle() + "");
    sb.setProjectionMatrix(cam.combined);

    stage.draw();

    sb.begin();
    sb.draw(stork.getTextureRegion(),stork.getPosition().x,stork.getPosition().y);
    orbs.render(sb);
    sb.end();

    sb.begin();
    font.draw(sb,"Score : "+ getScore(), 84 , 90 );
    sb.end();

    sb.begin();
    for(int i =1; i <= lives; i++){
        sb.draw(lifeTex, lifeTex.getWidth()*i - lifeTex.getWidth() + 20 , 100 - lifeTex.getHeight() - Gdx.graphics.getHeight()/10,lifeTex.getWidth(),lifeTex.getHeight());

    }
    sb.end();
    }

@Override
public void dispose() {
    stage.dispose();
    orbs.dispose();
    font.dispose();
}



public void CollisionCheckMain(){
    int temp;
    temp = orbs.checkCollision(stork.getBoundingRectangle());
    if(temp==1){
        score +=temp;
        if (score%20==0){
            lives+=1;
        }
    }
    else
        if(temp == -1){
            lives -=1;
    }
    checkKillCondition();
}

public void checkKillCondition(){
    if (lives == 0){
        //Killed, Restart
        gsm.set(new MenuState(gsm, cam, viewport,stage));
        dispose();
    }
}

public int getScore(){
    return score;
}
}

这是我的游戏课:

public class StorkLightGameClass extends ApplicationAdapter {
    public static final int HEIGHT = 100;
    public static final int WIDTH = 100;
    public static final float SPEED = 0.1f;

    public static final String TITLE="Stork Light";
    private GameStateManager gsm;
    private SpriteBatch batch;
    OrthographicCamera cam;
    Viewport viewport;
    Stage stage;

    @Override
    public void create () {
        Gdx.app.setLogLevel(Application.LOG_DEBUG);
        batch = new SpriteBatch();
        stage = new Stage();

        float aspectRatio = (float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth();

        cam = new OrthographicCamera();
        viewport = new StretchViewport(100 * aspectRatio,100,cam);
        viewport.apply();

      cam.position.set(cam.viewportWidth/2,cam.viewportHeight/2,0);

        batch.getProjectionMatrix().setToOrtho2D(0, 0, cam.viewportWidth,cam.viewportHeight);

        gsm = new GameStateManager();
        gsm.push(new MenuState(gsm,cam, viewport,stage));
}


    @Override
    public void render () {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        gsm.update(Gdx.graphics.getDeltaTime());
        gsm.render(batch);

    }

    @Override
    public void dispose () {
        batch.dispose();
    }

    @Override
    public void resize(int width, int height){
        Gdx.app.debug("GameClass", "resize called " + width + ":" + height);
        viewport.update(width,height);
        cam.position.set(cam.viewportWidth/2,cam.viewportHeight/2,0);
        batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
        stage.getViewport().update(width, height);
        stage.getCamera().viewportWidth = WIDTH;
        stage.getCamera().viewportHeight = HEIGHT * height / width;
     stage.getCamera().position.set(stage.getCamera().viewportWidth/2, stage.getCamera().viewportHeight/2, 0);
        stage.getCamera().update();

    }
}

以下是1920 x 1080分辨率android设备上的屏幕截图:

Rendered 100 x 100 bottom left

所需结果:

Previous result with pixel coodinates

其余代码可在此处找到:https://github.com/sanjeev309/storklight/tree/world_units

1 个答案:

答案 0 :(得分:0)

这是我的核心Libgdx阶段代码。它为我提供了超过7-8个项目。我使用了构造函数而不是create或show。这是纵向,将h和w切换为横向。

public class MenuScreenClass implements Screen {

private OrthographicCamera camera;
public static final float WORLD_HEIGHT = 240;
public static final float WORLD_WIDTH = 135;
private Viewport viewport;
private Stage stage;  

public MenuScreenClass(){

    float aspectRatio = (float) (Gdx.graphics.getHeight() / Gdx.graphics.getWidth());
    camera = new OrthographicCamera(aspectRatio * WORLD_WIDTH, WORLD_HEIGHT);
    camera.setToOrtho(false);
    viewport = new FitViewport(WORLD_WIDTH , WORLD_HEIGHT,camera );
    stage = new Stage(viewport, game.batch);      

    Gdx.input.setInputProcessor(stage);

}

@Override
public void show() {

}

@Override
public void render(float delta) {

    stage.draw();

    game.batch.begin();

    game.batch.end();

}  

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

}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {

}
}