From 877c5371a01776928d6687a73f0049e93470b30b Mon Sep 17 00:00:00 2001 From: jsrobson10 Date: Wed, 26 Aug 2020 20:07:23 +1000 Subject: [PATCH] Started making chunks asynchronous --- src/projectzombie/Main.java | 6 ++ .../display/DisplayRenderUI.java | 2 +- .../entity/EntityEventHandler.java | 4 +- src/projectzombie/init/Models.java | 1 + src/projectzombie/menu/MenuLoadingWorld.java | 62 ++++++++++++++ src/projectzombie/menu/MenuSaves.java | 2 +- src/projectzombie/menu/MenuWorldNew.java | 2 +- src/projectzombie/worker/WorkerChunkTask.java | 25 ++++++ src/projectzombie/worker/WorkerChunks.java | 80 +++++++++++++++++++ src/projectzombie/world/World.java | 2 + src/projectzombie/world/chunk/Chunk.java | 37 +++++++-- .../world/chunk/ChunkEventHandler.java | 27 +++++-- src/projectzombie/world/layer/Layer.java | 14 +++- .../world/layer/layergen/LayerGen.java | 4 +- .../layer/layergen/LayerGenBossArena.java | 12 +-- .../world/layer/layergen/LayerGenCaves.java | 5 +- .../world/layer/layergen/LayerGenEarth.java | 8 +- .../layer/layergen/LayerGenLavaCaves.java | 12 +-- 18 files changed, 251 insertions(+), 54 deletions(-) create mode 100644 src/projectzombie/menu/MenuLoadingWorld.java create mode 100644 src/projectzombie/worker/WorkerChunkTask.java create mode 100644 src/projectzombie/worker/WorkerChunks.java diff --git a/src/projectzombie/Main.java b/src/projectzombie/Main.java index e8e47ce..0446c03 100755 --- a/src/projectzombie/Main.java +++ b/src/projectzombie/Main.java @@ -33,6 +33,7 @@ import projectzombie.settings.Environment; import projectzombie.settings.Settings; import projectzombie.time.GameTimer; import projectzombie.time.NoSleep; +import projectzombie.worker.WorkerChunks; import projectzombie.worker.WorkerLighting; import projectzombie.world.World; import projectzombie.world.chunk.ChunkEventHandler; @@ -48,6 +49,7 @@ public class Main public static Random rand = new Random(); public static Menu menu; public static WorkerLighting workerLighting; + public static WorkerChunks workerChunks; public static boolean game_paused = false; public static int tickrate = 10; @@ -57,7 +59,10 @@ public class Main { clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + workerChunks = new WorkerChunks(); workerLighting = new WorkerLighting(); + + workerChunks.start(); workerLighting.start(); MathHelpers.init(); @@ -113,6 +118,7 @@ public class Main { // Kill the worker thread workerLighting.kill(); + workerChunks.kill(); } } } diff --git a/src/projectzombie/display/DisplayRenderUI.java b/src/projectzombie/display/DisplayRenderUI.java index c95403d..357c132 100755 --- a/src/projectzombie/display/DisplayRenderUI.java +++ b/src/projectzombie/display/DisplayRenderUI.java @@ -171,7 +171,7 @@ public class DisplayRenderUI GL33.glDisable(GL33.GL_DEPTH_TEST); - if(Main.menu.doGameRender && Main.menu.showIngameGUI) { + if(Main.menu.doGameRender && Main.menu.showIngameGUI && ChunkEventHandler.loaded) { renderGameGui(); } diff --git a/src/projectzombie/entity/EntityEventHandler.java b/src/projectzombie/entity/EntityEventHandler.java index ea1c76c..c199795 100755 --- a/src/projectzombie/entity/EntityEventHandler.java +++ b/src/projectzombie/entity/EntityEventHandler.java @@ -2,6 +2,7 @@ package projectzombie.entity; import mainloop.task.IMainloopTask; import projectzombie.Main; +import projectzombie.world.chunk.ChunkEventHandler; public class EntityEventHandler implements IMainloopTask { @@ -21,7 +22,8 @@ public class EntityEventHandler implements IMainloopTask public void MainLoopUpdate() { Main.menu.update(); - if(!Main.menu.doGameloop) { + + if(!Main.menu.doGameloop || !ChunkEventHandler.loaded) { return; } diff --git a/src/projectzombie/init/Models.java b/src/projectzombie/init/Models.java index c9c4a98..9b801ff 100755 --- a/src/projectzombie/init/Models.java +++ b/src/projectzombie/init/Models.java @@ -134,6 +134,7 @@ public class Models public static final ModelGui UI_WATER = new ModelGui(Resources.ATLAS.get("/gui/water.png"), new Vec2d(0.75, 0.75)); public static final ModelGui UI_ITEM_HOVER = new ModelGui(Resources.ATLAS.get("/gui/pixel_black.png")).setOpacity(0.25); public static final ModelGui UI_TEXT_BG = new ModelGui(Resources.ATLAS.get("/gui/pixel_white.png")).setColor(0.5f, 0.5f, 0.5f); + public static final ModelGui UI_STONE_BG = new ModelGui(Resources.ATLAS.get("/tile/stone.png")); public static final ModelItem UI_SLOT_ARMOR_HELMET = new ModelItem(Resources.ATLAS.get("/gui/slot_armor_helmet.png")); public static final ModelItem UI_SLOT_ARMOR_CHEST = new ModelItem(Resources.ATLAS.get("/gui/slot_armor_chest.png")); diff --git a/src/projectzombie/menu/MenuLoadingWorld.java b/src/projectzombie/menu/MenuLoadingWorld.java new file mode 100644 index 0000000..aeea13f --- /dev/null +++ b/src/projectzombie/menu/MenuLoadingWorld.java @@ -0,0 +1,62 @@ +package projectzombie.menu; + +import gl_engine.matrix.Matrix4; +import gl_engine.vec.Vec3d; +import projectzombie.Main; +import projectzombie.init.Models; +import projectzombie.input.types.InputGUI; +import projectzombie.menu.gui.GUI; +import projectzombie.menu.gui.GUIAlignment; +import projectzombie.menu.gui.GUILabel; +import projectzombie.util.gl.GlHelpers; +import projectzombie.world.chunk.ChunkEventHandler; + +public class MenuLoadingWorld extends Menu +{ + private GUI gui; + + public MenuLoadingWorld() + { + doGameloop = true; + doGameRender = true; + keepMouse = false; + showIngameGUI = false; + + GUILabel label = new GUILabel(); + label.setText("Loading world..."); + label.setAlign(GUIAlignment.CENTRE); + + gui = new GUI(); + input = new InputGUI(gui); + + gui.add(label); + } + + @Override + public void render() + { + double a = GlHelpers.getAspectRatio(); + + for(int x = 0; x < 16; x ++) { + for(int y = 0; y < 16; y ++) + { + Models.UI_STONE_BG.setModel(Matrix4.multiply( + Matrix4.scale(new Vec3d(1.25 * a, 1.25 * a, 1)), + Matrix4.translate(new Vec3d(-10 * a + 1.25 * a * x, -10 * a + 1.25 * a * y, 0)))); + Models.UI_STONE_BG.render(); + } + } + + gui.render(); + } + + @Override + public void update() + { + super.update(); + + if(ChunkEventHandler.loaded) { + Main.menu = new MenuGame(); + } + } +} diff --git a/src/projectzombie/menu/MenuSaves.java b/src/projectzombie/menu/MenuSaves.java index eacff0f..cf88646 100644 --- a/src/projectzombie/menu/MenuSaves.java +++ b/src/projectzombie/menu/MenuSaves.java @@ -109,7 +109,7 @@ public class MenuSaves extends Menu reader.saveDatabase(); Main.world = new World(saves.get(index).filename); - Main.menu = new MenuGame(); + Main.menu = new MenuLoadingWorld(); } private void deleteSave(int index) diff --git a/src/projectzombie/menu/MenuWorldNew.java b/src/projectzombie/menu/MenuWorldNew.java index 1751334..dfe1181 100644 --- a/src/projectzombie/menu/MenuWorldNew.java +++ b/src/projectzombie/menu/MenuWorldNew.java @@ -158,7 +158,7 @@ public class MenuWorldNew extends Menu reader.saveDatabase(); World.createWorld(path_new, seed); - Main.menu = new MenuGame(); + Main.menu = new MenuLoadingWorld(); } @Override diff --git a/src/projectzombie/worker/WorkerChunkTask.java b/src/projectzombie/worker/WorkerChunkTask.java new file mode 100644 index 0000000..2cb05dc --- /dev/null +++ b/src/projectzombie/worker/WorkerChunkTask.java @@ -0,0 +1,25 @@ +package projectzombie.worker; + +import java.util.Random; + +import gl_engine.vec.Vec2i; +import projectzombie.world.chunk.Chunk; +import projectzombie.world.layer.Layer; +import projectzombie.world.layer.layergen.LayerGen; + +class WorkerChunkTask +{ + Chunk chunk; + LayerGen layergen; + Layer layer; + Random rand; + Vec2i pos; + + public WorkerChunkTask(LayerGen layergen, Layer layer, Chunk chunk, Random rand, Vec2i pos) { + this.chunk = chunk; + this.layergen = layergen; + this.layer = layer; + this.rand = rand; + this.pos = pos; + } +} diff --git a/src/projectzombie/worker/WorkerChunks.java b/src/projectzombie/worker/WorkerChunks.java new file mode 100644 index 0000000..2cae30b --- /dev/null +++ b/src/projectzombie/worker/WorkerChunks.java @@ -0,0 +1,80 @@ +package projectzombie.worker; + +import java.util.Random; +import java.util.Vector; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import gl_engine.vec.Vec2i; +import projectzombie.world.chunk.Chunk; +import projectzombie.world.layer.Layer; +import projectzombie.world.layer.layergen.LayerGen; + +public class WorkerChunks extends Thread +{ + private boolean running = false; + private Vector chunks_in = new Vector(); + private AtomicReference> chunks_out = new AtomicReference>(); + + public void generateChunk(LayerGen layergen, Layer layer, Chunk chunk, Random rand, Vec2i pos) { + chunks_in.add(new WorkerChunkTask(layergen, layer, chunk, rand, pos)); + } + + public Vector getChunks() { + return chunks_out.getAndSet(new Vector()); + } + + public boolean hasChunk(Vec2i cpos) + { + boolean has[] = {false}; + + chunks_in.forEach(c -> { + if(c.pos.equal(cpos)) { + has[0] = true; + } + }); + + return has[0]; + } + + public WorkerChunks() { + chunks_out.set(new Vector()); + } + + @Override + public void run() + { + running = true; + + try + { + while(running) + { + if(chunks_in.size() == 0) { + Thread.sleep(1); + continue; + } + + WorkerChunkTask ct = chunks_in.remove(0); + + Chunk chunk = ct.chunk; + LayerGen layergen = ct.layergen; + Layer layer = ct.layer; + Random rand = ct.rand; + Vec2i pos = ct.pos; + + layergen.generateChunk(chunk, layer, rand, pos); + + chunks_out.get().add(chunk); + } + } + + catch(InterruptedException e) { + e.printStackTrace(); + } + } + + public void kill() { + running = false; + } +} diff --git a/src/projectzombie/world/World.java b/src/projectzombie/world/World.java index 353d12a..6480894 100755 --- a/src/projectzombie/world/World.java +++ b/src/projectzombie/world/World.java @@ -22,6 +22,7 @@ import projectzombie.display.bossbar.BossBars; import projectzombie.entity.player.EntityPlayer; import projectzombie.init.LayerGenerators; import projectzombie.init.Layers; +import projectzombie.menu.MenuLoadingWorld; import projectzombie.model.Model; import projectzombie.time.GameTimer; import projectzombie.world.chunk.ChunkEventHandler; @@ -197,6 +198,7 @@ public class World implements IBdfClassManager public void setLayer(int id) { + Main.menu = new MenuLoadingWorld(); ChunkEventHandler.loaded = false; DisplayLighting.clearLighting(); DisplayLighting.setDirty(); diff --git a/src/projectzombie/world/chunk/Chunk.java b/src/projectzombie/world/chunk/Chunk.java index b95b90e..345d30d 100755 --- a/src/projectzombie/world/chunk/Chunk.java +++ b/src/projectzombie/world/chunk/Chunk.java @@ -51,6 +51,8 @@ public class Chunk implements IBdfClassManager private byte tiles_front_meta[] = new byte[CHUNK_INDEX]; private byte tiles_back_meta[] = new byte[CHUNK_INDEX]; private byte tiles_lighting[] = new byte[CHUNK_INDEX]; + private byte tiles_temperature[] = new byte[CHUNK_INDEX]; + private byte tiles_humidity[] = new byte[CHUNK_INDEX]; public ArrayList entities = new ArrayList(); private Layer layer; public Vec2i c_pos; @@ -174,11 +176,6 @@ public class Chunk implements IBdfClassManager // Make all these tiles void tiles_back[i] = Tiles.VOID; tiles_front[i] = Tiles.VOID; - tiles_back_meta[i] = 0; - tiles_front_meta[i] = 0; - - // Set the light level to 0 - tiles_lighting[i] = 0; } } @@ -508,6 +505,36 @@ public class Chunk implements IBdfClassManager return null; } + public void setTemperature(double v, Vec2i pos) + { + // Get the id + Vec2i cpos = new Vec2i(0, 0); + cpos.x = MathHelpers.mod(pos.x, CHUNK_SIZE.mx); + cpos.y = MathHelpers.mod(pos.y, CHUNK_SIZE.my); + int id = cpos.getId(CHUNK_SIZE); + + setTemperature(v, id); + } + + public void setTemperature(double v, int id) { + tiles_temperature[id] = (byte)(v * 127); + } + + public void setHumidity(double v, Vec2i pos) + { + // Get the id + Vec2i cpos = new Vec2i(0, 0); + cpos.x = MathHelpers.mod(pos.x, CHUNK_SIZE.mx); + cpos.y = MathHelpers.mod(pos.y, CHUNK_SIZE.my); + int id = cpos.getId(CHUNK_SIZE); + + setHumidity(v, id); + } + + public void setHumidity(double v, int id) { + tiles_humidity[id] = (byte)(v * 127); + } + public void setBackTile(TileState tile, Vec2i pos) { // Get the id diff --git a/src/projectzombie/world/chunk/ChunkEventHandler.java b/src/projectzombie/world/chunk/ChunkEventHandler.java index cb911a5..ca1ca18 100755 --- a/src/projectzombie/world/chunk/ChunkEventHandler.java +++ b/src/projectzombie/world/chunk/ChunkEventHandler.java @@ -30,7 +30,8 @@ public class ChunkEventHandler implements IMainloopTask // Get the layer Vec3d ppos = Main.player.getPos(); Layer layer = Main.world.getLayer(); - loaded = true; + + int loaded_count = 0; // Loop over all the chunks in this layer for(Map2DElement ce : layer.chunks) @@ -41,20 +42,30 @@ public class ChunkEventHandler implements IMainloopTask if( // Is this chunk beyond the simulation distance - px > ce.pos.x + Chunk.SIMULATION_DISTANCE || - px < ce.pos.x - Chunk.SIMULATION_DISTANCE || - py > ce.pos.y + Chunk.SIMULATION_DISTANCE || - py < ce.pos.y - Chunk.SIMULATION_DISTANCE + px > ce.pos.x + Chunk.SIMULATION_DISTANCE + 1 || + px < ce.pos.x - Chunk.SIMULATION_DISTANCE - 1 || + py > ce.pos.y + Chunk.SIMULATION_DISTANCE + 1 || + py < ce.pos.y - Chunk.SIMULATION_DISTANCE - 1 ) { // Unload the chunk layer.unloadChunk(ce.pos); ce.o.free(); } + + else { + loaded_count += 1; + } } + if(loaded_count >= 4 * Chunk.SIMULATION_DISTANCE * (Chunk.SIMULATION_DISTANCE + 1) + 1) { + loaded = true; + } + + layer.loadChunks(); + // Loop over the simulation distance - for(int x=-Chunk.SIMULATION_DISTANCE;x } public abstract void generateChunk(Chunk chunk, Layer layer, Random rand, Vec2i pos); - public abstract double getTemperatureStatic(Layer layer, Vec2d pos); - public abstract double getTemperatureDynamic(Layer layer, Vec2d pos); - public abstract double getHumidity(Layer layer, Vec2d pos); + public abstract double getTemperature(Layer layer, Vec2d pos); public abstract void spawnEntities(Layer layer, Random rand); public abstract TileState getTileDestroyed(Layer layer, Vec2i pos); public abstract ColorRange getLightLevel(); diff --git a/src/projectzombie/world/layer/layergen/LayerGenBossArena.java b/src/projectzombie/world/layer/layergen/LayerGenBossArena.java index 2beec19..41a6eda 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenBossArena.java +++ b/src/projectzombie/world/layer/layergen/LayerGenBossArena.java @@ -109,18 +109,8 @@ public class LayerGenBossArena extends LayerGen implements LayerGenRememberPlaye } @Override - public double getTemperatureStatic(Layer layer, Vec2d pos) { + public double getTemperature(Layer layer, Vec2d pos) { return 0.8; } - - @Override - public double getTemperatureDynamic(Layer layer, Vec2d pos) { - return 0.8; - } - - @Override - public double getHumidity(Layer layer, Vec2d pos) { - return 0; - } } diff --git a/src/projectzombie/world/layer/layergen/LayerGenCaves.java b/src/projectzombie/world/layer/layergen/LayerGenCaves.java index 02299e6..c9e0817 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenCaves.java +++ b/src/projectzombie/world/layer/layergen/LayerGenCaves.java @@ -22,8 +22,6 @@ import projectzombie.world.layer.Layer; public class LayerGenCaves extends LayerGen { - - @Override public double getTemperatureStatic(Layer layer, Vec2d pos) { // Get the noise generator @@ -32,11 +30,10 @@ public class LayerGenCaves extends LayerGen } @Override - public double getTemperatureDynamic(Layer layer, Vec2d pos) { + public double getTemperature(Layer layer, Vec2d pos) { return getTemperatureStatic(layer, pos); } - @Override public double getHumidity(Layer layer, Vec2d pos) { // Get the noise generator diff --git a/src/projectzombie/world/layer/layergen/LayerGenEarth.java b/src/projectzombie/world/layer/layergen/LayerGenEarth.java index 2fbaca2..f765c73 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenEarth.java +++ b/src/projectzombie/world/layer/layergen/LayerGenEarth.java @@ -30,7 +30,6 @@ public class LayerGenEarth extends LayerGen layer.noise_gens[3].eval(pos.x / 64.0, pos.y / 64.0, t) * 0.02); } - @Override public double getTemperatureStatic(Layer layer, Vec2d pos) { // Get the noise generator @@ -39,7 +38,7 @@ public class LayerGenEarth extends LayerGen } @Override - public double getTemperatureDynamic(Layer layer, Vec2d pos) + public double getTemperature(Layer layer, Vec2d pos) { // Get the noise generator double humidity = getHumidity(layer, pos); @@ -50,7 +49,6 @@ public class LayerGenEarth extends LayerGen return MathHelpers.map(terrain_noise.eval(pos.x / World.BIOME_SIZE, pos.y / World.BIOME_SIZE), -1, 1, 0, 0.5 + light); } - @Override public double getHumidity(Layer layer, Vec2d pos) { // Get the noise generator @@ -67,8 +65,8 @@ public class LayerGenEarth extends LayerGen layer.noise_gens = new NoiseGenerator[] { - new NoiseGeneratorSimplex(rand, 64), // Temperature - new NoiseGeneratorSimplex(rand, 64), // Humidity + new NoiseGeneratorSimplex(rand, 4), // Temperature + new NoiseGeneratorSimplex(rand, 4), // Humidity new NoiseGeneratorSimplex(lrand), // Wind new NoiseGeneratorSimplex(lrand), // Wind diff --git a/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java b/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java index b326de5..07e5449 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java +++ b/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java @@ -178,18 +178,8 @@ public class LayerGenLavaCaves extends LayerGen } @Override - public double getTemperatureStatic(Layer layer, Vec2d pos) { + public double getTemperature(Layer layer, Vec2d pos) { return MathHelpers.map(layer.noise_gens[0].eval(pos.x / 128, pos.y / 128), -1, 1, 0.8, 1); } - - @Override - public double getTemperatureDynamic(Layer layer, Vec2d pos) { - return getTemperatureStatic(layer, pos); - } - - @Override - public double getHumidity(Layer layer, Vec2d pos) { - return 0; - } }