Started making chunks asynchronous
This commit is contained in:
parent
0cbb9c8551
commit
877c5371a0
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<WorkerChunkTask> chunks_in = new Vector<WorkerChunkTask>();
|
||||
private AtomicReference<Vector<Chunk>> chunks_out = new AtomicReference<Vector<Chunk>>();
|
||||
|
||||
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<Chunk> getChunks() {
|
||||
return chunks_out.getAndSet(new Vector<Chunk>());
|
||||
}
|
||||
|
||||
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<Chunk>());
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<Entity> entities = new ArrayList<Entity>();
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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<Chunk> 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<Chunk.SIMULATION_DISTANCE;x++) {
|
||||
for(int y=-Chunk.SIMULATION_DISTANCE;y<Chunk.SIMULATION_DISTANCE;y++)
|
||||
for(int x=-Chunk.SIMULATION_DISTANCE;x<=Chunk.SIMULATION_DISTANCE;x++) {
|
||||
for(int y=-Chunk.SIMULATION_DISTANCE;y<=Chunk.SIMULATION_DISTANCE;y++)
|
||||
{
|
||||
// Get the chunk based on the player position
|
||||
int cx = MathHelpers.floor(ppos.x / 16) + x;
|
||||
|
|
@ -62,7 +73,7 @@ public class ChunkEventHandler implements IMainloopTask
|
|||
Vec2i c_pos = new Vec2i(cx, cy);
|
||||
|
||||
// Is this chunk not loaded
|
||||
if(!layer.chunkLoaded(c_pos))
|
||||
if(!layer.chunkLoaded(c_pos) && !Main.workerChunks.hasChunk(c_pos))
|
||||
{
|
||||
// Load the chunk
|
||||
layer.loadChunk(c_pos);
|
||||
|
|
|
|||
|
|
@ -230,6 +230,16 @@ public class Layer implements IBdfClassManager
|
|||
chunks.get(c_pos).spawnEntity(entity);
|
||||
}
|
||||
|
||||
public void loadChunks()
|
||||
{
|
||||
for(Chunk chunk : Main.workerChunks.getChunks())
|
||||
{
|
||||
Vec2i pos = chunk.c_pos;
|
||||
chunks.set(pos, chunk);
|
||||
chunk.clearDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadChunk(Vec2i pos)
|
||||
{
|
||||
// Has the chunk been saved for later
|
||||
|
|
@ -244,9 +254,7 @@ public class Layer implements IBdfClassManager
|
|||
|
||||
// Create and generate the chunk
|
||||
Chunk chunk = new Chunk(this, pos, rand);
|
||||
chunks.set(pos, chunk);
|
||||
layergen.generateChunk(chunk, this, new Random(cseed), pos);
|
||||
chunk.clearDirty();
|
||||
Main.workerChunks.generateChunk(layergen, this, chunk, new Random(cseed), pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@ public abstract class LayerGen implements IMap2D<Chunk>
|
|||
}
|
||||
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue