【发布时间】:2018-01-06 22:05:20
【问题描述】:
我一直在使用 libGDX 框架为 android/desktop 创建一个简单的游戏。快要完成了,但我很难让它适应不同的屏幕比例。我目前正在使用 FitViewport,它可以很好地保持我想要的屏幕比例,但我想让它使顶部和底部的黑条分别为天空和地面着色。我也尝试过完全不使用视口,然后使用 ShapeRenderer 添加颜色,但它只是拉伸了所有艺术以适应屏幕,不使用我想要的屏幕比例,并且忽略了 ShapeRenderer 形状。
这是我的 GameRenderer 类的构造函数代码:
public GameRenderer (GameWorld gameWorld) {
this.gameWorld = gameWorld;
camera = new OrthographicCamera();
camera.setToOrtho(false, V_WIDTH / PPM, V_HEIGHT / PPM);
uiCamera = new OrthographicCamera();
uiCamera.setToOrtho(false, V_WIDTH, V_HEIGHT);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
viewport = new FitViewport(V_WIDTH / PPM, V_HEIGHT / PPM, camera);
viewport.apply();
shapeRenderer = new ShapeRenderer();
shapeRenderer.setProjectionMatrix(camera.combined);
debugRenderer = new Box2DDebugRenderer();
frog = gameWorld.getFrog();
jumpRope = gameWorld.getJumpRope();
score = gameWorld.getScore() + "";
highScore = AssetLoader.getHighScore() + "";
}
这里是 render() 方法:
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
score = gameWorld.getScore() + "";
highScore = AssetLoader.getHighScore() + "";
batch.begin();
batch.draw(AssetLoader.background, 0, 0, 236 / PPM, 300 / PPM);
batch.setProjectionMatrix(uiCamera.combined);
if (gameWorld.isReady() || gameWorld.isTitleScreen() ) {
AssetLoader.shadow.getData().setScale(0.4f, 0.4f);
AssetLoader.shadow.draw(batch, "Tap to start!", 23, V_HEIGHT - 60);
AssetLoader.font.getData().setScale(0.4f, 0.4f);
AssetLoader.font.draw(batch, "Tap to start!", 22, V_HEIGHT - 61);
} else {
if (gameWorld.isGameOver()) {
AssetLoader.shadow.getData().setScale(0.4f, 0.4f);
AssetLoader.shadow.draw(batch, "Game Over", 40, V_HEIGHT - 60);
AssetLoader.font.getData().setScale(0.4f, 0.4f);
AssetLoader.font.draw(batch, "Game Over", 39, V_HEIGHT - 61);
AssetLoader.shadow.draw(batch, "High Score: " + highScore, 15, V_HEIGHT - 90);
AssetLoader.font.draw(batch, "High Score: " + highScore, 14, V_HEIGHT - 91);
} else {
AssetLoader.shadow.getData().setScale(0.55f, 0.55f);
AssetLoader.shadow.draw(batch, score, (V_WIDTH / 2) - (8 * score.length()), V_HEIGHT / 1.25f);
AssetLoader.font.getData().setScale(0.55f, 0.55f);
AssetLoader.font.draw(batch, score, (V_WIDTH / 2) - (8 * score.length()) - 1, V_HEIGHT / 1.25f - 1);
}
}
batch.setProjectionMatrix(camera.combined);
if (jumpRope.getJumpRopeBehindFrog()) {
jumpRope.draw(batch);
}
if (gameWorld.getFrog().getY() > -60 / PPM) {
frog.draw(batch);
}
if (!jumpRope.getJumpRopeBehindFrog()) {
jumpRope.draw(batch);
}
batch.end();
debugRenderer.render(gameWorld.getWorld(), camera.combined);
gameWorld.getWorld().step(1/60f, 6, 2);
}
顾名思义,我将主 OrthographicCamera 相机用于我的所有游戏和 Box2D 内容,并将 uiCamera 用于所有 UI。感谢您提供任何和所有帮助!
尝试添加后台后:
public GameRenderer (GameWorld gameWorld) {
this.gameWorld = gameWorld;
camera = new OrthographicCamera();
camera.setToOrtho(false, V_WIDTH / PPM, V_HEIGHT / PPM);
uiCamera = new OrthographicCamera();
uiCamera.setToOrtho(false, V_WIDTH, V_HEIGHT);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
// Test code
backViewport = new ExtendViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
backStage = new Stage();
backStage.setViewport(backViewport);
//
viewport = new FitViewport(V_WIDTH / PPM, V_HEIGHT / PPM, camera);
viewport.apply();
shapeRenderer = new ShapeRenderer();
shapeRenderer.setProjectionMatrix(camera.combined);
debugRenderer = new Box2DDebugRenderer();
frog = gameWorld.getFrog();
jumpRope = gameWorld.getJumpRope();
score = gameWorld.getScore() + "";
highScore = AssetLoader.getHighScore() + "";
// Test code
backStage.addActor(new Image(AssetLoader.backgroundColor));
}
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
score = gameWorld.getScore() + "";
highScore = AssetLoader.getHighScore() + "";
batch.begin();
batch.draw(AssetLoader.background, 0, 0, 236 / PPM, 300 / PPM);
batch.setProjectionMatrix(uiCamera.combined);
if (gameWorld.isReady() || gameWorld.isTitleScreen() ) {
AssetLoader.shadow.getData().setScale(0.4f, 0.4f);
AssetLoader.shadow.draw(batch, "Tap to start!", 23, V_HEIGHT - 60);
AssetLoader.font.getData().setScale(0.4f, 0.4f);
AssetLoader.font.draw(batch, "Tap to start!", 22, V_HEIGHT - 61);
} else {
if (gameWorld.isGameOver()) {
AssetLoader.shadow.getData().setScale(0.4f, 0.4f);
AssetLoader.shadow.draw(batch, "Game Over", 40, V_HEIGHT - 60);
AssetLoader.font.getData().setScale(0.4f, 0.4f);
AssetLoader.font.draw(batch, "Game Over", 39, V_HEIGHT - 61);
AssetLoader.shadow.draw(batch, "High Score: " + highScore, 15, V_HEIGHT - 90);
AssetLoader.font.draw(batch, "High Score: " + highScore, 14, V_HEIGHT - 91);
} else {
AssetLoader.shadow.getData().setScale(0.55f, 0.55f);
AssetLoader.shadow.draw(batch, score, (V_WIDTH / 2) - (8 * score.length()), V_HEIGHT / 1.25f);
AssetLoader.font.getData().setScale(0.55f, 0.55f);
AssetLoader.font.draw(batch, score, (V_WIDTH / 2) - (8 * score.length()) - 1, V_HEIGHT / 1.25f - 1);
}
}
batch.setProjectionMatrix(camera.combined);
if (jumpRope.getJumpRopeBehindFrog()) {
jumpRope.draw(batch);
}
if (gameWorld.getFrog().getY() > -60 / PPM) {
frog.draw(batch);
}
if (!jumpRope.getJumpRopeBehindFrog()) {
jumpRope.draw(batch);
}
batch.end();
// I put this in front of everything so that I could see what it's doing
backStage.act();
backStage.draw();
//
debugRenderer.render(gameWorld.getWorld(), camera.combined);
gameWorld.getWorld().step(1/60f, 6, 2);
}
public void resize (int width, int height) {
backViewport.update(width, height);
viewport.update(width, height);
}
【问题讨论】:
-
我相信this 可能会有所帮助。
-
不,我在后台添加了我想要的内容到后台,但它不会超过主 FitViewport,也不会缩放到适当的大小,即使我使用 Gdx.graphics 也是如此。获取宽度()/获取高度()
-
我明白了。您是否像建议的问题一样为
backStage使用单独的ExtendViewport? -
是的!绝对有可能是我搞砸了,如果您认为有帮助,我可以编辑我的帖子以显示我添加的内容。
标签: android libgdx box2d viewport scaling