X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=sidebyside;f=core%2Fsrc%2Fru%2Fdeadsoftware%2Fcavedroid%2Fgame%2FGameSaver.java;h=53d147228f96a334a31ce9cd2e575c14b154e55e;hb=289536374d18bb05cde615c04d9fe576d6ac26bc;hp=26281f6c81dfa5c16207c91ce810a6e5f3016192;hpb=f4d52e3e4a3712050532786fca0aded5ff8b5a03;p=cavedroid.git diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java index 26281f6..53d1472 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java @@ -1,123 +1,248 @@ package ru.deadsoftware.cavedroid.game; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; +import ru.deadsoftware.cavedroid.MainConfig; +import ru.deadsoftware.cavedroid.game.mobs.MobsController; +import ru.deadsoftware.cavedroid.game.model.block.Block; +import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.world.GameWorld; -import java.io.BufferedOutputStream; -import java.io.DataInputStream; -import java.io.IOException; +import javax.annotation.CheckForNull; +import java.io.*; import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; -//TODO rewrite saver public class GameSaver { - private static final int VERSION = 0; + private static final String TAG = "GameSaver"; + public static class Data { + @CheckForNull + private MobsController mMobsController; + @CheckForNull + private DropController mDropController; + @CheckForNull + private Block[][] mForeMap, mBackMap; + + public Data(MobsController mobsController, DropController dropController, Block[][] foreMap, Block[][] backMap) { + mMobsController = mobsController; + mDropController = dropController; + mForeMap = foreMap; + mBackMap = backMap; + } + + public MobsController retrieveMobsController() { + assert mMobsController != null; + MobsController mobsController = mMobsController; + mMobsController = null; + return mobsController; + } + + public DropController retrieveDropController() { + assert mDropController != null; + DropController dropController = mDropController; + mDropController = null; + return dropController; + } + + public Block[][] retrieveForeMap() { + assert mForeMap != null; + Block[][] foreMap = mForeMap; + mForeMap = null; + return foreMap; + } + + public Block[][] retrieveBackMap() { + assert mBackMap != null; + Block[][] backMap = mBackMap; + mBackMap = null; + return backMap; + } + + public boolean isEmpty() { + return mMobsController == null && mDropController == null && mForeMap == null && mBackMap == null; + } + } + + private static final int SAVE_VERSION = 1; private static byte[] intToBytes(int i) { return ByteBuffer.allocate(4).putInt(i).array(); } - private static void saveMap(FileHandle file, int[][] map) throws IOException { - int rl, bl; + private static Map buildBlocksDictionary(Block[][] foreMap, Block[][] backMap) { + final HashMap dict = new HashMap<>(); + + int id = 0; + for (int i = 0; i < foreMap.length; i++) { + for (int j = 0; j < foreMap[i].length; j++) { + for (int k = 0; k < 2; k++) { + final Block block = k == 0 ? foreMap[i][j] : backMap[i][j]; + final String key = block.getParams().getKey(); + if (!dict.containsKey(key)) { + dict.put(key, id++); + } + } + } + } + + return dict; + } + + private static void saveDict(FileHandle file, Map dict) { + final String[] arr = new String[dict.size()]; + + for (Map.Entry entry : dict.entrySet()) { + arr[entry.getValue()] = entry.getKey(); + } + + final StringBuilder builder = new StringBuilder(); + for (String key : arr) { + builder.append(key); + builder.append('\n'); + } + + file.writeString(builder.toString(), false); + } + + private static String[] loadDict(FileHandle file) { + return file.readString().split("\n"); + } + + private static void saveMap(FileHandle file, Block[][] map, Map dict) throws IOException { + int run, block; int width = map.length; int height = map[0].length; + BufferedOutputStream out = new BufferedOutputStream(file.write(false)); - out.write(intToBytes(VERSION)); + + out.write(intToBytes(SAVE_VERSION)); out.write(intToBytes(width)); out.write(intToBytes(height)); + for (int y = 0; y < height; y++) { - bl = map[0][y]; - rl = 0; - for (int[] ints : map) { - if (ints[y] != bl) { - out.write(intToBytes(rl)); - out.write(intToBytes(bl)); - rl = 0; - bl = ints[y]; + block = dict.get(map[0][y].getParams().getKey()); + run = 0; + for (Block[] blocks : map) { + int newValue = dict.get(blocks[y].getParams().getKey()); + if (newValue != block) { + out.write(intToBytes(run)); + out.write(intToBytes(block)); + run = 0; + block = dict.get(blocks[y].getParams().getKey()); } - rl++; + run++; } - out.write(intToBytes(rl)); - out.write(intToBytes(bl)); + out.write(intToBytes(run)); + out.write(intToBytes(block)); } + out.flush(); out.close(); } + private static Block[][] loadMap(GameItemsHolder gameItemsHolder, FileHandle file, String[] dict) throws Exception { + Block[][] map; + int version, width, height; + int run, block; - private static int[][] loadMap(FileHandle file) throws Exception { - int[][] map; - int ver, width, height; - int rl, bl; DataInputStream in = new DataInputStream(file.read()); - ver = in.readInt(); - if (VERSION == ver) { + + version = in.readInt(); + + if (SAVE_VERSION == version) { width = in.readInt(); height = in.readInt(); - map = new int[width][height]; + map = new Block[width][height]; for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x += rl) { - rl = in.readInt(); - bl = in.readInt(); - for (int i = x; i < x + rl; i++) { - map[i][y] = bl; + for (int x = 0; x < width; x += run) { + run = in.readInt(); + block = in.readInt(); + for (int i = x; i < x + run; i++) { + map[i][y] = gameItemsHolder.getBlock(dict[block]); } } } - in.close(); } else { throw new Exception("version mismatch"); } + + in.close(); return map; } - public static GameProc load() { -// FileHandle file = Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/game.sav"); -// GameProc gameProc = null; -// try { -// ObjectInputStream in = new ObjectInputStream(file.read()); -// int ver = in.readInt(); -// if (VERSION == ver) { -// gameProc = (GameProc) in.readObject(); -// } else { -// throw new Exception("version mismatch"); -// } -// in.close(); -// gameProc.world = new GameWorld( -// loadMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/foremap.sav")), -// loadMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/backmap.sav")) -// ); -// gameProc.physics = new GamePhysics(); -// gameProc.input = new GameInput(); -// } catch (Exception e) { -// Gdx.app.error("GameSaver", e.getMessage(), e); -// Gdx.app.exit(); -// } -// return gameProc; + @CheckForNull + public static Data load(MainConfig mainConfig, GameItemsHolder gameItemsHolder) { + String folder = mainConfig.getGameFolder(); + FileHandle file = Gdx.files.absolute(folder + "/saves/game.sav"); + + try { + ObjectInputStream in = new ObjectInputStream(file.read()); + int version = in.readInt(); + DropController dropController; + MobsController mobsController; + + if (SAVE_VERSION == version) { + dropController = (DropController) in.readObject(); + mobsController = (MobsController) in.readObject(); + } else { + throw new Exception("version mismatch"); + } + + in.close(); + + final String[] dict = loadDict(Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/dict")); + Block[][] foreMap = loadMap(gameItemsHolder, Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/foremap.sav"), dict); + Block[][] backMap = loadMap(gameItemsHolder, Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/backmap.sav"), dict); + + if (dropController == null || mobsController == null) { + throw new Exception("couldn't load"); + } + + return new Data(mobsController, dropController, foreMap, backMap); + } catch (Exception e) { + Gdx.app.error("GameSaver", e.getMessage()); + } + return null; } - public static void save(GameProc gp) { -// FileHandle file = Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/"); -// file.mkdirs(); -// file = Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/game.sav"); -// try { -// ObjectOutputStream out = new ObjectOutputStream(file.write(false)); -// out.writeInt(VERSION); -// out.writeObject(gp); -// out.close(); -// saveMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/foremap.sav"), gp.world.getFullForeMap()); -// saveMap(Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/backmap.sav"), gp.world.getFullBackMap()); -// } catch (Exception e) { -// e.printStackTrace(); -// } - } + public static void save(MainConfig mainConfig, + DropController dropController, + MobsController mobsController, + GameWorld gameWorld) { + String folder = mainConfig.getGameFolder(); + FileHandle file = Gdx.files.absolute(folder + "/saves/"); + file.mkdirs(); + file = Gdx.files.absolute(folder + "/saves/game.sav"); + + final Block[][] foreMap, backMap; + foreMap = gameWorld.getFullForeMap(); + backMap = gameWorld.getFullBackMap(); + + final Map dict = buildBlocksDictionary(foreMap, backMap); - public static boolean exists() { -// return (Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/game.sav").exists() && -// Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/foremap.sav").exists() && -// Gdx.files.absolute(CaveGame.GAME_FOLDER + "/saves/backmap.sav").exists()); - return false; + try { + ObjectOutputStream out = new ObjectOutputStream(file.write(false)); + out.writeInt(SAVE_VERSION); + out.writeObject(dropController); + out.writeObject(mobsController); + out.close(); + + saveDict(Gdx.files.absolute(folder + "/saves/dict"), dict); + saveMap(Gdx.files.absolute(folder + "/saves/foremap.sav"), gameWorld.getFullForeMap(), dict); + saveMap(Gdx.files.absolute(folder + "/saves/backmap.sav"), gameWorld.getFullBackMap(), dict); + } catch (Exception e) { + e.printStackTrace(); + } } + public static boolean exists(MainConfig mainConfig) { + String folder = mainConfig.getGameFolder(); + return (Gdx.files.absolute(folder + "/saves/game.sav").exists() && + Gdx.files.absolute(folder + "/saves/foremap.sav").exists() && + Gdx.files.absolute(folder + "/saves/backmap.sav").exists()); + } }