我正在使用libgdx
开发游戏,并且我在不同设备上遇到长宽比问题
经过深思熟虑,我认为以下是问题的最佳解决方案:
我希望相机始终固定为16:9
宽高比,并使用相机绘制所有内容
如果设备方面是例如4:3
我想只显示视图的一部分,而不是拉伸它。
它应该看起来像这样
blue
是虚拟屏幕(摄像机视口),red
是设备屏幕(可见区域为4:3设备)
例如,如果设备屏幕也是16:9
,则应该可以看到完整视图。
问题是我不知道如何实现这一目标。
答案 0 :(得分:1)
我为肖像画面做了这个,在顶部和底部留下了一些空白。正如您在下图中所看到的那样,游戏保持4:3的比例,并留下任何剩余的空白。
内容始终居中,并通过不均匀拉伸内容来保持其宽高比。所以这里是我用来实现它的一些示例代码。
public static final float worldW = 3;
public static final float worldH = 4;
public static OrthographicCamera camera;
...
//CALCULATING THE SCREENSIZE
float tempCalc = Gdx.graphics.getHeight() * GdxGame.worldW / Gdx.graphics.getWidth();
if(tempCalc < GdxGame.worldH){
//Adjust width
camera.viewportHeight = GdxGame.worldH;
camera.viewportWidth = Gdx.graphics.getWidth() * GdxGame.worldH / Gdx.graphics.getHeight();
worldWDiff = camera.viewportWidth - GdxGame.worldW;
}else{
//Adjust Height
camera.viewportHeight = tempCalc;
camera.viewportWidth = GdxGame.worldW;
worldHDiff = camera.viewportHeight - GdxGame.worldH;
}
camera.position.set(camera.viewportWidth/2f - worldWDiff/2f, camera.viewportHeight/2f - worldHDiff/2f, 0f);
camera.zoom = 1f;
camera.update();
我确信我不会提出完美的解决方案,但您可以使用有关如何计算相机位置和视口的值,以便您可以实现所需的效果。我想,总比没有好。
此外,冲突奥林匹克开发者谈论如何实现类似的东西,并仍然使它在不同的设备上看起来很好(这真的很有趣,但没有代码):Our solution to handle multiple screen sizes in Android - Part one
答案 1 :(得分:1)
较新版本的libGDX为glViewport提供了一个名为Viewport的包装器。
Camera camera = new OrthographicCamera();
//the viewport object will handle camera's attributes
//the aspect provided (worldWidth/worldHeight) will be kept
Viewport viewport = new FitViewport(worldWidth, worldHeight, camera);
//your resize method:
public void resize(int width, int height)
{
//notice that the method receives the entire screen size
//the last argument tells the viewport to center the camera in the screen
viewport.update(width, height, true);
}
答案 2 :(得分:0)
我编写了一个适用于不同大小的屏幕和图像的功能。如果可能,图像可能会被缩放和翻译。
public void transformAndDrawImage(SpriteBatch spriteBatch, Texture background, float scl, float offsetX, float offseY){
float width;
float height;
float _offsetX;
float _offsetY;
float bh2sh = 1f*background.getHeight()/Gdx.graphics.getHeight();
float bw2sw = 1f*background.getWidth()/Gdx.graphics.getWidth();
float aspectRatio = 1f*background.getHeight()/background.getWidth();
if(bh2sh>bw2sw){
width = background.getWidth() / bw2sw * scl;
height = width * aspectRatio;
}
else{
height = background.getHeight() / bh2sh * scl;
width = height / aspectRatio;
}
_offsetX = (-width+Gdx.graphics.getWidth())/2;
_offsetX += offsetX;
if(_offsetX-Gdx.graphics.getWidth()<=-width) _offsetX=-width+Gdx.graphics.getWidth();
if(_offsetX>0) _offsetX=0;
_offsetY = (-height+Gdx.graphics.getHeight())/2;
_offsetY += offseY;
if(_offsetY-Gdx.graphics.getHeight()<=-height) _offsetY=-height+Gdx.graphics.getHeight();
if(_offsetY>0) _offsetY=0;
spriteBatch.draw(background, _offsetX, _offsetY, width, height);
}
如何使用它?这很简单:
@Override
public void render(float delta) {
Gdx.graphics.getGL10().glClearColor( 0.1f, 0.1f, 0.1f, 1 );
Gdx.graphics.getGL10().glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT );
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
//zoom the image by 20%
float zoom = 1.2f; //Must be not less than 1.0
//translating the image depends on a few parameters such as zooming, aspect ratio of screen and image
offsetX+=0.1f; //offset the image to the left, if it's possible
offsetY+=0.1f; //offset the image to the bottom, if it's possible
transformAndDrawImage(spriteBatch, background, zoom, offsetX, offsetY);
//draw something else...
spriteBatch.end();
}