Я реалізував деякі екрани, використовуючи libGDX, які, очевидно, використовуватимуть Screen
клас, передбачений фреймворком 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 має власну функціональність для підтримки пропорцій, яку я хотів би тут обговорити. Шукаючи проблему пропорцій в Інтернеті, я натрапив на кілька форумів / розробників, у яких виникала така проблема: "Як підтримувати пропорції на різних розмірах екрана?" Одне з рішень, яке справді працювало для мене, було опубліковане вище.
Пізніше, коли я приступив до впровадження touchDown()
методів для екрану, я виявив, що внаслідок масштабування при touchDown()
зміні розміру координати, на яких я впровадив, значно зміниться. Попрацювавши з деяким кодом для перекладу координат відповідно до зміни розміру екрана, я значною мірою зменшив цю кількість, але мені не вдалося зберегти їх з точністю до точки. Наприклад, якби я реалізував touchDown()
текстуру, зміна розміру екрана змістила б сенсорний прослуховувач на області текстури на кілька пікселів вправо або вліво, залежно від зміни розміру, і це було явно небажано.
Пізніше я дізнався, що клас сцени має власну функціональність для підтримки пропорції ( boolean stretch = false
). Тепер, коли я реалізував свій екран за допомогою сценичного класу, пропорції він добре підтримується. Однак при зміні розміру або різних розмірах екрана чорна область, яка генерується, завжди відображається з правого боку екрана; тобто екран не відцентрований, що робить його досить потворним, якщо чорна область істотно велика.
Чи може хтось із членів спільноти допомогти мені вирішити цю проблему?