You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
6.3 KiB
241 lines
6.3 KiB
/** |
|
* Copyright 2022 Jamie Munro, Distributed under the Common Public Attribution License Version 1.0 (CPAL-1.0) |
|
* Tile engine |
|
*/ |
|
|
|
import java.io.BufferedReader; |
|
import java.io.File; |
|
import java.io.FileReader; |
|
import java.io.IOException; |
|
import java.io.InputStreamReader; |
|
import java.util.ArrayList; |
|
import java.util.List; |
|
|
|
/** |
|
* Level class |
|
* Represents a level/map |
|
*/ |
|
class Level { |
|
private Configuration conf; |
|
private TileProperties props; |
|
|
|
private String name; |
|
private int startX; |
|
private int startY; |
|
|
|
private int cols; |
|
private int rows; |
|
|
|
private Tile[][] tileset; |
|
private Tile emptyTile; |
|
|
|
/** |
|
* Constructor |
|
*/ |
|
public Level(Configuration config, TileProperties properties) { |
|
conf = config; |
|
props = properties; |
|
emptyTile = new Tile(conf.emptyTile, -1, -1, props); |
|
} |
|
|
|
/** |
|
* Retrives the tile at the specified location (0-indexed) |
|
* Returns the empty tile (id=0) if there is no tile at that location |
|
* @param col column (x co-ordinate) |
|
* @param row row (y co-ordainate) |
|
* @return tile at (col, row) |
|
* @throws IOException |
|
*/ |
|
public Tile getTile(int col, int row) { |
|
if ((col >= 0) && (col < this.cols) && (row >= 0) && (row < this.rows)) { |
|
return this.tileset[row][col]; |
|
} |
|
else { |
|
return emptyTile; |
|
} |
|
} |
|
|
|
/** |
|
* Getter for level name |
|
* @return name of level |
|
*/ |
|
public String getName() { |
|
return this.name; |
|
} |
|
|
|
/** |
|
* Getter for cols |
|
* @return total number of columns (0-indexed) |
|
*/ |
|
public int getCols() { |
|
return this.cols; |
|
} |
|
|
|
/** |
|
* Getter for rows |
|
* @return total number of rows (0-indexed) |
|
*/ |
|
public int getRows() { |
|
return this.rows; |
|
} |
|
|
|
/** |
|
* Getter for startX |
|
* @return intended starting row/x-position for player |
|
*/ |
|
public int getStartX() { |
|
return this.startX; |
|
} |
|
|
|
/** |
|
* Getter for startY |
|
* @return intended starting col/y-position for player |
|
*/ |
|
public int getStartY() { |
|
return this.startY; |
|
} |
|
|
|
/** |
|
* Loads a level from CSV into this instance |
|
* @param filepath filepath to load from |
|
* @throws Exception if file cannot be found or level is invalid |
|
*/ |
|
public void loadLevel(String filepath) throws Exception { |
|
BufferedReader reader; |
|
|
|
//try to load properties file from filepath, and failing that try to load from jar |
|
if (new File(filepath).exists()) { |
|
reader = new BufferedReader(new FileReader(filepath)); |
|
} |
|
else { |
|
reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/" + filepath))); |
|
} |
|
|
|
String firstLine = reader.readLine(); |
|
if (firstLine == null) { |
|
reader.close(); |
|
throw new IOException("Invalid Level"); |
|
} |
|
else { |
|
String[] metaData = firstLine.split(","); |
|
this.name = metaData[0]; |
|
this.startX = Integer.parseInt(metaData[1]); |
|
this.startY = Integer.parseInt(metaData[2]); |
|
} |
|
|
|
|
|
List<List<Tile>> tileMatrix = new ArrayList<List<Tile>>(); |
|
|
|
String line; |
|
int row = 0; |
|
while((line = reader.readLine()) != null) { |
|
String[] lineItems = line.split(","); |
|
|
|
List<Tile> tileRow = new ArrayList<Tile>(); |
|
|
|
for (int col = 0; col < lineItems.length; col++) { |
|
int id = Integer.parseInt(lineItems[col]); |
|
Tile tile = new Tile(id, col, row, props); |
|
tileRow.add(tile); |
|
} |
|
|
|
tileMatrix.add(tileRow); |
|
|
|
row++; |
|
} |
|
|
|
reader.close(); |
|
|
|
this.rows = tileMatrix.size(); |
|
this.cols = tileMatrix.get(0).size(); |
|
this.tileset = new Tile[this.rows][this.cols]; |
|
|
|
for (row = 0; row < this.rows; row++) { |
|
for (int col = 0; col < this.cols; col++) { |
|
this.tileset[row][col] = tileMatrix.get(row).get(col); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Generates an empty level with a border |
|
* @param levelWidth width in tiles of generated level |
|
* @param levelHeight height in tiles of generated level |
|
* @param emptyTileId id of tile to place in interior of level |
|
* @param boundaryTileId of tile to place around the edge of the level |
|
*/ |
|
public void generateEmptyLevel(int levelWidth, int levelHeight, int emptyTileId, int boundaryTileId) { |
|
this.cols = levelWidth; |
|
this.rows = levelHeight; |
|
|
|
this.tileset = new Tile[this.rows][this.cols]; |
|
|
|
for (int row = 0; row < this.rows; row++) { |
|
for (int col = 0; col < this.cols; col++) { |
|
if ((row == 0) || (row == this.rows - 1) || (col == 0) || (col == this.cols - 1)) { |
|
this.tileset[row][col] = new Tile(boundaryTileId, col, row, props); |
|
} |
|
else { |
|
this.tileset[row][col] = new Tile(emptyTileId, col, row, props); |
|
} |
|
} |
|
} |
|
|
|
this.name = "Empty Level"; |
|
this.startX = this.cols / 2; |
|
this.startY = this.rows / 2; |
|
} |
|
|
|
/** |
|
* Generates a level consisting of random tiles with a border |
|
* @param levelWidth width in tiles of generated level |
|
* @param levelHeight height in tiles of generated level |
|
* @param minId minimum id of tiles to place in interior of level |
|
* @param maxId maximum id of tiles to place in interior of level |
|
* @param boundaryTileId of tile to place around the edge of the level |
|
* @param probability of selecting tile with ID minID % |
|
*/ |
|
public void generateRandomLevel(int levelWidth, int levelHeight, int minId, int maxId, int boundaryTileId, int p0) { |
|
this.cols = levelWidth; |
|
this.rows = levelHeight; |
|
|
|
this.tileset = new Tile[this.rows][this.cols]; |
|
|
|
for (int row = 0; row < this.rows; row++) { |
|
for (int col = 0; col < this.cols; col++) { |
|
if ((row == 0) || (row == this.rows - 1) || (col == 0) || (col == this.cols - 1)) { |
|
this.tileset[row][col] = new Tile(boundaryTileId, col, row, props); |
|
} |
|
else { |
|
int randomId = minId; |
|
int r1 = int(random(0, 101)); |
|
|
|
if (r1 > p0) { |
|
randomId = int(random(minId+1, maxId + 1)); |
|
} |
|
|
|
this.tileset[row][col] = new Tile(randomId, col, row, props); |
|
|
|
} |
|
} |
|
} |
|
|
|
this.name = "Randomly generated"; |
|
this.startX = this.cols / 2; |
|
this.startY = this.rows / 2; |
|
} |
|
|
|
@Override |
|
public String toString() { |
|
String str = ""; |
|
|
|
for (int row = 0; row < this.rows; row++) { |
|
for (int col = 0; col < this.cols; col++) { |
|
str += this.getTile(col, row) + ","; |
|
} |
|
str += "\n"; |
|
} |
|
|
|
return str; |
|
} |
|
}
|
|
|