android - 无法实现正确的相机和视口(viewport)

标签 android libgdx

我正在为 android 开发我的开源 LibGDX 游戏,我正在尝试从使用像素坐标更改为世界坐标。 但是,我无法通过使用正交相机和视口(viewport)来获得预期的结果,因为显示器仍然以像素坐标呈现。

例如:我将世界相机配置为 100 x 100 单位,但显示器在任何设备上呈现 100 x 100 像素。

我曾尝试更改视口(viewport),但我怀疑问题与它有任何关系。我在使用 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 分辨率安卓设备上的截图:

Rendered 100 x 100 bottom left

期望的结果:

Previous result with pixel coodinates

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

最佳答案

这是我的核心 Libgdx 阶段代码。它为我提供了超过 7-8 个项目。我使用构造函数而不是创建或显示。这是纵向,将 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() {

}
}

关于android - 无法实现正确的相机和视口(viewport),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54059774/

相关文章:

ios - 使用RoboVM进行应用内购买的解决方案是什么

libgdx - 在 libgdx 中高效使用多个纹理

android - 如何获取 SoftInputMode 的值

java - 简单数学运算符上的奇怪 java 错误

android - 应用程序中的生物识别身份验证和 oauth2

java - 停止或中断 libGDX Scene2D 中的 Action

algorithm - 我需要帮助实现一种算法,该算法将从 libGDX 中的纹理解析特定纹理

fonts - 使用着色器勾勒字体轮廓并使用距离场

java - android java权限拒绝manifest.xml

android - 在 Phonegap 应用程序的 iOS/Android 设备中,按钮 css 的变化非常缓慢