File Parser for levels #18

Merged
tonitch merged 29 commits from MapParser into master 2023-04-21 20:00:16 +02:00
4 changed files with 39 additions and 16 deletions
Showing only changes of commit acf1faba49 - Show all commits

View File

@ -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.

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}