Screen
libGDXフレームワークによって提供されるクラスを明らかに使用するlibGDXを使用していくつかの画面を実装しました。ただし、これらの画面の実装は、事前定義された画面サイズでのみ機能します。たとえば、スプライトが640 x 480サイズの画面(アスペクト比4:3)を対象としている場合、スプライトは画面の境界を超えて画面サイズに合わせて調整されないため、他の画面サイズでは意図したとおりに機能しません。まったく。さらに、libGDXによって単純なスケーリングが提供された場合、ゲーム画面のアスペクト比が変化するため、私が直面している問題は依然として存在していました。
インターネットで調べた後、同じ問題について話し合っているブログ/フォーラムに出くわしました。私はそれを実装しました、そして今のところそれはうまく働いています。しかし、これがこれを達成するための最良の選択肢であるかどうか、またはより良い代替案があるかどうかを確認したいと思います。以下は、私がこの正当な問題にどのように対処しているかを示すコードです。
フォーラムリンク:http://www.java-gaming.org/index.php ? topic = 25685.new
public class SplashScreen implements Screen {
// Aspect Ratio maintenance
private static final int VIRTUAL_WIDTH = 640;
private static final int VIRTUAL_HEIGHT = 480;
private static final float ASPECT_RATIO = (float) VIRTUAL_WIDTH / (float) VIRTUAL_HEIGHT;
private Camera camera;
private Rectangle viewport;
// ------end------
MainGame TempMainGame;
public Texture splashScreen;
public TextureRegion splashScreenRegion;
public SpriteBatch splashScreenSprite;
public SplashScreen(MainGame maingame) {
TempMainGame = maingame;
}
@Override
public void dispose() {
splashScreenSprite.dispose();
splashScreen.dispose();
}
@Override
public void render(float arg0) {
//----Aspect Ratio maintenance
// update camera
camera.update();
camera.apply(Gdx.gl10);
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
// clear previous frame
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// DRAW EVERYTHING
//--maintenance end--
splashScreenSprite.begin();
splashScreenSprite.disableBlending();
splashScreenSprite.draw(splashScreenRegion, 0, 0);
splashScreenSprite.end();
}
@Override
public void resize(int width, int height) {
//--Aspect Ratio Maintenance--
// calculate new viewport
float aspectRatio = (float)width/(float)height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > ASPECT_RATIO) {
scale = (float) height / (float) VIRTUAL_HEIGHT;
crop.x = (width - VIRTUAL_WIDTH * scale) / 2f;
} else if(aspectRatio < ASPECT_RATIO) {
scale = (float) width / (float) VIRTUAL_WIDTH;
crop.y = (height - VIRTUAL_HEIGHT * scale) / 2f;
} else {
scale = (float) width / (float) VIRTUAL_WIDTH;
}
float w = (float) VIRTUAL_WIDTH * scale;
float h = (float) VIRTUAL_HEIGHT * scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
//Maintenance ends here--
}
@Override
public void show() {
camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); //Aspect Ratio Maintenance
splashScreen = new Texture(Gdx.files.internal("images/splashScreen.png"));
splashScreenRegion = new TextureRegion(splashScreen, 0, 0, 640, 480);
splashScreenSprite = new SpriteBatch();
if(Assets.load()) {
this.dispose();
TempMainGame.setScreen(TempMainGame.mainmenu);
}
}
}
更新:最近、libGDXには、ここで説明したいアスペクト比を維持するための独自の機能がいくつかあることがわかりました。インターネットでアスペクト比の問題を検索しているときに、「さまざまな画面サイズでアスペクト比を維持する方法」という問題を抱えているフォーラムや開発者に出くわしました。私にとって本当にうまくいった解決策の1つは上に投稿されました。
後でtouchDown()
画面のメソッドの実装を進めたときに、サイズ変更のスケーリングのために、実装した座標touchDown()
が大幅に変更されることがわかりました。画面のサイズ変更に応じて座標を変換するコードを使用した後、この量を大幅に減らしましたが、ピンポイントの精度で座標を維持することに成功しませんでした。たとえばtouchDown()
、テクスチャに実装した場合、画面のサイズを変更すると、サイズ変更に応じて、テクスチャ領域のtouchListenerが数ピクセル右または左にシフトしますが、これは明らかに望ましくありません。
後で、ステージクラスにはアスペクト比を維持するための独自のネイティブ機能があることがわかりました(boolean stretch = false
)。ステージクラスを使用して画面を実装したので、アスペクト比はそれによって適切に維持されます。ただし、サイズ変更や異なる画面サイズでは、生成される黒い領域は常に画面の右側に表示されます。つまり、画面が中央に配置されていないため、黒い領域がかなり大きい場合は非常に見苦しくなります。
コミュニティのメンバーがこの問題を解決するのを手伝ってくれますか?