Some explorations to save the game

Keywords: Java xml Android

To make an slg game, because the content of slg game is usually too long, it must be persisted

Prior to 1. Set, load and save the custom game map format In java, you can directly use fileoutputstream and dataoutputstream

 public static void saveMapBin(MapBinDAO binFile, String Path) {
        try {
            FileOutputStream fs_out = new FileOutputStream(Path);//"D://test.bin"
            DataOutputStream out = new DataOutputStream(fs_out);
            out.writeShort(binFile.mapVersion);// 4
            out.writeInt(binFile.mapWidth);// 8
            out.writeInt(binFile.mapHeight);// 8
            for (int i = 0; i < binFile.getMapbin().size(); i++) {
                out.writeByte(binFile.getMapbin().get(i).getBlockType());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackTile());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackIdx());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackRefX());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackRefY());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeTile());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeIdx());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeRefX());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeRefY());// 2
                out.writeByte(binFile.getMapbin().get(i).getWaterPass());// 2
                out.writeByte(binFile.getMapbin().get(i).getLandPass());// 2
                out.writeInt(binFile.getMapbin().get(i).getRegionId());// 8
                out.writeByte(binFile.getMapbin().get(i).getClimateId());// 2
            }
            out.close();
            
            // out.writeInt(i);//4 position
            // out.writeShort(i2);//2 position
            // out.writeByte(i3);//1 position
            // out.close();
            
        } catch (FileNotFoundException fe) {
            System.err.println(fe);
        } catch (IOException ioe) {
            System.err.println(ioe);
        }
        System.out.println("Ok");
    }

Now we need to save it in libgdx

Here I meet this requirement in the process of making map editor. Save the modified map

Here I write a FileByte class to simulate the DataOutputStream class to save byte data

package com.zhfy.game.framework.tool;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class FileByte {
    private int bytesLength;
    private List<Integer> bytes;
    
    
    public void init() {
        bytes=new ArrayList<Integer>();
        bytesLength=0;
    }
    
    //4
    public final void writeInt(int v) throws IOException {
        if(bytes==null) {
            init();
        }
        
        bytes.add((v >>> 24) & 0xFF);
        bytes.add((v >>> 16) & 0xFF);
        bytes.add((v >>>  8) & 0xFF);
        bytes.add((v >>>  0) & 0xFF);
        incCount(4);
    }
    
    //2
    public final void writeShort(int v) throws IOException {
        if(bytes==null) {
            init();
        }
        bytes.add((v >>> 8) & 0xFF);
        bytes.add((v >>> 0) & 0xFF);
        incCount(2);
    }
    
    //1
    public final void writeByte(int v) throws IOException {
        if(bytes==null) {
            init();
        }
        bytes.add(v);
        incCount(1);
    }
    
    
    private void incCount(int value) {
        int temp = bytesLength + value;
        if (temp < 0) {
            temp = Integer.MAX_VALUE;
        }
        bytesLength = temp;
    }
    
    
    //TODO To be verified
    public byte[] getByte(){
        byte[] bLocalArr = new byte[bytesLength];
        int i,iMax;iMax=bytes.size();
        
        for ( i = 0; i<iMax; i++) {
            bLocalArr[i] = (byte) (bytes.get(i)& 0xFF);
        }
        init();
        return bLocalArr;
    }
    
}

Then the save method is changed to

public static void saveMapBin(MapBinDAO binFile, String Path) {
        try {
            FileByte out=new FileByte();
            out.writeShort(binFile.mapVersion);// 4
            out.writeInt(binFile.mapWidth);// 8
            out.writeInt(binFile.mapHeight);// 8
            for (int i = 0; i < binFile.getMapbin().size(); i++) {
                out.writeByte(binFile.getMapbin().get(i).getBlockType());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackTile());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackIdx());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackRefX());// 2
                out.writeByte(binFile.getMapbin().get(i).getBackRefY());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeTile());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeIdx());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeRefX());// 2
                out.writeByte(binFile.getMapbin().get(i).getForeRefY());// 2
                out.writeByte(binFile.getMapbin().get(i).getWaterPass());// 2
                out.writeByte(binFile.getMapbin().get(i).getLandPass());// 2
                out.writeInt(binFile.getMapbin().get(i).getRegionId());// 8
                out.writeByte(binFile.getMapbin().get(i).getClimateId());// 2
            }
            FileHandle file = Gdx.files.local(Path); 
            file.writeBytes(out.getByte(), false);
            // out.writeInt(i);//4 position
            // out.writeShort(i2);//2 position
            // out.writeByte(i3);//1 position
            // out.close();
            
        } catch (FileNotFoundException fe) {
            System.err.println(fe);
        } catch (IOException ioe) {
            System.err.println(ioe);
        }
        System.out.println("Ok");
    }

Prompt that the game is saved successfully in the game

But through Everything, we find that the address is not in the expected location, such as the top and bottom of the figure, the bottom is the original file location, and the top is the location generated after saving

The main reason is

// according to mapid generate MapBinDAO class
    public MapBinDAO getMapDaoByMapId(int mapId) {
        XmlReader reader = new XmlReader();
        String str = "";
        Element root = reader.parse(Gdx.files.internal("config/def_map.xml"));
        int childNum = root.getChildCount();
        for (int i = 0; i < childNum; i++) {
            if (root.getChild(i).getInt("id") == mapId) {
                str = root.getChild(i).get("name");
                bt = Gdx.files.internal("bin/" + str + ".bin").readBytes();
                try {
                    mapBinDao = GameMap.readMapBin(bt);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return mapBinDao;
            }
        }
        return mapBinDao;
    }

The way to save the location is local, and the way we load the resources is internal

From the data

internal location is read-only

The local location is readable and writable

In addition, if you use the internal method to save it, you will make an error,

So here, change the loading location to local, and put it in the corresponding location of desktop, and put the file in the corresponding location of android assets when it is officially released

Posted by winkhere on Wed, 27 Nov 2019 08:02:45 -0800