我在LibGDX中遇到FitViewport
问题。调整窗口大小时,一切正常。接下来我切换屏幕,一切都只是翻回到正常尺寸,图像被裁剪到左侧,同时应用程序的尺寸仍然调整大小。
但是,当我按下to first screen
按钮时,会发生这种情况:
所以一切正常(按to main screen
按钮将您带回原始屏幕),除了缩放按钮和图像的位置。
窗口的尺寸保持不变,但图像会恢复到原始尺寸(500x500)并放在坐标(0,0)处。
有关如何解决此问题的任何想法或建议?我对这个问题感到不满,似乎无法做到正确......我希望它就像第一个屏幕一样。
这些是我的类文件:我使用抽象的Screen类来跟踪屏幕(以及稍后进行扩展)和ScreenManager:
主要课程:
public class MainClass implements ApplicationListener {
@Override
public void create () {
ScreenManager.setScreen(new MainScreen());
}
@Override
public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (ScreenManager.getCurrentScreen() != null) {
ScreenManager.getCurrentScreen().render();
}
}
@Override
public void resize(int width, int height) {
if (ScreenManager.getCurrentScreen() != null)
ScreenManager.getCurrentScreen().resize(width, height);
}
}
摘要屏幕类:
public abstract class Screen {
public abstract void create();
public abstract void render();
public abstract void resize(int width, int height);
public abstract void pause();
public abstract void dispose();
public abstract void resume();
}
屏幕管理员课程:
public class ScreenManager {
private static Screen currentScreen;
public static void setScreen(Screen screen) {
if (currentScreen != null)
currentScreen.dispose();
currentScreen = screen;
currentScreen.create();
}
public static Screen getCurrentScreen() {
return currentScreen;
}
}
主屏类:
public class MainScreen extends Screen {
private Texture bg1;
private Image bg1Image;
private Skin skin;
private Stage stage;
private OrthographicCamera camera;
private FitViewport fitViewport;
@Override
public void create() {
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
fitViewport = new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), camera);
bg1 = new Texture(Gdx.files.internal("background1.png"));
bg1Image = new Image(bg1);
skin = new Skin(Gdx.files.internal("uiskin.json"));
TextButton nextButton = new TextButton("to first screen", skin);
nextButton.setPosition(200, 200);
nextButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
ScreenManager.setScreen(new FirstScreen());
super.clicked(event, x, y);
}
});
stage = new Stage(fitViewport);
stage.addActor(bg1Image);
stage.addActor(nextButton);
Gdx.input.setInputProcessor(stage);
}
@Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
fitViewport.apply();
stage.draw();
}
@Override
public void resize(int width, int height) {
fitViewport.update(width, height, true);
camera.update();
}
}
第一个屏幕类:
public class FirstScreen extends Screen {
private Texture bg2;
private Image bg2Image;
private Skin skin;
private Stage stage;
private OrthographicCamera camera;
private FitViewport fitViewport;
@Override
public void create() {
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
fitViewport = new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), camera);
bg2 = new Texture(Gdx.files.internal("background2.png"));
bg2Image = new Image(bg2);
skin = new Skin(Gdx.files.internal("uiskin.json"));
TextButton prevButton = new TextButton("to main screen", skin);
prevButton.setPosition(200, 200);
prevButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
ScreenManager.setScreen(new MainScreen());
super.clicked(event, x, y);
}
});
stage = new Stage(fitViewport);
stage.addActor(bg2Image);
stage.addActor(prevButton);
Gdx.input.setInputProcessor(stage);
}
@Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
fitViewport.apply();
stage.draw();
}
@Override
public void resize(int width, int height) {
fitViewport.update(width, height, true);
camera.update();
}
}
(我知道我提供了很多课程,但我想详细解释一切......) 我猜这可能是次要的,但我似乎无法做到这一点,这让我疯狂...... 任何帮助或建议将不胜感激!
答案 0 :(得分:0)
使用ScreenManager创建新屏幕时,您不会在新实例化的屏幕上调用resize
。它是第一次运行,因为您在ApplicationListener上调用resize
之前创建了第一个屏幕,然后在屏幕上调用resize
。
顺便说一下,你也必须在这些屏幕超出范围之前调用dispose
,否则你会泄漏内存。 dispose
屏幕'dispose
方法中的所有资产,批次等(实施Disposable的任何内容)。
答案 1 :(得分:0)
你的问题在这里:
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
fitViewport = new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), camera);
每次检查当前窗口大小并创建具有窗口大小的视口。解决方案是手动定义窗口大小并根据此值创建新的屏幕视口。
在主类中创建静态公共大小变量(当然,您可以创建它,或者不创建,但可以直接写入值 - 但由于将来的重构,这不是很好)
public static final float WIDTH = 800, HEIGHT = 600; //or any other values you need
然后只需创建您的视口和相机
camera = new OrthographicCamera(Main.WIDTH, Main.HEIGHT);
camera.setToOrtho(false, Main.WIDTH, Main.HEIGHT);
fitViewport = new FitViewport(Main.WIDTH, Main.HEIGHT, camera);
就是这样。
如果您不需要,请考虑不要创建新相机 - 也许默认的舞台相机对您来说已经足够了?想一想。