Android 按下后退按钮后打开应用程序时,Libgdx纹理都很奇怪?
这就是我的困境,我真的快要在游戏商店上发布我的游戏了 在设备上测试应用程序时,我意识到当单击home按钮时,然后再次打开应用程序。一切都处理得很好 然而,当按下后退按钮并再次打开应用程序时,我游戏中的纹理会变得很奇怪,就像真的很奇怪一样 下面是屏幕截图,显示了应该是什么样子,不应该是什么样子 这是一个链接,显示了应该是什么样子 这是一个在按下后退按钮后加载的 经过一段时间的测试,我认为问题在于当点击后退按钮时,它会触发一个“退出”类型的函数,该函数应该退出应用程序。然而,由于某些原因,该应用程序仍然存在于手机的背景中,这导致在单击“后退”按钮后加载奇怪的纹理。如果我是正确的,我需要做什么来处理这种行为Android 按下后退按钮后打开应用程序时,Libgdx纹理都很奇怪?,android,libgdx,scene2d,Android,Libgdx,Scene2d,这就是我的困境,我真的快要在游戏商店上发布我的游戏了 在设备上测试应用程序时,我意识到当单击home按钮时,然后再次打开应用程序。一切都处理得很好 然而,当按下后退按钮并再次打开应用程序时,我游戏中的纹理会变得很奇怪,就像真的很奇怪一样 下面是屏幕截图,显示了应该是什么样子,不应该是什么样子 这是一个链接,显示了应该是什么样子 这是一个在按下后退按钮后加载的 经过一段时间的测试,我认为问题在于当点击后退按钮时,它会触发一个“退出”类型的函数,该函数应该退出应用程序。然而,由于某些原因,该应用程
public class MainMenuScreen implements Screen{
private static final int FLOOR_Y_OFFSET = -150;
private static final int FOREGROUND_Y_OFFSET = -150;
private FishyDash game;
private OrthographicCamera cam;
private Texture background;
private Texture foreground;
private Vector2 foregroundPos1, foregroundPos2;
private Texture floor;
private Vector2 floorPos1, floorPos2;
private Fish fishy;
//TABLE STUFF
private Table table;
private Table buttonTable;
private Stage stage;
private Image game_title;
private Skin skin;
private TextureAtlas buttonAtlas;
private TextButton buttonPlay, buttonRate;
private Viewport gamePort;
public BitmapFont font;
//Load all the sounds needed
public Sound jumpSound;
public Sound buttonClicked;
public Music backgroundMusic;
GameState gameState;
//On Pause stuff
public static Vector2 fish_pause_pos;
public MainMenuScreen(FishyDash game) {
this.game = game;
gameState = GameState.READY;
System.out.println("first");
}
@Override
public void show() {
System.out.println("second");
//Initialize all the sounds
jumpSound = Assets.manager.get(Assets.jumpSound, Sound.class);
buttonClicked = Assets.manager.get(Assets.buttonClicked, Sound.class);
backgroundMusic = Assets.manager.get(Assets.backgroundMusic, Music.class);
backgroundMusic.setLooping(true);
backgroundMusic.setVolume(.5f);
backgroundMusic.play();
//Initialize the textures needed in the MainMenuScreen class
background = Assets.manager.get(Assets.background, Texture.class);
floor = Assets.manager.get(Assets.floor, Texture.class);
foreground = Assets.manager.get(Assets.foreground, Texture.class);
fishy = new Fish();
fishy.setPos(80, foreground.getHeight() + FOREGROUND_Y_OFFSET - 150);
fishy.setMOVEMENT_X(200);
fishy.setGRAVITY(-40);
cam = new OrthographicCamera();
cam.setToOrtho(false, background.getWidth(), background.getHeight());
foregroundPos1 = new Vector2(cam.position.x - (cam.viewportWidth / 2), 0);
foregroundPos2 = new Vector2(cam.position.x - (cam.viewportWidth / 2) + foreground.getWidth(), 0);
floorPos1 = new Vector2(cam.position.x - (cam.viewportWidth / 2), 0);
floorPos2 = new Vector2(cam.position.x - (cam.viewportWidth / 2) + floor.getWidth(), 0);
createTable();
// Gdx.input.setCatchBackKey(true);
// game.getAdsController().showBannerAd();
}
public void createTable() {
gamePort = new StretchViewport(FishyDash.V_WIDTH, FishyDash.V_HEIGHT, cam);
stage = new Stage(gamePort, game.batch);
stage.getViewport().setCamera(cam);
table = new Table();
table.setFillParent(true);
table.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
buttonTable = new Table();
buttonTable.setFillParent(true);
buttonTable.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
game_title = new Image(new Texture("game_title.png"));
font = Assets.manager.get(Assets.font, BitmapFont.class);
buttonAtlas = Assets.manager.get(Assets.buttonAtlas, TextureAtlas.class);
skin = new Skin(buttonAtlas);
//Creating the TextStyle for the playButton
TextButton.TextButtonStyle playButtonStyle = new TextButton.TextButtonStyle();
playButtonStyle.up = skin.getDrawable("button_up");
playButtonStyle.down = skin.getDrawable("button_down");
playButtonStyle.pressedOffsetX = 1;
playButtonStyle.pressedOffsetY = -1;
playButtonStyle.font = font;
//Creating the TextStyle for the rateButton
TextButton.TextButtonStyle rateButtonStyle = new TextButton.TextButtonStyle();
rateButtonStyle.up = skin.getDrawable("button_up");
rateButtonStyle.down = skin.getDrawable("button_down");
rateButtonStyle.pressedOffsetX = 1;
rateButtonStyle.pressedOffsetY = -1;
rateButtonStyle.font = font;
//Setting the style and text for the playButton
buttonPlay = new TextButton("PlAY", playButtonStyle);
buttonPlay.pad(10);
//Setting the style and text for the rateButton
buttonRate = new TextButton("RATE", rateButtonStyle);
buttonRate.pad(10);
table.top();
table.add(game_title).padTop(175).expandX();
buttonTable.bottom().padBottom(200);
buttonTable.add(buttonPlay).expandX().padLeft(30);
buttonTable.add(buttonRate).expandX().padRight(30);
// table.debug();
stage.addActor(table);
stage.addActor(buttonTable);
buttonPlay.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
buttonClicked.play();
dispose();
game.setScreen(new GameScreen(game));
}
});
buttonRate.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
buttonClicked.play();
System.out.println("Nothing happens Yet");
}
});
}
public void updateWorld(float delta) {
switch (gameState) {
case READY:
fishy.update(delta);
if (fishy.getPosition().y < foreground.getHeight() + FOREGROUND_Y_OFFSET - 35) {
fishy.setMOVEMENT_X(100);
}
if (fishy.getPosition().y < floor.getHeight() + FLOOR_Y_OFFSET + 150) {
fishy.setMOVEMENT_X(100);
fishy.normalJump();
jumpSound.stop();
}
updateForeground();
updateFloor();
cam.position.x = fishy.getPosition().x + (cam.viewportWidth / 2) - 80;
cam.update();
table.setPosition(cam.position.x - cam.viewportWidth / 2, 0);
buttonTable.setPosition(cam.position.x - cam.viewportWidth / 2, 0);
Gdx.input.setInputProcessor(stage);
break;
case PAUSED:
gameState = GameState.READY;
break;
}
}
public void drawWorld() {
game.batch.setProjectionMatrix(cam.combined);
switch (gameState) {
case READY:
game.batch.begin();
game.batch.draw(background, cam.position.x - cam.viewportWidth / 2, 0);
game.batch.draw(foreground, foregroundPos1.x, foregroundPos1.y + FOREGROUND_Y_OFFSET);
game.batch.draw(foreground, foregroundPos2.x, foregroundPos2.y + FOREGROUND_Y_OFFSET);
game.batch.draw(floor, floorPos1.x, floorPos1.y + FLOOR_Y_OFFSET);
game.batch.draw(floor, floorPos2.x, floorPos2.y + FLOOR_Y_OFFSET);
game.batch.draw(fishy.getAnimation().getKeyFrame(fishy.timePassed, true),
fishy.getPosition().x, fishy.getPosition().y);
game.batch.end();
stage.act();
stage.draw();
break;
case PAUSED:
break;
}
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
updateWorld(delta);
drawWorld();
}
@Override
public void dispose() {
System.out.println("Main Menu Dispose Called");
fishy.dispose();
stage.dispose();
}
public void updateForeground() {
if(cam.position.x - (cam.viewportWidth / 2) > foregroundPos1.x + foreground.getWidth())
foregroundPos1.add(foreground.getWidth() * 2, 0);
if(cam.position.x - (cam.viewportWidth / 2) > foregroundPos2.x + foreground.getWidth())
foregroundPos2.add(foreground.getWidth() * 2, 0);
}
public void updateFloor() {
if(cam.position.x - (cam.viewportWidth / 2) > floorPos1.x + floor.getWidth())
floorPos1.add(floor.getWidth() * 2, 0);
if(cam.position.x - (cam.viewportWidth / 2) > floorPos2.x + floor.getWidth())
floorPos2.add(floor.getWidth() * 2, 0);
}
@Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
@Override
public void pause() {
System.out.println("pause");
gameState = GameState.PAUSED;
}
@Override
public void resume() {
System.out.println("resume");
}
@Override
public void hide() {
System.out.println("hide");
}
public enum GameState {
READY, PAUSED;
}
}
即使关闭应用程序,背景中存在的对象的静态实例也存在问题 当应用程序打开assets Manager的所有实例时,请确保您正在将其作为新实例进行处理、置零和创建 使用
另外,如果您使用了一些,请处理蒙皮,如果您将一些用作单音,请将处理程序设置为null,例如,您应该避免静态资产引用。当Android活动退出时,应用程序保持活动状态,因此静态引用的对象也保持活动状态,直到下次从启动器启动游戏(新活动实例)为止 从技术上讲,您可以对资产进行静态引用,但如果您这样做,您需要确切地知道您在做什么,而且很容易出错。(您必须绝对确保在活动关闭时处理完所有内容,将静态引用清除为null,并确保在游戏再次启动时加载新实例。)最安全的做法是避免对任何实现
一次性
的对象进行静态引用
您需要阅读Java的类对象(不是类,不是对象,而是“类对象”),以便了解这里发生了什么。static
方法无法对非static
成员变量进行操作,因此您还需要从load
方法中删除static
关键字
然后,要访问资产管理器,需要创建资产类的实例,并通过标准成员变量进行访问:
public class FishyDash extends Game {
Assets assets;
public void create(){
assets = new Assets();
assets.load();
//....
}
}
public class MainMenuScreen implements Screen{
//...
public void show() {
System.out.println("second");
jumpSound = game.assets.manager.get(Assets.jumpSound, Sound.class);
//...
}
//...
}
这是一个更危险的答案。只有当您完全了解Android生命周期、Libgdx生命周期和Java的类对象时,我才建议您这样做 您可以保留静态资产引用,但必须确保它们在游戏结束时被处理掉
public class Assets {
//Safer to keep this private and use below public method for access
private static AssetManager manager; //do not instantiate here
public static AssetManager manager(){
if (manager == null) load();
return manager;
}
public static void load (){
if (manager == null) manager = new AssetManager();
//your existing load code
}
public static void dispose() {
if (manager != null){
manager.dispose();
manager = null;
}
}
}
public class FishyDash extends Game {
//...
@Override
public void dispose() {
Assets.dispose();
}
}
public class MainMenuScreen implements Screen{
//...
public void show() {
System.out.println("second");
//NOTE THE PARENTHESES AFTER manager below
jumpSound = Assets.manager().get(Assets.jumpSound, Sound.class);
//...
}
//...
}
我不相信我在使用任何静态实例变量?然后检查您的资产管理器或其他您应该处理的对象-列表如下:好的,我使用的是这个公共静态最终资产管理器manager=new AssetManager();但现在我将其更改为这个AssetManager=new AssetManager();但是问题是,它给了我一个错误,非静态字段“manager”不能从静态上下文引用。我的马槽现在是红色的,有什么解决办法吗?你不需要让静态字段变成非静态的!如果您将它用作静态的,请保留它-只需确保在dispose方法上您正在处理它并将引用设置为null-这就是以前多次提出的所有问题。不要对AssetManager或纹理进行静态引用。退出Android活动不会退出整个应用程序,因此静态引用将保留。@Tenfour04我添加了我的资产代码,我希望您能对此有所启发。我在维基上读到,这是做事情的正确方法,但我似乎不能使用manager.load()?你能链接到维基上的哪个地方吗?从技术上讲,您可以对资产进行静态引用,但如果您这样做,您需要确切地知道您在做什么,而且很容易出错。初学者经常犯这样的错误,所以wiki应该清理一下。我还在想办法,但我不知道该怎么办。所以现在在我的资产类别的dispose方法中,我在处理了manager之后添加了manager=null。我尝试使用Gdx.input.setCatchBackKey(true),然后在其中处理assest,但它只会加载一个黑色屏幕,上面链接着:小心,并继续告诉您为什么不应该在assets.OMG中使用
static
关键字!我现在非常爱你,这绝对是我需要的信息,对不起,我不太理解你之前的评论。。但我知道我的错误,我完全忽略了我的加载方法是静态的,我不知道怎么做,但我做到了。我只是没有把二和二放在一起。但这就是解决办法!非常感谢你!
public class FishyDash extends Game {
Assets assets;
public void create(){
assets = new Assets();
assets.load();
//....
}
}
public class MainMenuScreen implements Screen{
//...
public void show() {
System.out.println("second");
jumpSound = game.assets.manager.get(Assets.jumpSound, Sound.class);
//...
}
//...
}
public class Assets {
//Safer to keep this private and use below public method for access
private static AssetManager manager; //do not instantiate here
public static AssetManager manager(){
if (manager == null) load();
return manager;
}
public static void load (){
if (manager == null) manager = new AssetManager();
//your existing load code
}
public static void dispose() {
if (manager != null){
manager.dispose();
manager = null;
}
}
}
public class FishyDash extends Game {
//...
@Override
public void dispose() {
Assets.dispose();
}
}
public class MainMenuScreen implements Screen{
//...
public void show() {
System.out.println("second");
//NOTE THE PARENTHESES AFTER manager below
jumpSound = Assets.manager().get(Assets.jumpSound, Sound.class);
//...
}
//...
}