Zaimplementowałem kilka ekranów używając libGDX, które oczywiście korzystałyby z Screen
klasy dostarczonej przez framework libGDX. Jednak implementacja dla tych ekranów działa tylko ze wstępnie zdefiniowanymi rozmiarami ekranu. Na przykład, jeśli duszek był przeznaczony dla ekranu o rozmiarze 640 x 480 (współczynnik proporcji 4: 3), nie będzie działał zgodnie z przeznaczeniem na innych rozmiarach ekranu, ponieważ sprite dopasowuje się do granic ekranu i nie są skalowane do rozmiaru ekranu w ogóle. Co więcej, gdyby libGDX zapewniało proste skalowanie, problem, z którym się zmagam, nadal istniałby, ponieważ spowodowałoby to zmianę proporcji ekranu gry.
Po poszukaniu informacji w Internecie trafiłem na blog / forum , na którym omawiano ten sam problem. Zaimplementowałem to i na razie działa dobrze. Ale chcę potwierdzić, czy jest to najlepsza opcja, aby to osiągnąć, czy też istnieją lepsze alternatywy. Poniżej znajduje się kod pokazujący, jak radzę sobie z tym uzasadnionym problemem.
LINK FORUM: 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);
}
}
}
AKTUALIZACJA: Niedawno dowiedziałem się, że libGDX ma swoją własną funkcjonalność do utrzymywania współczynników proporcji, które chciałbym tutaj omówić. Podczas wyszukiwania informacji o problemie ze współczynnikiem proporcji w Internecie natknąłem się na kilka forów / programistów, którzy mieli problem z pytaniem „Jak zachować proporcje na różnych rozmiarach ekranu?” Jedno z rozwiązań, które naprawdę mi się sprawdziło, zostało zamieszczone powyżej.
Później, kiedy przystąpiłem do implementacji touchDown()
metod dla ekranu, stwierdziłem, że ze względu na skalowanie przy touchDown()
zmianie rozmiaru współrzędne, na których zaimplementowałem , zmieniłyby się znacznie. Po przepracowaniu jakiegoś kodu w celu przetłumaczenia współrzędnych zgodnie ze zmianą rozmiaru ekranu, zmniejszyłem tę kwotę w dużym stopniu, ale nie udało mi się zachować ich z dokładnością do punktu. Na przykład, gdybym zaimplementował touchDown()
teksturę, zmiana rozmiaru ekranu spowodowałaby przesunięcie narzędzia touchListener w obszarze tekstury o kilka pikseli w prawo lub w lewo, w zależności od zmiany rozmiaru i było to oczywiście niepożądane.
Później dowiedziałem się, że klasa stage ma własną natywną funkcjonalność, aby utrzymać współczynnik kształtu ( boolean stretch = false
). Teraz, gdy zaimplementowałem mój ekran przy użyciu klasy stage, współczynnik proporcji jest przez nią dobrze utrzymywany. Jednak w przypadku zmiany rozmiaru lub innych rozmiarów ekranu, generowany czarny obszar zawsze pojawia się po prawej stronie ekranu; to znaczy ekran nie jest wyśrodkowany, co sprawia, że jest dość brzydki, jeśli czarny obszar jest znacznie duży.
Czy jakikolwiek członek społeczności może mi pomóc rozwiązać ten problem?