Add binary serializer, make game classes serializable
This commit is contained in:
parent
6d2501b022
commit
67d74936d2
9 changed files with 222 additions and 22 deletions
|
@ -9,8 +9,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.Klooni;
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
|
||||||
|
|
||||||
public abstract class BaseScorer {
|
public abstract class BaseScorer implements BinSerializable {
|
||||||
|
|
||||||
//region Members
|
//region Members
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,16 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.Klooni;
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
|
||||||
|
|
||||||
// Represents the on screen board, with all the put cells
|
// Represents the on screen board, with all the put cells
|
||||||
// and functions to determine when it is game over given a PieceHolder
|
// and functions to determine when it is game over given a PieceHolder
|
||||||
public class Board {
|
public class Board implements BinSerializable {
|
||||||
|
|
||||||
//region Members
|
//region Members
|
||||||
|
|
||||||
|
@ -185,4 +190,30 @@ public class Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region Serialization
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
// Cell count, cells in row-major order
|
||||||
|
out.writeInt(cellCount);
|
||||||
|
for (int i = 0; i < cellCount; ++i)
|
||||||
|
for (int j = 0; j < cellCount; ++j)
|
||||||
|
cells[i][j].write(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream in) throws IOException {
|
||||||
|
// If the saved cell count does not match the current cell count,
|
||||||
|
// then an IOException is thrown since the data saved was invalid
|
||||||
|
final int savedCellCount = in.readInt();
|
||||||
|
if (savedCellCount != cellCount)
|
||||||
|
throw new IOException("Invalid cellCount saved.");
|
||||||
|
|
||||||
|
for (int i = 0; i < cellCount; ++i)
|
||||||
|
for (int j = 0; j < cellCount; ++j)
|
||||||
|
cells[i][j].read(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,16 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.math.Interpolation;
|
import com.badlogic.gdx.math.Interpolation;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.Klooni;
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
|
||||||
|
|
||||||
// Represents a single cell, with a position, size and color.
|
// Represents a single cell, with a position, size and color.
|
||||||
// Instances will use the cell texture provided by the currently used skin.
|
// Instances will use the cell texture provided by the currently used skin.
|
||||||
public class Cell {
|
public class Cell implements BinSerializable {
|
||||||
|
|
||||||
//region Members
|
//region Members
|
||||||
|
|
||||||
|
@ -108,4 +113,19 @@ public class Cell {
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region Serialization
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
// Only the color index is saved
|
||||||
|
out.writeInt(colorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream in) throws IOException {
|
||||||
|
colorIndex = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.Klooni;
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
|
||||||
// Represents a piece with an arbitrary shape, which
|
// Represents a piece with an arbitrary shape, which
|
||||||
|
@ -88,22 +92,25 @@ public class Piece {
|
||||||
|
|
||||||
// Generates a random piece with always the same color for the generated shape
|
// Generates a random piece with always the same color for the generated shape
|
||||||
static Piece random() {
|
static Piece random() {
|
||||||
int color = MathUtils.random(8); // 9 pieces
|
return fromIndex(MathUtils.random(8)); // 9 pieces, [0…8]
|
||||||
switch (color) {
|
}
|
||||||
|
|
||||||
|
private static Piece fromIndex(int colorIndex) {
|
||||||
|
switch (colorIndex) {
|
||||||
// Squares
|
// Squares
|
||||||
case 0: return new Piece(1, 1, false, color);
|
case 0: return new Piece(1, 1, false, colorIndex);
|
||||||
case 1: return new Piece(2, 2, false, color);
|
case 1: return new Piece(2, 2, false, colorIndex);
|
||||||
case 2: return new Piece(3, 3, false, color);
|
case 2: return new Piece(3, 3, false, colorIndex);
|
||||||
|
|
||||||
// Lines
|
// Lines
|
||||||
case 3: return new Piece(1, 2, MathUtils.randomBoolean(), color);
|
case 3: return new Piece(1, 2, MathUtils.randomBoolean(), colorIndex);
|
||||||
case 4: return new Piece(1, 3, MathUtils.randomBoolean(), color);
|
case 4: return new Piece(1, 3, MathUtils.randomBoolean(), colorIndex);
|
||||||
case 5: return new Piece(1, 4, MathUtils.randomBoolean(), color);
|
case 5: return new Piece(1, 4, MathUtils.randomBoolean(), colorIndex);
|
||||||
case 6: return new Piece(1, 5, MathUtils.randomBoolean(), color);
|
case 6: return new Piece(1, 5, MathUtils.randomBoolean(), colorIndex);
|
||||||
|
|
||||||
// L's
|
// L's
|
||||||
case 7: return new Piece(2, MathUtils.random(3), color);
|
case 7: return new Piece(2, MathUtils.random(3), colorIndex);
|
||||||
case 8: return new Piece(3, MathUtils.random(3), color);
|
case 8: return new Piece(3, MathUtils.random(3), colorIndex);
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Random function is broken.");
|
throw new RuntimeException("Random function is broken.");
|
||||||
}
|
}
|
||||||
|
@ -161,4 +168,16 @@ public class Piece {
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region Serialization
|
||||||
|
|
||||||
|
void write(DataOutputStream out) throws IOException {
|
||||||
|
out.writeInt(colorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Piece read(DataInputStream in) throws IOException {
|
||||||
|
return fromIndex(in.readInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,16 @@ import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.Klooni;
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
|
||||||
|
|
||||||
// A holder of pieces that can be drawn on screen.
|
// A holder of pieces that can be drawn on screen.
|
||||||
// Pieces can be picked up from it and dropped on a board.
|
// Pieces can be picked up from it and dropped on a board.
|
||||||
public class PieceHolder {
|
public class PieceHolder implements BinSerializable {
|
||||||
|
|
||||||
//region Members
|
//region Members
|
||||||
|
|
||||||
|
@ -229,4 +234,34 @@ public class PieceHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region Serialization
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
// Piece count, false if piece == null, true + piece if piece != null
|
||||||
|
out.writeInt(count);
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
if (pieces[i] == null) {
|
||||||
|
out.writeBoolean(false);
|
||||||
|
} else {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
pieces[i].write(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream in) throws IOException {
|
||||||
|
// If the saved piece count does not match the current piece count,
|
||||||
|
// then an IOException is thrown since the data saved was invalid
|
||||||
|
final int savedPieceCount = in.readInt();
|
||||||
|
if (savedPieceCount != count)
|
||||||
|
throw new IOException("Invalid piece count saved.");
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
pieces[i] = in.readBoolean() ? Piece.read(in) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,21 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.math.Interpolation;
|
import com.badlogic.gdx.math.Interpolation;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.Klooni;
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
|
||||||
|
|
||||||
// Used to keep track of the current and maximum
|
// Used to keep track of the current and maximum
|
||||||
// score, and to also display it on the screen.
|
// score, and to also display it on the screen.
|
||||||
// The maximum score is NOT saved automatically.
|
// The maximum score is NOT saved automatically.
|
||||||
public class Scorer extends BaseScorer {
|
public class Scorer extends BaseScorer implements BinSerializable {
|
||||||
|
|
||||||
//region Members
|
//region Members
|
||||||
|
|
||||||
private int currentScore, maxScore;
|
private int currentScore, highScore;
|
||||||
|
|
||||||
// To interpolate between shown score -> real score
|
// To interpolate between shown score -> real score
|
||||||
private float shownScore;
|
private float shownScore;
|
||||||
|
@ -27,7 +32,7 @@ public class Scorer extends BaseScorer {
|
||||||
super(game, layout, Klooni.getMaxScore());
|
super(game, layout, Klooni.getMaxScore());
|
||||||
|
|
||||||
currentScore = 0;
|
currentScore = 0;
|
||||||
maxScore = Klooni.getMaxScore();
|
highScore = Klooni.getMaxScore();
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
@ -55,7 +60,7 @@ public class Scorer extends BaseScorer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isNewRecord() {
|
protected boolean isNewRecord() {
|
||||||
return currentScore > maxScore;
|
return currentScore > highScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,4 +78,21 @@ public class Scorer extends BaseScorer {
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region Serialization
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
// currentScore, highScore
|
||||||
|
out.writeInt(currentScore);
|
||||||
|
out.writeInt(highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream in) throws IOException {
|
||||||
|
currentScore = in.readInt();
|
||||||
|
highScore = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,19 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.Klooni;
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class TimeScorer extends BaseScorer {
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
import io.github.lonamiwebs.klooni.serializer.BinSerializable;
|
||||||
|
|
||||||
|
public class TimeScorer extends BaseScorer implements BinSerializable {
|
||||||
|
|
||||||
//region Members
|
//region Members
|
||||||
|
|
||||||
private long startTime;
|
private long startTime;
|
||||||
private final int highScoreTime;
|
private int highScoreTime;
|
||||||
|
|
||||||
// Indicates where we would die in time. Score adds to this, so we take
|
// Indicates where we would die in time. Score adds to this, so we take
|
||||||
// longer to die. To get the "score" we simply calculate `deadTime - startTime`
|
// longer to die. To get the "score" we simply calculate `deadTime - startTime`
|
||||||
|
@ -113,4 +118,23 @@ public class TimeScorer extends BaseScorer {
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region Serialization
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
// startTime, highScoreTime, deadTime
|
||||||
|
out.writeLong(startTime);
|
||||||
|
out.writeInt(highScoreTime);
|
||||||
|
out.writeLong(deadTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream in) throws IOException {
|
||||||
|
startTime = in.readLong();
|
||||||
|
highScoreTime = in.readInt();
|
||||||
|
deadTime = in.readLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.github.lonamiwebs.klooni.serializer;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface BinSerializable {
|
||||||
|
void write(final DataOutputStream out) throws IOException;
|
||||||
|
void read(final DataInputStream in) throws IOException;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package io.github.lonamiwebs.klooni.serializer;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class BinSerializer {
|
||||||
|
public static void serialize(final BinSerializable serializable, final OutputStream output)
|
||||||
|
throws IOException {
|
||||||
|
DataOutputStream out = new DataOutputStream(output);
|
||||||
|
try {
|
||||||
|
serializable.write(out);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException ignored) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo uhm maybe make the classes serializable? like telethon, kinda, idk, bye.
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
DataInputStream d = new DataInputStream(new FileInputStream("test.txt"));
|
||||||
|
DataOutputStream out = new DataOutputStream(new FileOutputStream("test1.txt"));
|
||||||
|
String count;
|
||||||
|
d.readFully();
|
||||||
|
while((count = d.readLine()) != null){
|
||||||
|
String u = count.toUpperCase();
|
||||||
|
System.out.println(u);
|
||||||
|
out.writeBytes(u + " ,");
|
||||||
|
}
|
||||||
|
d.close();
|
||||||
|
out.close();
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue