LibGDX/Box2D游戏屏幕缩放适配求助:自定义黑栏颜色
方案一:用ShapeRenderer绘制纯色背景(最简单直接)
这个方法不需要额外的Stage,只用ShapeRenderer就能快速实现,适合纯颜色的天空和地面。
步骤1:添加屏幕专用相机
在GameRenderer里新增一个OrthographicCamera,用来适配整个屏幕的像素坐标:
private OrthographicCamera screenCamera; // 在构造函数中初始化 public GameRenderer (GameWorld gameWorld) { // ... 你的原有代码 ... screenCamera = new OrthographicCamera(); screenCamera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); // ... 你的原有代码 ... }
步骤2:在render方法最开始绘制背景
修改你的render()方法,先绘制全屏背景,再渲染游戏内容:
public void render () { // 先跳过glClear,因为我们要覆盖整个屏幕 // Gdx.gl.glClearColor(0, 0, 0, 1); // Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // 第一步:绘制天空和地面背景 shapeRenderer.setProjectionMatrix(screenCamera.combined); shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); // 计算FitViewport在屏幕上的实际显示区域 float gameViewportWidth = viewport.getScreenWidth(); float gameViewportHeight = viewport.getScreenHeight(); float gameViewportX = viewport.getScreenX(); float gameViewportY = viewport.getScreenY(); // 绘制天空(顶部黑栏区域) shapeRenderer.setColor(0.3f, 0.6f, 1.0f, 1); // 浅蓝色,可自行调整RGB值 shapeRenderer.rect(0, gameViewportY + gameViewportHeight, Gdx.graphics.getWidth(), Gdx.graphics.getHeight() - (gameViewportY + gameViewportHeight)); // 绘制地面(底部黑栏区域) shapeRenderer.setColor(0.2f, 0.8f, 0.2f, 1); // 绿色,可自行调整RGB值 shapeRenderer.rect(0, 0, Gdx.graphics.getWidth(), gameViewportY); shapeRenderer.end(); // 第二步:渲染你的游戏内容(原有代码不变) score = gameWorld.getScore() + ""; highScore = AssetLoader.getHighScore() + ""; batch.begin(); // ... 你的原有batch绘制代码 ... batch.end(); // ... 你的原有debug和world.step代码 ... }
步骤3:更新resize方法
在resize()方法中同步更新屏幕相机的尺寸:
public void resize (int width, int height) { viewport.update(width, height); screenCamera.setToOrtho(false, width, height); // 更新屏幕相机 }
方案二:用Stage实现背景层(更灵活,适合扩展)
如果以后想在天空加云朵、地面加草地这类元素,用Stage来管理背景会更方便。
步骤1:重构背景Stage的初始化
替换你之前的backStage相关代码,用全屏的OrthographicViewport:
private Stage backStage; private OrthographicViewport backViewport; private Image skyImage; private Image groundImage; public GameRenderer (GameWorld gameWorld) { // ... 你的原有代码 ... // 初始化全屏背景Stage backViewport = new OrthographicViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); backStage = new Stage(backViewport); // 创建天空背景(全屏) skyImage = new Image(); skyImage.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); skyImage.setColor(0.3f, 0.6f, 1.0f, 1); // 天空色 backStage.addActor(skyImage); // 创建地面背景(初始尺寸) groundImage = new Image(); float initialGroundHeight = (Gdx.graphics.getHeight() - viewport.getScreenHeight()) / 2; groundImage.setSize(Gdx.graphics.getWidth(), initialGroundHeight); groundImage.setPosition(0, 0); groundImage.setColor(0.2f, 0.8f, 0.2f, 1); // 地面色 backStage.addActor(groundImage); // ... 你的原有代码 ... }
步骤2:调整render顺序
把backStage的绘制放在最开始,确保背景在游戏内容下方:
public void render () { // 先绘制背景Stage backStage.act(Gdx.graphics.getDeltaTime()); backStage.draw(); // 再渲染游戏内容(原有代码不变) score = gameWorld.getScore() + ""; highScore = AssetLoader.getHighScore() + ""; batch.begin(); // ... 你的原有batch绘制代码 ... batch.end(); // ... 你的原有debug和world.step代码 ... }
步骤3:更新resize方法
在窗口/屏幕尺寸变化时,同步更新背景元素的大小:
public void resize (int width, int height) { viewport.update(width, height); backViewport.update(width, height); // 更新天空尺寸 skyImage.setSize(width, height); // 更新地面尺寸(底部黑栏的高度) float groundHeight = (height - viewport.getScreenHeight()) / 2; groundImage.setSize(width, groundHeight); groundImage.setPosition(0, 0); }
注意事项
- 记得把原来的
Gdx.gl.glClearColor和Gdx.gl.glClear注释掉,因为背景层已经覆盖了整个屏幕,不需要再清成黑色。 - 两种方案都能完美保留
FitViewport的游戏比例,不会让美术资源拉伸。 - 颜色值可以根据你的游戏风格自行调整,RGB范围是0-1之间的浮点数。
内容的提问来源于stack exchange,提问作者Dayne Kramer
相关产品推荐
相关产品推荐

