java - android-Libgdx序列化和反序列化

标签 java android serialization libgdx

我有一个 Player 类,它记录玩家位置和其他几个变量。此外,为了在游戏关闭后记住这些状态,我尝试序列化和反序列化我的 player 对象。这个过程对于我的 libGdx 项目的桌面版本来说工作得很好,但是当我用我的 Android 设备运行它时它失败了(我的坐标没有保存)。此外,当我检查“desktop”文件夹时,我可以看到“player.dat”文件,但是在我的android文件夹中它不存在......起初我想这可能与我的方式有关正在调试并将实际游戏保存在我的手机上并运行它,但即使如此,坐标也没有保存。

玩家等级:

public class Player implements Serializable {

    private static final transient String defaultTexture = "data/libgdx.png";

    private static final long serialVersionUID = 1L;
    transient Texture texture;
    Vector2 position;
    String textureLoc;
    transient Sprite sprite;

    public Player (Vector2 position, String textureLoc){
        this.position = position;
        this.textureLoc = textureLoc;
    }

    public void loadContent() {
        if (Gdx.files.internal(textureLoc).exists())
            texture = new Texture(Gdx.files.internal(textureLoc));
        else
            texture = new Texture(Gdx.files.internal(defaultTexture));
        sprite = new Sprite(texture);
    }

    public void update(OrthographicCamera camera) {

        if(Gdx.input.isTouched()){
            Vector3 tp = new Vector3();
            tp.set(Gdx.input.getX(), Gdx.input.getY(), 0);
            camera.unproject(tp);
            if(tp.y > sprite.getY()){
                position.y += 4f;
            }else{
                position.y -= 4f;
            }
        }           
    }

    public void draw(SpriteBatch batch) {
        batch.draw(texture, position.x, position.y);
    }

    public static void savePlayer(Player player) throws IOException {
        FileHandle file = Gdx.files.local("player.dat");
        try {
            file.writeBytes(serialize(player), false);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Player readPlayer() throws IOException, ClassNotFoundException {
        Player player = null;
        FileHandle file = Gdx.files.local("player.dat");
        player = (Player) deserialize(file.readBytes());
        return player;
    }

    private static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }

    public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return o.readObject();
    }

    public Vector2 getPosition(){
        return position;
    }

    public void setPosition(Vector2 position){
        this.position = position;
    }
}

主类:

public class MyGdxGame extends ApplicationAdapter { 
    private OrthographicCamera camera;
    Player player;
    SpriteBatch batch;  
    Vector2 position = new Vector2(50,50);
    boolean x = false;
    boolean y = false;  

    BitmapFont font;    

    @Override
    public void create () {     
        font = new BitmapFont();
        font.setScale(50f);

        camera = new OrthographicCamera();
        batch = new SpriteBatch();
        player = new Player(new Vector2(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2), "data/mario.jpg");
        if(Gdx.files.local("player.dat").exists()){
            System.out.println("Player Exists. Reading File ...");

            x = true;
            try {
                player = Player.readPlayer();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) { 
                e.printStackTrace();
            }           
        }else{
            System.out.println("Player does not exist. Creating new player ...");
            y = true;

            player = new Player(new Vector2(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2), "data/mario.jpg");          
        }   

        player.loadContent(); 
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);   
        player.update(camera);
        batch.begin();
        if(x){font.draw(batch, "Player Exists. Reading File ...", 20, 20);}
        if(y){font.draw(batch, "Player does not exist. Creating new player ...", 100, 100);}
        player.draw(batch);
        batch.end();        
    }

    public void dispose(){
        try {
            Player.savePlayer(player);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我唯一的猜测是,也许在 Android 上保存/获取序列化文件有一些细节,但即便如此,我遵循了 libGdx API,所以它应该可以工作。

最佳答案

以防万一将来其他人遇到同样的问题,您还需要在暂停以及处置上保存游戏状态。事实证明,序列化和反序列化过程一切正常,并且文件实际上可以很好地存储到您的设备上。主要问题是 dispose 只有在手机手动杀死应用程序时才会被调用,而不是你:)所以就像我说的,还要在暂停时保存游戏状态,即当您单击设备上的主页按钮时。例如:

 public void pause () { 
         try {
            Player.savePlayer(player);
         } catch (IOException e) {
            e.printStackTrace();
         }
 }

关于java - android-Libgdx序列化和反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24826195/

相关文章:

java - 使用SearchView到ListView进行搜索(关于JSON)

java - Android Studio : Layout hierarchy problems

c# - MvvmCross,如何在另一个程序集中注册Service?

java - Android JSON变量存储到带键的多维数组

json - 更改 JSON.NET 序列化属性名称的方式

php - 使用 JQuery Serialize 时如何为空白字段插入 NULL 值?

java - 如果一个数组被分配给一个对象引用,那么对象引用指向什么?

java - 配置spring缓存咖啡因

java - Spring Boot - 在类路径资源中创建名称为 'dataSource' 的 bean 时出错

c# - C# 中的二进制序列化(实际上是所见即所得序列化)