Skip to content

Commit

Permalink
Split tile arrays into Chunks
Browse files Browse the repository at this point in the history
Removes tile and data arrays from Level, and disperses it among Chunks. These are managed in ChunkManager, used by Level and LevelGen in order to access Chunks and Tiles.
  • Loading branch information
zandgall committed Dec 5, 2024
1 parent 478c266 commit 67ad94d
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 176 deletions.
39 changes: 39 additions & 0 deletions src/client/java/minicraft/level/Chunk.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package minicraft.level;

import minicraft.level.tile.Tile;
import minicraft.level.tile.Tiles;

public class Chunk {
public static final int SIZE = 32;

public short[] data, tiles;

public Chunk() {
data = new short[SIZE * SIZE];
tiles = new short[SIZE * SIZE];
}

/**
* Returns a tile. Mods x and y to the range 0-SIZE as to never be out of bounds
*/
public Tile getTile(int x, int y) {
return Tiles.get(tiles[(x % SIZE) + (y % SIZE) * SIZE]);
}

/**
* Updates a tile. Mods x and y to the range 0-SIZE as to never be out of bounds
*/
public void setTile(int x, int y, Tile t, int dataVal) {
int index = (x % SIZE) + (y % SIZE) * SIZE;
tiles[index] = t.id;
data[index] = (short) dataVal;
}

public int getData(int x, int y) {
return data[(x % SIZE) + (y % SIZE) * SIZE] & 0xFFFF;
}

public void setData(int x, int y, int val) {
data[(x % SIZE) + (y % SIZE) * SIZE] = (short) val;
}
}
56 changes: 56 additions & 0 deletions src/client/java/minicraft/level/ChunkManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package minicraft.level;

import minicraft.level.tile.Tile;
import minicraft.level.tile.Tiles;

public class ChunkManager {
public Chunk[] chunks;
public int levelWidth, levelHeight;
private int widthInChunks, heightInChunks;

public ChunkManager(int levelWidth, int levelHeight) {
this.levelWidth = levelWidth;
this.levelHeight = levelHeight;
// Create enough chunks to cover the number of tiles provided
widthInChunks = (int)Math.ceil((double)levelWidth / Chunk.SIZE);
heightInChunks = (int)Math.ceil((double)levelHeight / Chunk.SIZE);
chunks = new Chunk[widthInChunks * heightInChunks];
for(int i = 0; i < widthInChunks * heightInChunks; i++)
chunks[i] = new Chunk();
}

/**
* Return the chunk in which the tileX and tileY land, or null if out of bounds
*/
public Chunk getChunk(int tileX, int tileY) {
if(tileX < 0 || tileY < 0 || tileX >= levelWidth || tileY >= levelHeight /* || (tileX + tileY * levelWidth / Chunk.SIZE) >= chunks.length */)
return null;
int cInd = tileX / Chunk.SIZE + (tileY / Chunk.SIZE) * widthInChunks;
return chunks[cInd];
}

public Tile getTile(int x, int y) {
Chunk c = getChunk(x, y);
if(c == null) return Tiles.get("connector tile");
return c.getTile(x, y);
}

public void setTile(int x, int y, Tile t, int dataVal) {
Chunk c = getChunk(x, y);
if(c == null) return;
c.setTile(x, y, t, dataVal);
}

public int getData(int x, int y) {
Chunk c = getChunk(x, y);
if(c == null) return 0;
return c.getData(x, y);
}

public void setData(int x, int y, int val) {
Chunk c = getChunk(x, y);
if(c == null) return;
c.setData(x, y, val);
}

}
38 changes: 14 additions & 24 deletions src/client/java/minicraft/level/Level.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ public static String getDepthString(int depth) {
public int w, h; // Width and height of the level
private final long seed; // The used seed that was used to generate the world

public short[] tiles; // An array of all the tiles in the world.
public short[] data; // An array of the data of the tiles in the world.
public ChunkManager chunkManager;

// public short[] tiles; // An array of all the tiles in the world.
// public short[] data; // An array of the data of the tiles in the world.

public final TreeTile.TreeType[] treeTypes; // An array of tree types

Expand Down Expand Up @@ -186,24 +188,18 @@ public Level(int w, int h, long seed, int level, Level parentLevel, boolean make
updateMobCap();

if (!makeWorld) {
int arrsize = w * h;
tiles = new short[arrsize];
data = new short[arrsize];
chunkManager = new ChunkManager(w, h);
return;
}

Logging.WORLD.debug("Making level " + level + "...");

maps = LevelGen.createAndValidateMap(w, h, level, seed);
if (maps == null) {
Logging.WORLD.error("Level generation: Returned maps array is null");
chunkManager = LevelGen.createAndValidateMap(w, h, level, seed);
if (chunkManager == null || chunkManager.chunks == null) {
Logging.WORLD.error("Level generation: Returned chunks array is null");
return;
}

tiles = maps[0]; // Assigns the tiles in the map
data = maps[1]; // Assigns the data of the tiles


if (level < 0)
generateSpawnerStructures();

Expand Down Expand Up @@ -559,8 +555,7 @@ private void sortAndRender(Screen screen, List<Entity> list) {
}

public Tile getTile(int x, int y) {
if (x < 0 || y < 0 || x >= w || y >= h /* || (x + y * w) >= tiles.length*/) return Tiles.get("connector tile");
return Tiles.get(tiles[x + y * w]);
return chunkManager.getTile(x, y);
}

/**
Expand All @@ -582,21 +577,16 @@ public void setTile(int x, int y, Tile t) {
}

public void setTile(int x, int y, Tile t, int dataVal) {
if (x < 0 || y < 0 || x >= w || y >= h) return;

tiles[x + y * w] = t.id;
data[x + y * w] = (short) dataVal;
t.onTileSet(this, x, y);
chunkManager.setTile(x, y, t, dataVal);
getTile(x, y).onTileSet(this, x, y);
}

public int getData(int x, int y) {
if (x < 0 || y < 0 || x >= w || y >= h) return 0;
return data[x + y * w] & 0xFFFF;
return chunkManager.getData(x, y);
}

public void setData(int x, int y, int val) {
if (x < 0 || y < 0 || x >= w || y >= h) return;
data[x + y * w] = (short) val;
chunkManager.setData(x, y, val);
}

public void add(Entity e) {
Expand Down Expand Up @@ -1193,7 +1183,7 @@ private void generateDungeonStructures() {
*/
public void regenerateBossRoom() {
if (depth == -4) {
Structure.dungeonBossRoom.draw(tiles, w / 2, h / 2, w); // Generating the boss room at the center.
Structure.dungeonBossRoom.draw(chunkManager, w / 2, h / 2); // Generating the boss room at the center.
for (int x = w / 2 - 4; x < w / 2 + 5; x++) { // Resetting tile data.
for (int y = h / 2 - 4; y < h / 2 + 5; y++) {
setData(x, y, 0);
Expand Down
Loading

0 comments on commit 67ad94d

Please sign in to comment.