File Parser for levels #18
@ -31,11 +31,20 @@ level data at the top of the file.
|
||||
- 4 first bits : width
|
||||
- 4 last bits: height
|
||||
- next bytes -> Width * Height (+1 if Width * Height % 8 is not 0)
|
||||
- Position ( only for saved file )
|
||||
- 'F' and 'L' on 2 bytes for floating positions when the piece is not placed
|
||||
- x and y on 2 bytes for position if the piece is placed
|
||||
|
||||
### Saved file
|
||||
|
||||
For saved file, the extension will be .slevel
|
||||
The only difference is that at the end of the map data (after the pieces and before the
|
||||
Footer. there will be the position of each pieces from their top-left corner in the map.
|
||||
following this pattern for each pieces
|
||||
|
||||
- 'F' and 'L' on 2 bytes for floating positions when the piece is not placed
|
||||
- x and y on 2 bytes for position if the piece is placed
|
||||
|
||||
## Known Limitation
|
||||
|
||||
1) by putting the piece size on one byte. We limit the maximum piece size to 15 x 15 (1111 | 1111)
|
||||
I don't think we will ever need a piece larger than 5x5 so this is clearly a feature, not a bug! :-)
|
||||
We might use the same methods for the pieces positions but there could be a posibility to have
|
||||
larger map if I use 2 bytes for the positions.
|
||||
|
@ -3,6 +3,7 @@ package school_project.Parsers;
|
||||
import school_project.Map;
|
||||
import school_project.Piece;
|
||||
import school_project.Utils.Bitwise;
|
||||
import school_project.Vec2;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
@ -115,14 +116,23 @@ public class BinaryParser implements FileParser {
|
||||
byte piece_count = levelData[3 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0)];
|
||||
Piece[] ret = new Piece[piece_count];
|
||||
byte[] pieces_data = Arrays.copyOfRange(levelData, 4 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0), levelData.length - 1);
|
||||
byte[] pieces_positions = saved_data ? Arrays.copyOfRange(levelData, levelData.length - 1 - piece_count,levelData.length - 1): null;
|
||||
int piece_offset = 0;
|
||||
for (int piece_index = 0; piece_index < piece_count; piece_index++) {
|
||||
// TODO: 3/24/23 BUG! this should not check every byte linearly like this... data are not next to each other...
|
||||
byte[] _piece_size = Bitwise.ByteToNible(pieces_data[piece_index]);
|
||||
byte _piece_width = _piece_size[0], _piece_height = _piece_size[1];
|
||||
byte[] _piece_data = Arrays.copyOfRange(pieces_data, piece_index + 1, 1 + _piece_width * _piece_height / 8 + (_piece_height * _piece_width % 8 != 0 ? 1 : 0));
|
||||
byte[] _piece_save_data = Arrays.copyOfRange(pieces_data, )
|
||||
boolean[][] _piece_matrix = BuildMatrixFromBytes(_piece_width, _piece_height, _piece_data);
|
||||
Vec2 _piece_size = Bitwise.ByteToNible(pieces_data[piece_index + piece_offset]);
|
||||
|
||||
byte[] _piece_data = Arrays.copyOfRange(pieces_data, piece_index + piece_offset + 1, piece_index + piece_offset + 1 + _piece_size.x * _piece_size.y / 8 + (_piece_size.x * _piece_size.y % 8 != 0 ? 1 : 0));
|
||||
|
||||
boolean[][] _piece_matrix = BuildMatrixFromBytes(_piece_size.x, _piece_size.y, _piece_data);
|
||||
|
||||
ret[piece_index] = new Piece(_piece_matrix);
|
||||
|
||||
if(saved_data){
|
||||
Vec2 _piece_pos = new Vec2(pieces_positions[piece_index*2], pieces_positions[piece_index*2 + 1]);
|
||||
ret[piece_index].setPosition(_piece_pos);
|
||||
}
|
||||
|
||||
piece_offset += _piece_size.x * _piece_size.y / 8 + (_piece_size.x * _piece_size.y % 8 != 0 ? 1 : 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -212,7 +222,7 @@ public class BinaryParser implements FileParser {
|
||||
ret += p.getHeight() * p.getWidth() / 8;
|
||||
ret += p.getHeight() * p.getWidth() % 8 == 0 ? 0 : 1; // add 1 if the size of the piece is not mult of 8
|
||||
if(data){
|
||||
ret += p.getPosition() != null ? 2: 1; // if the piece is not placed, only one byte else 2
|
||||
ret += 2; // if the piece is not placed, only one byte else 2
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -22,6 +22,7 @@ public interface FileParser {
|
||||
* Could be used for generating level file. might not be used in game.
|
||||
* @param file the file where to save
|
||||
* @param levelData the map to save
|
||||
* @param save_data should save the map data (need to be false only in development I think)
|
||||
*/
|
||||
void saveLevel(File file, Map levelData, boolean save_data) throws IOException;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package school_project.Utils;
|
||||
|
||||
import school_project.Vec2;
|
||||
|
||||
public class Bitwise {
|
||||
|
||||
/**
|
||||
@ -16,15 +18,16 @@ public class Bitwise {
|
||||
/**
|
||||
* Transform a byte (8 bit) to two Nible (4 bit) with a split in the middle
|
||||
* Exemple:
|
||||
* in = 01000101 (=69)
|
||||
* out = { 00000100, 00000101 } (={4, 5})
|
||||
* in = 01000101 (=69)
|
||||
* out = { 00000100, 00000101 } (={4, 5})
|
||||
*
|
||||
* @param in the byte to split
|
||||
* @return an arrya of 2 byte ret[0] = left part; ret[1] = right part
|
||||
*/
|
||||
public static byte[] ByteToNible(byte in){
|
||||
byte[] ret = new byte[2];
|
||||
ret[0] = (byte) (in >> 4);
|
||||
ret[1] = (byte) (in & 15); // apply the mask '00001111'
|
||||
public static Vec2 ByteToNible(byte in){
|
||||
Vec2 ret = new Vec2();
|
||||
ret.x = (byte) (in >> 4);
|
||||
ret.y = (byte) (in & 15); // apply the mask '00001111'
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user