Redid the games lighting and made it asyncronous.

This commit is contained in:
josua 2020-03-13 22:01:28 +11:00
parent 5aa5a6a989
commit d24f9296a5
40 changed files with 718 additions and 188 deletions

Binary file not shown.

Binary file not shown.

View File

@ -17,12 +17,12 @@ import projectzombie.init.Textures;
import projectzombie.input.JoystickCallback; import projectzombie.input.JoystickCallback;
import projectzombie.input.KeyCallback; import projectzombie.input.KeyCallback;
import projectzombie.mainloop.MainloopEventHandler; import projectzombie.mainloop.MainloopEventHandler;
import projectzombie.mainloop.MainloopHelpers;
import projectzombie.menu.Menu; import projectzombie.menu.Menu;
import projectzombie.menu.MenuMain; import projectzombie.menu.MenuMain;
import projectzombie.settings.Cheats; import projectzombie.settings.Cheats;
import projectzombie.settings.Environment; import projectzombie.settings.Environment;
import projectzombie.settings.Settings; import projectzombie.settings.Settings;
import projectzombie.tiles.LightLevelNoise;
import projectzombie.time.GameTimer; import projectzombie.time.GameTimer;
import projectzombie.time.NoSleep; import projectzombie.time.NoSleep;
import projectzombie.world.World; import projectzombie.world.World;
@ -73,10 +73,10 @@ public class Main
mainloop.register(ChunkEventHandler.CHUNK_EVENT_HANDLER); mainloop.register(ChunkEventHandler.CHUNK_EVENT_HANDLER);
mainloop.register(DisplayStatsEventHandler.DISPLAY_STATS_EVENT_HANDLER); mainloop.register(DisplayStatsEventHandler.DISPLAY_STATS_EVENT_HANDLER);
mainloop.register(JoystickCallback.JOYSTICK_CALLBACK); mainloop.register(JoystickCallback.JOYSTICK_CALLBACK);
mainloop.register(new LightLevelNoise());
mainloop.register(new GameTimer()); mainloop.register(new GameTimer());
mainloop.register(new KeyCallback()); mainloop.register(new KeyCallback());
mainloop.register(new NoSleep()); mainloop.register(new NoSleep());
mainloop.register(new MainloopHelpers());
// Create the display // Create the display
window = new DisplayWindow("Project Zombie"); window = new DisplayWindow("Project Zombie");

View File

@ -16,7 +16,7 @@ import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryStack;
import projectzombie.Main; import projectzombie.Main;
import projectzombie.display.lighting.LightingManager; import projectzombie.display.lighting.DynamicLighting;
import projectzombie.display.transparent.TransparentObjects; import projectzombie.display.transparent.TransparentObjects;
import projectzombie.entity.player.EntityPlayer; import projectzombie.entity.player.EntityPlayer;
import projectzombie.init.Textures; import projectzombie.init.Textures;
@ -95,7 +95,7 @@ public class DisplayRender
GlHelpers.translate3(-camera.pos.x, -camera.pos.y, -camera.pos.z); GlHelpers.translate3(-camera.pos.x, -camera.pos.y, -camera.pos.z);
// Process all the light sources // Process all the light sources
LightingManager.update(); DynamicLighting.update();
// Render the world and the player // Render the world and the player
Main.world.render(camera); Main.world.render(camera);

View File

@ -0,0 +1,48 @@
package projectzombie.display.lighting;
import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.map.IMap2D;
import projectzombie.util.math.map.Map2D;
import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i;
import projectzombie.world.chunk.Chunk;
public class ChunkLightingCollection implements IMap2D<ChunkLightingTemp>
{
private Map2D<ChunkLightingTemp> chunks = new Map2D<ChunkLightingTemp>(this);
public final int RENDER_DISTANCE = Chunk.RENDER_DISTANCE;
@Override
public ChunkLightingTemp getEmpty(Vec2i pos) {
return new ChunkLightingTemp();
}
private Vec2i getChunkPosFromPos(Vec2i pos) {
return this.getChunkPosFromPos(new Vec2d(pos.x, pos.y));
}
private Vec2i getChunkPosFromPos(Vec2d pos) {
return new Vec2i(
MathHelpers.floor(pos.x / (double)Chunk.CHUNK_SIZE.mx),
MathHelpers.floor(pos.y / (double)Chunk.CHUNK_SIZE.my));
}
public ChunkLightingTemp getChunkwCPos(Vec2i cpos) {
if(!chunks.contains(cpos)) {
ChunkLightingTemp chunk = new ChunkLightingTemp();
chunks.set(cpos, chunk);
return chunk;
} else {
return chunks.get(cpos);
}
}
public ChunkLightingTemp getChunk(Vec2i pos) {
return getChunkwCPos(getChunkPosFromPos(pos));
}
public ChunkLightingTemp getChunk(Vec2d pos) {
return getChunkwCPos(getChunkPosFromPos(pos));
}
}

View File

@ -0,0 +1,49 @@
package projectzombie.display.lighting;
import projectzombie.util.math.vec.Vec2i;
import projectzombie.world.chunk.Chunk;
public class ChunkLightingTemp
{
private byte lighting_daylight[] = new byte[Chunk.CHUNK_INDEX];
private byte lighting_light[] = new byte[Chunk.CHUNK_INDEX];
public ChunkLightingTemp() {
for(int i=0;i<Chunk.CHUNK_INDEX;i++) {
lighting_daylight[i] = 0;
lighting_light[i] = 0;
}
}
public void setDaylightLevel(double v, Vec2i pos) {
setDaylightLevel(v, pos.getId(Chunk.CHUNK_SIZE));
}
public void setDaylightLevel(double v, int id) {
lighting_daylight[id] = (byte)(v * Byte.MAX_VALUE);
}
public void setLightLevel(double v, Vec2i pos) {
setLightLevel(v, pos.getId(Chunk.CHUNK_SIZE));
}
public void setLightLevel(double v, int id) {
lighting_light[id] = (byte)(v * Byte.MAX_VALUE);
}
public double getDaylightLevel(Vec2i pos) {
return getDaylightLevel(pos.getId(Chunk.CHUNK_SIZE));
}
public double getDaylightLevel(int id) {
return lighting_daylight[id] / (double)Byte.MAX_VALUE;
}
public double getLightLevel(Vec2i pos) {
return getLightLevel(pos.getId(Chunk.CHUNK_SIZE));
}
public double getLightLevel(int id) {
return lighting_light[id] / (double)Byte.MAX_VALUE;
}
}

View File

@ -11,7 +11,7 @@ import projectzombie.world.chunk.Chunk;
import projectzombie.world.chunk.ChunkEventHandler; import projectzombie.world.chunk.ChunkEventHandler;
import projectzombie.world.layer.Layer; import projectzombie.world.layer.Layer;
public class LightingManager public class DynamicLighting
{ {
public static int lightingMode = 0; public static int lightingMode = 0;
@ -20,10 +20,9 @@ public class LightingManager
if(!ChunkEventHandler.loaded) return; if(!ChunkEventHandler.loaded) return;
int r = Camera.camera.renderDistance; int r = Camera.camera.renderDistance;
Layer layer = Main.world.getLayer(); Layer layer = Main.world.getLayer();
double light_clear = layer.layergen.getLightLevel();
EntityPlayer player = Main.player; EntityPlayer player = Main.player;
// Clear every light source // Copy every light source from the tile light sources
for(int cx=-r;cx<=r;cx++) { for(int cx=-r;cx<=r;cx++) {
for(int cy=-r;cy<=r;cy++) for(int cy=-r;cy<=r;cy++)
{ {
@ -36,14 +35,15 @@ public class LightingManager
for(int x=0;x<16;x++) { for(int x=0;x<16;x++) {
for(int y=0;y<16;y++) for(int y=0;y<16;y++)
{ {
// Clear the tiles light // Reset the tiles light
chunk.setLightLevel(light_clear, new Vec2i(x, y)); int id = new Vec2i(x, y).getId(Chunk.CHUNK_SIZE);
chunk.setDynamicLightLevel(chunk.getLightLevel(id), id);
} }
} }
} }
} }
// Loop over every entity and every block to scan for light sources // Loop over every entity to scan for light sources
for(int cx=-r;cx<=r;cx++) { for(int cx=-r;cx<=r;cx++) {
for(int cy=-r;cy<=r;cy++) for(int cy=-r;cy<=r;cy++)
{ {
@ -63,36 +63,7 @@ public class LightingManager
addLightToTiles(layer, new Vec2i( addLightToTiles(layer, new Vec2i(
MathHelpers.floor(e.pos.x), MathHelpers.floor(e.pos.x),
MathHelpers.floor(e.pos.y)), MathHelpers.floor(e.pos.y)),
e.getLightLevel(), true); e.getLightLevel());
}
}
// Create all the tile light sources
for(int x=0;x<16;x++) {
for(int y=0;y<16;y++)
{
// Get the tile position
Vec2i tpos = new Vec2i(x + cpos.x * 16, y + cpos.y * 16);
int tid = tpos.getId(Chunk.CHUNK_SIZE);
// Get the front and back tiles
TileState fts = chunk.getFrontTile(tid);
TileState bts = chunk.getBackTile(tid);
// Do any of these emit light
if(fts.tile.emitsLight || bts.tile.emitsLight)
{
// Calculate the light given off by the tile
double light_tile = chunk.getLightLevel(tid);
double light_tile_old = light_tile;
light_tile = MathHelpers.biggest(light_tile, fts.tile.getLightLevel(fts, tpos));
light_tile = MathHelpers.biggest(light_tile, fts.tile.getLightLevel(bts, tpos));
// Has the light level changed; add light to this tile
if(light_tile != light_tile_old) {
addLightToTiles(layer, tpos, light_tile, true);
}
}
} }
} }
} }
@ -103,11 +74,11 @@ public class LightingManager
addLightToTiles(layer, new Vec2i( addLightToTiles(layer, new Vec2i(
MathHelpers.floor(player.pos.x), MathHelpers.floor(player.pos.x),
MathHelpers.floor(player.pos.y)), MathHelpers.floor(player.pos.y)),
player.getLightLevel(), true); player.getLightLevel());
} }
} }
private static void addLightToTiles(Layer layer, Vec2i lpos, double light, boolean ignoreDissipation) private static void addLightToTiles(Layer layer, Vec2i lpos, double light)
{ {
if( if(
MathHelpers.floor(lpos.squareDistance(new Vec2i( MathHelpers.floor(lpos.squareDistance(new Vec2i(
@ -124,25 +95,19 @@ public class LightingManager
Chunk chunk = layer.getChunk(lpos); Chunk chunk = layer.getChunk(lpos);
TileState bt = chunk.getBackTile(lid); TileState bt = chunk.getBackTile(lid);
TileState ft = chunk.getFrontTile(lid); TileState ft = chunk.getFrontTile(lid);
double light_dissipation = 0;
if(!ignoreDissipation) { double light_dissipation = MathHelpers.biggest(
light_dissipation = MathHelpers.biggest(
bt.tile.getLightDissipation(bt), bt.tile.getLightDissipation(bt),
ft.tile.getLightDissipation(ft)); ft.tile.getLightDissipation(ft));
}
// Calculate the light level // Calculate the light level
double light_tile = chunk.getLightLevel(lid); double light_tile = chunk.getDynamicLightLevel(lid);
if(light <= light_tile) { if(light <= light_tile) {
return; return;
} }
// Merge the light and the light tile values // Merge the light and the light tile values
chunk.setLightLevel(light, lid); chunk.setDynamicLightLevel(light, lid);
// Set the light dissipation
light = light - light_dissipation;
// Get all the adjacent positions of the light tiles to flow onto // Get all the adjacent positions of the light tiles to flow onto
Vec2i positions[] = { Vec2i positions[] = {
@ -154,7 +119,7 @@ public class LightingManager
// Add the light to all the adjacent positions // Add the light to all the adjacent positions
for(Vec2i position : positions) { for(Vec2i position : positions) {
addLightToTiles(layer, position, light, false); addLightToTiles(layer, position, light - light_dissipation);
} }
} }
} }

View File

@ -0,0 +1,210 @@
package projectzombie.display.lighting;
import mainloop.task.IMainloopTask;
import projectzombie.Main;
import projectzombie.display.Camera;
import projectzombie.entity.player.EntityPlayer;
import projectzombie.mainloop.MainloopHelpers;
import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.TileState;
import projectzombie.util.math.range.Range4i;
import projectzombie.util.math.vec.Vec2i;
import projectzombie.util.math.vec.Vec4i;
import projectzombie.world.chunk.Chunk;
import projectzombie.world.chunk.ChunkEventHandler;
import projectzombie.world.layer.Layer;
public class TileLighting implements IMainloopTask
{
public static boolean lighting_dirty = false;
public static void update()
{
if(!ChunkEventHandler.loaded) return;
Layer layer = Main.world.getLayer();
EntityPlayer player = Main.player;
boolean dirty = false;
for(int cx=-Chunk.RENDER_DISTANCE;cx<=Chunk.RENDER_DISTANCE;cx++) {
for(int cy=-Chunk.RENDER_DISTANCE;cy<=Chunk.RENDER_DISTANCE;cy++) {
Vec2i cpos = new Vec2i(
cx + MathHelpers.floor(player.pos.x / 16),
cy + MathHelpers.floor(player.pos.y / 16));
Chunk chunk = layer.chunks.get(cpos);
if(chunk.light_dirty) {
chunk.light_dirty = false;
dirty = true;
}
}
}
if(!dirty) {
return;
}
// Create the chunk collection
ChunkLightingCollection chunks = new ChunkLightingCollection();
Range4i range = new Range4i(
Chunk.RENDER_DISTANCE*3,
Chunk.RENDER_DISTANCE*3,
Chunk.CHUNK_SIZE.mx,
Chunk.CHUNK_SIZE.my);
// Do daylight and tile light calculations
MainloopHelpers.loopAsync(0, range.maxValue(),
(it) -> {
Vec4i upto = Vec4i.fromId(range, it);
Vec2i cpos = new Vec2i(
upto.x + MathHelpers.floor(player.pos.x / 16) - chunks.RENDER_DISTANCE,
upto.y + MathHelpers.floor(player.pos.y / 16) - chunks.RENDER_DISTANCE);
Chunk chunk = layer.chunks.get(cpos);
Vec2i tpos = new Vec2i(cpos.x * 16 + upto.z, cpos.y * 16 + upto.m);
int tid = tpos.getId(Chunk.CHUNK_SIZE);
TileState tile_f = chunk.getFrontTile(tid);
TileState tile_b = chunk.getBackTile(tid);
if(tile_f.tile.passNaturalLight && tile_b.tile.passNaturalLight) {
addLightToTiles(chunks, layer, tpos, 0, 1, true);
}
if(tile_f.tile.emitsLight || tile_b.tile.emitsLight) {
addLightToTiles(chunks, layer, tpos, 0, MathHelpers.biggest(
tile_f.tile.getLightLevel(tile_f, tpos),
tile_b.tile.getLightLevel(tile_b, tpos)
), false);
}
},
() -> {
for(int cx=-chunks.RENDER_DISTANCE;cx<=chunks.RENDER_DISTANCE;cx++) {
for(int cy=-chunks.RENDER_DISTANCE;cy<=chunks.RENDER_DISTANCE;cy++)
{
Vec2i cpos = new Vec2i(
cx + MathHelpers.floor(player.pos.x / 16),
cy + MathHelpers.floor(player.pos.y / 16));
Chunk chunk = layer.chunks.get(cpos);
ChunkLightingTemp chunk_t = chunks.getChunkwCPos(cpos);
for(int x=0;x<16;x++) {
for(int y=0;y<16;y++)
{
Vec2i tpos = new Vec2i(cpos.x * 16 + x, cpos.y * 16 + y);
int tid = tpos.getId(Chunk.CHUNK_SIZE);
chunk.setDaylightLevel(chunk_t.getDaylightLevel(tid), tid);
chunk.setLightLevel(chunk_t.getLightLevel(tid), tid);
}
}
}
}
});
}
private static void addLightToTiles(
ChunkLightingCollection chunks,
Layer layer, Vec2i lpos,
int it, double light,
boolean daylightMode
) {
if(
MathHelpers.floor(lpos.squareDistance(new Vec2i(
MathHelpers.floor(Main.player.pos.x),
MathHelpers.floor(Main.player.pos.y))) / 16)
> Camera.camera.renderDistance
) {
return;
}
if(light <= 0) {
return;
}
Chunk chunk = layer.getChunk(lpos);
ChunkLightingTemp chunk_t = chunks.getChunk(lpos);
int lid = lpos.getId(Chunk.CHUNK_SIZE);
// Don't calculate anything on empty chunks
if(chunk == Chunk.CHUNK_EMPTY) {
return;
}
TileState tile_f = chunk.getFrontTile(lid);
TileState tile_b = chunk.getBackTile(lid);
// Set the light level
if(daylightMode) {
if(tile_f.tile.passNaturalLight && tile_b.tile.passNaturalLight && it == 1) {
return;
}
if(light <= chunk_t.getDaylightLevel(lid)) return;
chunk_t.setDaylightLevel(light, lid);
} else {
if(light <= chunk_t.getLightLevel(lid)) return;
chunk_t.setLightLevel(light, lid);
}
// Calculate the dissipation
double dissipation = MathHelpers.biggest(
tile_b.tile.getLightDissipation(tile_b),
tile_f.tile.getLightDissipation(tile_f));
// Get all the adjacent positions of the light tiles to flow onto
Vec2i positions[] = {
new Vec2i(lpos.x+1, lpos.y),
new Vec2i(lpos.x-1, lpos.y),
new Vec2i(lpos.x, lpos.y+1),
new Vec2i(lpos.x, lpos.y-1)
};
int samechunk = 0;
for(Vec2i position : positions) {
Vec2i new_cpos = Layer.getChunkPosFromPos(position);
if(new_cpos.equal(chunk.c_pos)) {
samechunk += 1;
}
}
if(samechunk == 4) {
double neighbour_light = 0;
for(Vec2i position : positions) {
TileState tf = chunk.getFrontTile(position);
TileState tb = chunk.getBackTile(position);
neighbour_light = MathHelpers.smallest(MathHelpers.biggest(
tb.tile.getLightLevel(tb, position),
tf.tile.getLightLevel(tf, position)),
neighbour_light);
}
if(neighbour_light > light) {
return;
}
}
// Add the light to all the adjacent positions
for(Vec2i position : positions) {
addLightToTiles(chunks, layer, position, it + 1, light - dissipation, daylightMode);
}
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > 10000;
}
@Override
public boolean MainLoopRepeat() {
return true;
}
@Override
public void MainLoopUpdate() {
lighting_dirty = true;
}
}

View File

@ -148,9 +148,9 @@ public class EntityBullet extends EntityParticle
public void render(Vec2d pos, Camera camera) public void render(Vec2d pos, Camera camera)
{ {
// Set the colour // Set the colour
double light = chunk.getLightLevel(new Vec2i( Vec3d light = chunk.getRGBLightLevel(new Vec2i(
MathHelpers.floor(pos.x), MathHelpers.floor(pos.y))); MathHelpers.floor(pos.x), MathHelpers.floor(pos.y)));
GlHelpers.color3(1 * light, 0.8 * light, 0.3 * light); GlHelpers.color3(1 * light.x, 0.8 * light.y, 0.3 * light.z);
// Set the height // Set the height
this.setHeight(height); this.setHeight(height);

View File

@ -7,6 +7,7 @@ import projectzombie.util.gl.texture.TextureReference;
import projectzombie.util.math.MathHelpers; import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.vec.Vec2d; import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
import projectzombie.util.math.vec.Vec3d;
public class EntityVertical extends Entity public class EntityVertical extends Entity
{ {
@ -30,9 +31,9 @@ public class EntityVertical extends Entity
} }
public void render(Vec2d pos, Camera camera, double opacity) { public void render(Vec2d pos, Camera camera, double opacity) {
double light = chunk.getLightLevel(new Vec2i( Vec3d light = chunk.getRGBLightLevel(new Vec2i(
MathHelpers.floor(pos.x), MathHelpers.floor(pos.y))); MathHelpers.floor(pos.x), MathHelpers.floor(pos.y)));
GlHelpers.color4(light, light, light, opacity); GlHelpers.color4(light.x, light.y, light.z, opacity);
this.render(pos, camera, tex, size); this.render(pos, camera, tex, size);
GlHelpers.color4(1, 1, 1, 1); GlHelpers.color4(1, 1, 1, 1);
} }

View File

@ -12,6 +12,8 @@ public class EntityZombie extends EntityVertical implements EntityAlive
protected OpenSimplexNoise noise_movement; protected OpenSimplexNoise noise_movement;
protected OpenSimplexNoise noise_gun_fire; protected OpenSimplexNoise noise_gun_fire;
protected OpenSimplexNoise noise_gun_angle; protected OpenSimplexNoise noise_gun_angle;
protected OpenSimplexNoise noise_target_x;
protected OpenSimplexNoise noise_target_y;
protected double time; protected double time;
protected double health_max = 100; protected double health_max = 100;
protected double health = health_max; protected double health = health_max;
@ -23,6 +25,8 @@ public class EntityZombie extends EntityVertical implements EntityAlive
noise_movement = new OpenSimplexNoise(rand.nextLong()); noise_movement = new OpenSimplexNoise(rand.nextLong());
noise_gun_fire = new OpenSimplexNoise(rand.nextLong()); noise_gun_fire = new OpenSimplexNoise(rand.nextLong());
noise_gun_angle = new OpenSimplexNoise(rand.nextLong()); noise_gun_angle = new OpenSimplexNoise(rand.nextLong());
noise_target_x = new OpenSimplexNoise(rand.nextLong());
noise_target_y = new OpenSimplexNoise(rand.nextLong());
time = 0; time = 0;
// Set some settings // Set some settings
@ -36,12 +40,17 @@ public class EntityZombie extends EntityVertical implements EntityAlive
public void tick(Chunk chunk, Layer layer) { public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer); super.tick(chunk, layer);
// Get the player targeted area
Vec2d target = new Vec2d(
Main.player.pos.x + noise_target_x.eval(time*5, Main.player.pos.x/10, Main.player.pos.y/10)*10,
Main.player.pos.y + noise_target_y.eval(time*5, Main.player.pos.x/10, Main.player.pos.y/10)*10);
// Get the angle between the player and the zombie // Get the angle between the player and the zombie
double angle = Math.atan2(pos.x - Main.player.pos.x, pos.y - Main.player.pos.y); double angle_walk = Math.atan2(pos.x - target.x, pos.y - target.y);
double angle_fire = Math.atan2(pos.x - Main.player.pos.x, pos.y - Main.player.pos.y);
// Move forward towards the player // Move forward towards the player
this.angle = Math.toDegrees(angle) + 180; this.angle = Math.toDegrees(angle_walk) + 180;
this.angle += noise_movement.eval(time, 0)*80;
this.moveForward(); this.moveForward();
if(noise_gun_fire.eval(time, 0) > 0 && !Main.player.dead && !Main.player.in_animation) if(noise_gun_fire.eval(time, 0) > 0 && !Main.player.dead && !Main.player.in_animation)
@ -52,7 +61,7 @@ public class EntityZombie extends EntityVertical implements EntityAlive
if(gun_interval == 0) if(gun_interval == 0)
{ {
// Aim the gun at the player // Aim the gun at the player
double angle_gun = Math.toDegrees(angle) + 180; double angle_gun = Math.toDegrees(angle_fire) + 180;
angle_gun += noise_gun_angle.eval(time, 0)*20; angle_gun += noise_gun_angle.eval(time, 0)*20;
// Fire the gun // Fire the gun

View File

@ -44,7 +44,7 @@ public class ParticleBlood extends EntityParticle
height += velocity.z; height += velocity.z;
velocity.x /= 1.05; velocity.x /= 1.05;
velocity.y /= 1.05; velocity.y /= 1.05;
velocity.z -= 0.001; velocity.z -= MathHelpers.FallSpeed;
if(height < 0) { if(height < 0) {
height = 0; height = 0;
velocity.z = 0; velocity.z = 0;
@ -61,12 +61,12 @@ public class ParticleBlood extends EntityParticle
public void render(Vec2d pos, Camera camera) public void render(Vec2d pos, Camera camera)
{ {
// Get the light level // Get the light level
double light = chunk.getLightLevel(new Vec2i( Vec3d light = chunk.getRGBLightLevel(new Vec2i(
MathHelpers.floor(pos.x), MathHelpers.floor(pos.y))); MathHelpers.floor(pos.x), MathHelpers.floor(pos.y)));
// Set some settings // Set some settings
GlHelpers.pushMatrix(); GlHelpers.pushMatrix();
GlHelpers.color3(r_color * light, 0, 0); GlHelpers.color3(r_color * light.x, 0, 0);
GlHelpers.translate3(0, 0, height); GlHelpers.translate3(0, 0, height);
// Call super // Call super

View File

@ -59,10 +59,10 @@ public class ParticleBreak extends EntityVertical
time -= 1; time -= 1;
height += velocity.z; height += velocity.z;
velocity.z -= 0.001; velocity.z -= MathHelpers.FallSpeed;
if(height <= 0) { if(height < -1) {
velocity.z = 0; kill();
} }
else { else {
@ -73,9 +73,9 @@ public class ParticleBreak extends EntityVertical
@Override @Override
public void render(Vec2d pos, Camera camera, TextureReference tex, Vec2d size) { public void render(Vec2d pos, Camera camera, TextureReference tex, Vec2d size) {
double light = chunk.getLightLevel(new Vec2i( Vec3d light = chunk.getRGBLightLevel(new Vec2i(
MathHelpers.floor(pos.x), MathHelpers.floor(pos.y))); MathHelpers.floor(pos.x), MathHelpers.floor(pos.y)));
GlHelpers.color3(light, light, light); GlHelpers.color3(light.x, light.y, light.z);
GlHelpers.pushMatrix(); GlHelpers.pushMatrix();
GlHelpers.translate3(0, 0, height); GlHelpers.translate3(0, 0, height);
super.render(pos, camera, tex, size); super.render(pos, camera, tex, size);

View File

@ -31,13 +31,13 @@ public class ParticleLava extends EntityParticle
super.tick(chunk, layer); super.tick(chunk, layer);
// Add the velocity // Add the velocity
velocity.z -= 0.0005; velocity.z -= MathHelpers.FallSpeed;
pos.x += velocity.x; pos.x += velocity.x;
pos.y += velocity.y; pos.y += velocity.y;
height += velocity.z; height += velocity.z;
// Is the height below 0; destroy this particle // Is the height below 0; destroy this particle
if(height < 0) { if(height < -1) {
kill(); kill();
} }
} }

View File

@ -29,7 +29,7 @@ public class ParticleWater extends EntityParticle
super.tick(chunk, layer); super.tick(chunk, layer);
// Add the velocity // Add the velocity
velocity.z -= 0.005; velocity.z -= MathHelpers.FallSpeed;
pos.x += velocity.x; pos.x += velocity.x;
pos.y += velocity.y; pos.y += velocity.y;
height += velocity.z; height += velocity.z;
@ -44,9 +44,9 @@ public class ParticleWater extends EntityParticle
public void render(Vec2d pos, Camera camera) { public void render(Vec2d pos, Camera camera) {
GlHelpers.pushMatrix(); GlHelpers.pushMatrix();
GlHelpers.translate3(0, 0, height); GlHelpers.translate3(0, 0, height);
double light = chunk.getLightLevel(new Vec2i( Vec3d light = chunk.getRGBLightLevel(new Vec2i(
MathHelpers.floor(pos.x), MathHelpers.floor(pos.y))); MathHelpers.floor(pos.x), MathHelpers.floor(pos.y)));
GlHelpers.color4(0, 0, light, 0.4); GlHelpers.color4(0, 0, light.z, 0.4);
super.render(pos, camera); super.render(pos, camera);
GlHelpers.color4(1, 1, 1, 1); GlHelpers.color4(1, 1, 1, 1);
GlHelpers.popMatrix(); GlHelpers.popMatrix();

View File

@ -177,7 +177,7 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
GlHelpers.translate3(0, 0, height); GlHelpers.translate3(0, 0, height);
// Set the colour due to the lighting // Set the colour due to the lighting
double light = chunk.getLightLevel(new Vec2i( double light = chunk.getDynamicLightLevel(new Vec2i(
MathHelpers.floor(pos.x), MathHelpers.floor(pos.y))); MathHelpers.floor(pos.x), MathHelpers.floor(pos.y)));
GlHelpers.color3(light, light, light); GlHelpers.color3(light, light, light);

View File

@ -0,0 +1,83 @@
package projectzombie.mainloop;
import java.util.ArrayList;
import mainloop.task.IMainloopTask;
class AsyncTask
{
int i, max;
MainloopEnd end;
MainloopIterator iterator;
AsyncTask(int min, int max, MainloopIterator iterator, MainloopEnd end) {
this.i = min;
this.max = max;
this.end = end;
this.iterator = iterator;
}
void update() {
long start = System.currentTimeMillis();
while(i < max && System.currentTimeMillis() - start < 2) {
iterator.iterate(i);
i += 1;
}
if(i == max) {
end.end();
i += 1;
}
}
boolean done() {
return i > max;
}
}
public class MainloopHelpers implements IMainloopTask
{
private static ArrayList<AsyncTask> tasks = new ArrayList<AsyncTask>();
public static void loopAsync(int min, int max, MainloopIterator iterator, MainloopEnd end) {
tasks.add(new AsyncTask(min, max, iterator, end));
}
public static void loopSync(int min, int max, MainloopIterator iterator, MainloopEnd end) {
for(int i=min;i<max;i++) {
iterator.iterate(i);
}
end.end();
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > 10;
}
@Override
public boolean MainLoopRepeat() {
return true;
}
@Override
public void MainLoopUpdate()
{
long start = System.currentTimeMillis();
for(int i=0;i<tasks.size();i++) {
AsyncTask t = tasks.get(i);
if(t.done()) {
tasks.remove(i);
i -= 1;
return;
}
t.update();
}
if(System.currentTimeMillis() > start + 8) {
tasks.remove(0);
}
}
}

View File

@ -0,0 +1,6 @@
package projectzombie.mainloop;
public interface MainloopIterator
{
public void iterate(int i);
}

View File

@ -1,6 +1,7 @@
package projectzombie.menu; package projectzombie.menu;
import projectzombie.input.types.InputGUI; import projectzombie.input.types.InputGUI;
import projectzombie.menu.gui.ButtonGroup;
import projectzombie.menu.gui.GUI; import projectzombie.menu.gui.GUI;
import projectzombie.menu.gui.components.ButtonGroupPause; import projectzombie.menu.gui.components.ButtonGroupPause;
import projectzombie.menu.gui.components.LabelPause; import projectzombie.menu.gui.components.LabelPause;
@ -20,7 +21,10 @@ public class MenuDeath extends Menu
gui.add(new OverlayBackground()); gui.add(new OverlayBackground());
gui.add(new LabelPause("You Died!")); gui.add(new LabelPause("You Died!"));
gui.add(new ButtonGroupPause());
ButtonGroup group = new ButtonGroupPause();
gui.setSelected(group.get(0));
gui.add(group);
} }
@Override @Override

View File

@ -1,47 +0,0 @@
package projectzombie.tiles;
import java.util.Random;
import mainloop.task.IMainloopTask;
import projectzombie.time.GameTimer;
import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.random.OpenSimplexNoise;
public class LightLevelNoise implements IMainloopTask
{
private static final Random rand = new Random();
private static final OpenSimplexNoise lava_noise_g = new OpenSimplexNoise(rand.nextLong());
private static final OpenSimplexNoise lantern_noise_g = new OpenSimplexNoise(rand.nextLong());
private static double lava_noise = 0;
private static double lantern_noise = 0;
static double getLightLevel(OpenSimplexNoise noise) {
return noise.eval(GameTimer.getTime() / 50.0, 0);
}
static double getLavaLightLevel() {
return lava_noise;
}
static double getLanternLightLevel() {
return lantern_noise;
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > 10;
}
@Override
public boolean MainLoopRepeat() {
return true;
}
@Override
public void MainLoopUpdate()
{
lava_noise = MathHelpers.map(getLightLevel(lava_noise_g), -1, 1, 0.6, 0.8);
lantern_noise = MathHelpers.map(getLightLevel(lantern_noise_g), -1, 1, 0.6, 1);
}
}

View File

@ -21,6 +21,7 @@ public class Tile implements ITransparentObject
public boolean unbreakable = false; public boolean unbreakable = false;
protected double light_dissipation = 1/8.0; protected double light_dissipation = 1/8.0;
public boolean emitsLight = true; public boolean emitsLight = true;
public boolean passNaturalLight = true;
public Tile(String id) { public Tile(String id) {
this.id = id; this.id = id;

View File

@ -8,6 +8,7 @@ import projectzombie.entity.Entity;
import projectzombie.entity.particle.ParticleBreak; import projectzombie.entity.particle.ParticleBreak;
import projectzombie.entity.player.EntityPlayer; import projectzombie.entity.player.EntityPlayer;
import projectzombie.init.Textures; import projectzombie.init.Textures;
import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.TileState; import projectzombie.util.math.TileState;
import projectzombie.util.math.vec.Vec2d; import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
@ -42,7 +43,7 @@ public class TileBossPortal extends TileVertical
{ {
// Get the player and set some player variables // Get the player and set some player variables
EntityPlayer ep = (EntityPlayer)entity; EntityPlayer ep = (EntityPlayer)entity;
ep.height = 8; ep.height = 5;
// Create the boss arena // Create the boss arena
LayerGenBossArena layergen = new LayerGenBossArena(); LayerGenBossArena layergen = new LayerGenBossArena();
@ -55,6 +56,7 @@ public class TileBossPortal extends TileVertical
Main.mainloop.register(new IMainloopTask() Main.mainloop.register(new IMainloopTask()
{ {
int stage = 0; int stage = 0;
double velocity = 0;
@Override @Override
public void MainLoopUpdate() public void MainLoopUpdate()
@ -64,17 +66,21 @@ public class TileBossPortal extends TileVertical
// Only do this if the world is loaded // Only do this if the world is loaded
if(ChunkEventHandler.loaded) if(ChunkEventHandler.loaded)
{ {
ep.height -= 0.05; this.velocity -= MathHelpers.FallSpeed;
ep.height += this.velocity;
if(ep.height <= 0) { if(ep.height <= 0) {
this.velocity *= -0.6;
if(this.velocity <= 0.001) {
ep.height = 0; ep.height = 0;
} }
} }
} }
} }
}
@Override @Override
public boolean MainLoopRepeat() { public boolean MainLoopRepeat() {
return ep.height > 0; return ep.height > 0 || this.velocity > 0.001;
} }
@Override @Override

View File

@ -25,7 +25,7 @@ public class TileFlat extends Tile implements IHasTexture
super.render(pos, camera, state); super.render(pos, camera, state);
// Render the tile // Render the tile
GlHelpers.color3(state.light * color.x, state.light * color.y, state.light * color.z); GlHelpers.color3(state.light.x * color.x, state.light.y * color.y, state.light.z * color.z);
GlHelpers.begin(); GlHelpers.begin();
tex.texCoord(1, 1); GlHelpers.vertex3(pos.x+0, pos.y+0, 0); tex.texCoord(1, 1); GlHelpers.vertex3(pos.x+0, pos.y+0, 0);
tex.texCoord(0, 1); GlHelpers.vertex3(pos.x+1, pos.y+0, 0); tex.texCoord(0, 1); GlHelpers.vertex3(pos.x+1, pos.y+0, 0);

View File

@ -22,7 +22,7 @@ public class TileLantern extends TileVertical
@Override @Override
public double getLightLevel(TileState state, Vec2i pos) { public double getLightLevel(TileState state, Vec2i pos) {
return LightLevelNoise.getLanternLightLevel(); return 0.8;
} }
@Override @Override

View File

@ -34,7 +34,7 @@ public class TileLava extends TileFlat
@Override @Override
public double getLightLevel(TileState state, Vec2i pos) { public double getLightLevel(TileState state, Vec2i pos) {
return LightLevelNoise.getLavaLightLevel(); return 0.8;
} }
@Override @Override

View File

@ -33,7 +33,7 @@ public class TileLavaFlow extends TileFlat
@Override @Override
public double getLightLevel(TileState state, Vec2i pos) { public double getLightLevel(TileState state, Vec2i pos) {
return LightLevelNoise.getLavaLightLevel(); return 0.6;
} }
@Override @Override

View File

@ -24,7 +24,7 @@ public class TileVertical extends Tile implements IHasTexture
@Override @Override
public void render(Vec2d pos, Camera camera, TileState state) { public void render(Vec2d pos, Camera camera, TileState state) {
super.render(pos, camera, state); super.render(pos, camera, state);
GlHelpers.color3(state.light, state.light, state.light); GlHelpers.color3(state.light.x, state.light.y, state.light.z);
VerticalRender.render(pos, camera, tex, size); VerticalRender.render(pos, camera, tex, size);
} }

View File

@ -13,6 +13,7 @@ public class TileWall extends TileFlat
this.tileHitbox = 1; this.tileHitbox = 1;
this.light_dissipation = 1/2.0; this.light_dissipation = 1/2.0;
this.passNaturalLight = false;
} }
} }

View File

@ -0,0 +1,20 @@
package projectzombie.util.math;
import projectzombie.util.math.vec.Vec3d;
public class ColorRange
{
Vec3d colorMin, colorMax;
public ColorRange(Vec3d colorMin, Vec3d colorMax) {
this.colorMin = colorMin;
this.colorMax = colorMax;
}
public Vec3d getColor(double v) {
return new Vec3d(
MathHelpers.map(v, 0, 1, colorMin.x, colorMax.x),
MathHelpers.map(v, 0, 1, colorMin.y, colorMax.y),
MathHelpers.map(v, 0, 1, colorMin.z, colorMax.z));
}
}

View File

@ -5,6 +5,8 @@ import projectzombie.util.math.vec.Vec3d;
public class MathHelpers public class MathHelpers
{ {
public static final double FallSpeed = 0.00098;
public static double squared(double x) { public static double squared(double x) {
return x*x; return x*x;
} }
@ -84,18 +86,6 @@ public class MathHelpers
else return a; else return a;
} }
/*
def rotate(point, angle):
angle = angle * (math.pi/180)
s = math.sin(angle)
c = math.cos(angle)
x = point[0] * c - point[1] * s
y = point[0] * s + point[1] * c
return [x, y]
*/
public static Vec2d rotate2(Vec2d pos, double angle) public static Vec2d rotate2(Vec2d pos, double angle)
{ {
// Calculate 2 sin and cos values // Calculate 2 sin and cos values

View File

@ -2,6 +2,7 @@ package projectzombie.util.math;
import projectzombie.init.Tiles; import projectzombie.init.Tiles;
import projectzombie.tiles.Tile; import projectzombie.tiles.Tile;
import projectzombie.util.math.vec.Vec3d;
public class TileState public class TileState
{ {
@ -9,7 +10,7 @@ public class TileState
public Tile tile; public Tile tile;
public byte meta; public byte meta;
public double light = 0; public Vec3d light;
public TileState(Tile tile, byte meta) { public TileState(Tile tile, byte meta) {
this.tile = tile; this.tile = tile;
@ -20,7 +21,7 @@ public class TileState
this(tile, (byte)meta); this(tile, (byte)meta);
} }
public TileState withLightLevel(double level) { public TileState withLightLevel(Vec3d level) {
TileState ts = new TileState(tile, meta); TileState ts = new TileState(tile, meta);
ts.light = level; ts.light = level;
return ts; return ts;

View File

@ -15,6 +15,7 @@ import projectzombie.util.math.random.RandomHelpers;
import projectzombie.util.math.range.Range2i; import projectzombie.util.math.range.Range2i;
import projectzombie.util.math.vec.Vec2d; import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
import projectzombie.util.math.vec.Vec3d;
import projectzombie.world.layer.Layer; import projectzombie.world.layer.Layer;
public class Chunk public class Chunk
@ -32,10 +33,13 @@ public class Chunk
private byte tiles_front_meta[] = new byte[CHUNK_INDEX]; private byte tiles_front_meta[] = new byte[CHUNK_INDEX];
private byte tiles_back_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_lighting[] = new byte[CHUNK_INDEX];
private byte tiles_lighting_dynamic[] = new byte[CHUNK_INDEX];
private byte tiles_lighting_daylight[] = new byte[CHUNK_INDEX];
public ArrayList<Entity> entities = new ArrayList<Entity>(); public ArrayList<Entity> entities = new ArrayList<Entity>();
private Layer layer; private Layer layer;
private Vec2i c_pos; public Vec2i c_pos;
public boolean dirty; public boolean dirty;
public boolean light_dirty;
public Chunk(Layer layer, Vec2i c_pos, Random rand) public Chunk(Layer layer, Vec2i c_pos, Random rand)
{ {
@ -43,6 +47,7 @@ public class Chunk
this.layer = layer; this.layer = layer;
this.c_pos = c_pos; this.c_pos = c_pos;
this.dirty = false; this.dirty = false;
this.light_dirty = true;
// Loop over all the tiles in the chunk // Loop over all the tiles in the chunk
for(int i=0;i<CHUNK_INDEX;i++) for(int i=0;i<CHUNK_INDEX;i++)
@ -53,9 +58,10 @@ public class Chunk
tiles_back_meta[i] = 0; tiles_back_meta[i] = 0;
tiles_front_meta[i] = 0; tiles_front_meta[i] = 0;
// Set the light level // Set the light level to 0
double light_level = layer.layergen.getLightLevel(); tiles_lighting[i] = 0;
tiles_lighting[i] = (byte)(light_level*Byte.MAX_VALUE); tiles_lighting_daylight[i] = 0;
tiles_lighting_dynamic[i] = 0;
} }
} }
@ -150,6 +156,7 @@ public class Chunk
// Set the back tile // Set the back tile
this.tiles_back[id] = tile.tile; this.tiles_back[id] = tile.tile;
this.tiles_back_meta[id] = tile.meta; this.tiles_back_meta[id] = tile.meta;
this.light_dirty = true;
this.dirty = true; this.dirty = true;
} }
@ -169,6 +176,7 @@ public class Chunk
// Set the front tile // Set the front tile
this.tiles_front[id] = tile.tile; this.tiles_front[id] = tile.tile;
this.tiles_front_meta[id] = tile.meta; this.tiles_front_meta[id] = tile.meta;
this.light_dirty = true;
this.dirty = true; this.dirty = true;
} }
@ -187,7 +195,7 @@ public class Chunk
{ {
// Send back the back tile // Send back the back tile
TileState ts = new TileState(this.tiles_back[id], this.tiles_back_meta[id]); TileState ts = new TileState(this.tiles_back[id], this.tiles_back_meta[id]);
ts.light = this.tiles_lighting[id] / (double) Byte.MAX_VALUE; ts.light = getRGBLightLevel(id);
return ts; return ts;
} }
@ -206,18 +214,36 @@ public class Chunk
{ {
// Send back the front tile // Send back the front tile
TileState ts = new TileState(this.tiles_front[id], this.tiles_front_meta[id]); TileState ts = new TileState(this.tiles_front[id], this.tiles_front_meta[id]);
ts.light = this.tiles_lighting[id] / (double) Byte.MAX_VALUE; ts.light = getRGBLightLevel(id);
return ts; return ts;
} }
public Vec3d getRGBLightLevel(Vec2i tpos) {
return getRGBLightLevel(tpos.getId(CHUNK_SIZE));
}
public Vec3d getRGBLightLevel(int id)
{
double daylight_level = this.getDaylightLevel(id);
Vec3d light = this.layer.layergen.getLightLevel().getColor(daylight_level);
double light_level = this.getDynamicLightLevel(id);
if(light_level > light.x) light.x = light_level;
if(light_level > light.y) light.y = light_level;
if(light_level > light.z) light.z = light_level;
return light;
}
public void breakBackTile(Vec2i pos) public void breakBackTile(Vec2i pos)
{ {
TileState ts = getBackTile(pos); TileState ts = getBackTile(pos);
this.light_dirty = true;
this.dirty = true; this.dirty = true;
if(!ts.tile.unbreakable) { if(!ts.tile.unbreakable) {
setBackTile(layer.layergen.getTileDestroyed(), pos); setBackTile(layer.layergen.getTileDestroyed(), pos);
for(int i=0;i<20;i++) { for(int i=0;i<100;i++) {
spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts)); spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts));
} }
} }
@ -226,11 +252,12 @@ public class Chunk
public void breakFrontTile(Vec2i pos) public void breakFrontTile(Vec2i pos)
{ {
TileState ts = getFrontTile(pos); TileState ts = getFrontTile(pos);
this.light_dirty = true;
this.dirty = true; this.dirty = true;
if(!ts.tile.unbreakable) { if(!ts.tile.unbreakable) {
setFrontTile(Tiles.VOID.getDefaultState(), pos); setFrontTile(Tiles.VOID.getDefaultState(), pos);
for(int i=0;i<20;i++) { for(int i=0;i<100;i++) {
spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts)); spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts));
} }
} }
@ -251,6 +278,21 @@ public class Chunk
return getLightLevel(id); return getLightLevel(id);
} }
public double getDaylightLevel(int id) {
return tiles_lighting_daylight[id] / (double)Byte.MAX_VALUE;
}
public double getDaylightLevel(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);
return getDaylightLevel(id);
}
public void setLightLevel(double light, int id) { public void setLightLevel(double light, int id) {
this.tiles_lighting[id] = (byte)(light * Byte.MAX_VALUE); this.tiles_lighting[id] = (byte)(light * Byte.MAX_VALUE);
} }
@ -266,6 +308,51 @@ public class Chunk
setLightLevel(light, id); setLightLevel(light, id);
} }
public void setDaylightLevel(double light, int id) {
this.tiles_lighting_daylight[id] = (byte)(light * Byte.MAX_VALUE);
}
public void setDaylightLevel(double light, 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);
setDaylightLevel(light, id);
}
public double getDynamicLightLevel(int id) {
return tiles_lighting_dynamic[id] / (double)Byte.MAX_VALUE;
}
public double getDynamicLightLevel(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);
return getDynamicLightLevel(id);
}
public void setDynamicLightLevel(double light, int id) {
this.tiles_lighting_dynamic[id] = (byte)(light * Byte.MAX_VALUE);
}
public void setDynamicLightLevel(double light, 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);
setDynamicLightLevel(light, id);
}
public void killEntity(Entity e) { public void killEntity(Entity e) {
entities.remove(e); entities.remove(e);
} }

View File

@ -10,8 +10,6 @@ import projectzombie.util.math.vec.Vec2i;
public class ChunkEmpty extends Chunk public class ChunkEmpty extends Chunk
{ {
public ChunkEmpty() { public ChunkEmpty() {
super(null, null, null); super(null, null, null);
} }
@ -97,6 +95,43 @@ public class ChunkEmpty extends Chunk
public void setFrontTile(TileState tile, int id) { public void setFrontTile(TileState tile, int id) {
} }
@Override
public double getDynamicLightLevel(int id) {
return 0;
}
@Override
public double getDynamicLightLevel(Vec2i pos) {
return 0;
}
@Override
public void setDynamicLightLevel(double light, int id) {
}
@Override
public void setDynamicLightLevel(double light, Vec2i pos) {
}
@Override
public void tickRandomly() {
}
@Override
public double getDaylightLevel(int id) {
return 0;
}
@Override
public double getDaylightLevel(Vec2i pos) {
return 0;
}
@Override
public void setDaylightLevel(double light, int id) {
}
@Override
public void setDaylightLevel(double light, Vec2i pos) {
}
} }

View File

@ -2,6 +2,8 @@ package projectzombie.world.chunk;
import mainloop.task.IMainloopTask; import mainloop.task.IMainloopTask;
import projectzombie.Main; import projectzombie.Main;
import projectzombie.display.lighting.TileLighting;
import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.map.Map2DElement; import projectzombie.util.math.map.Map2DElement;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
import projectzombie.world.layer.Layer; import projectzombie.world.layer.Layer;
@ -52,8 +54,8 @@ public class ChunkEventHandler implements IMainloopTask
for(int y=-Chunk.SIMULATION_DISTANCE;y<Chunk.SIMULATION_DISTANCE;y++) for(int y=-Chunk.SIMULATION_DISTANCE;y<Chunk.SIMULATION_DISTANCE;y++)
{ {
// Get the chunk based on the player position // Get the chunk based on the player position
int cx = (int)Main.player.pos.x / 16 + x; int cx = MathHelpers.floor(Main.player.pos.x / 16) + x;
int cy = (int)Main.player.pos.y / 16 + y; int cy = MathHelpers.floor(Main.player.pos.y / 16) + y;
Vec2i c_pos = new Vec2i(cx, cy); Vec2i c_pos = new Vec2i(cx, cy);
// Is this chunk not loaded // Is this chunk not loaded
@ -64,6 +66,8 @@ public class ChunkEventHandler implements IMainloopTask
} }
} }
} }
TileLighting.update();
} }
} }

View File

@ -114,11 +114,11 @@ public class Layer
getChunk(pos).breakFrontTile(pos); getChunk(pos).breakFrontTile(pos);
} }
private Vec2i getChunkPosFromPos(Vec2i pos) { public static Vec2i getChunkPosFromPos(Vec2i pos) {
return this.getChunkPosFromPos(new Vec2d(pos.x, pos.y)); return getChunkPosFromPos(new Vec2d(pos.x, pos.y));
} }
private Vec2i getChunkPosFromPos(Vec2d pos) { public static Vec2i getChunkPosFromPos(Vec2d pos) {
return new Vec2i( return new Vec2i(
MathHelpers.floor(pos.x / (double)Chunk.CHUNK_SIZE.mx), MathHelpers.floor(pos.x / (double)Chunk.CHUNK_SIZE.mx),
MathHelpers.floor(pos.y / (double)Chunk.CHUNK_SIZE.my)); MathHelpers.floor(pos.y / (double)Chunk.CHUNK_SIZE.my));
@ -142,6 +142,42 @@ public class Layer
chunks.get(c_pos).setLightLevel(light, pos); chunks.get(c_pos).setLightLevel(light, pos);
} }
public double getDynamicLightLevel(Vec2i pos)
{
// Get the chunk pos
Vec2i c_pos = getChunkPosFromPos(pos);
// Get the chunks front tile
return chunks.get(c_pos).getDynamicLightLevel(pos);
}
public void setDynamicLightLevel(double light, Vec2i pos)
{
// Get the chunk pos
Vec2i c_pos = getChunkPosFromPos(pos);
// Get the chunks front tile
chunks.get(c_pos).setDynamicLightLevel(light, pos);
}
public double getDaylightLevel(Vec2i pos)
{
// Get the chunk pos
Vec2i c_pos = getChunkPosFromPos(pos);
// Get the chunks front tile
return chunks.get(c_pos).getDaylightLevel(pos);
}
public void setDaylightLevel(double light, Vec2i pos)
{
// Get the chunk pos
Vec2i c_pos = getChunkPosFromPos(pos);
// Get the chunks front tile
chunks.get(c_pos).setDaylightLevel(light, pos);
}
public TileState getFrontTile(Vec2i pos) public TileState getFrontTile(Vec2i pos)
{ {
// Get the chunk pos // Get the chunk pos

View File

@ -2,6 +2,7 @@ package projectzombie.world.layer.layergen;
import java.util.Random; import java.util.Random;
import projectzombie.util.math.ColorRange;
import projectzombie.util.math.TileState; import projectzombie.util.math.TileState;
import projectzombie.util.math.map.IMap2D; import projectzombie.util.math.map.IMap2D;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
@ -13,7 +14,7 @@ public abstract class LayerGen implements IMap2D<Chunk>
public abstract void generateChunk(Chunk chunk, Layer layer, long seed, Random rand, Vec2i pos); public abstract void generateChunk(Chunk chunk, Layer layer, long seed, Random rand, Vec2i pos);
public abstract void spawnEntities(Layer layer, Random rand); public abstract void spawnEntities(Layer layer, Random rand);
public abstract TileState getTileDestroyed(); public abstract TileState getTileDestroyed();
public abstract double getLightLevel(); public abstract ColorRange getLightLevel();
@Override @Override
public Chunk getEmpty(Vec2i pos) { public Chunk getEmpty(Vec2i pos) {

View File

@ -5,11 +5,13 @@ import java.util.Random;
import projectzombie.entity.EntityBoss; import projectzombie.entity.EntityBoss;
import projectzombie.entity.player.EntityPlayer; import projectzombie.entity.player.EntityPlayer;
import projectzombie.init.Tiles; import projectzombie.init.Tiles;
import projectzombie.util.math.ColorRange;
import projectzombie.util.math.MathHelpers; import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.TileState; import projectzombie.util.math.TileState;
import projectzombie.util.math.random.RandomHelpers; import projectzombie.util.math.random.RandomHelpers;
import projectzombie.util.math.vec.Vec2d; import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
import projectzombie.util.math.vec.Vec3d;
import projectzombie.world.chunk.Chunk; import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer; import projectzombie.world.layer.Layer;
@ -92,8 +94,8 @@ public class LayerGenBossArena extends LayerGen implements LayerGenRememberPlaye
} }
@Override @Override
public double getLightLevel() { public ColorRange getLightLevel() {
return 0; return new ColorRange(new Vec3d(0, 0, 0), new Vec3d(0.08, 0.04, 0.02));
} }
@Override @Override

View File

@ -6,12 +6,14 @@ import projectzombie.Main;
import projectzombie.entity.Entity; import projectzombie.entity.Entity;
import projectzombie.entity.EntityZombie; import projectzombie.entity.EntityZombie;
import projectzombie.init.Tiles; import projectzombie.init.Tiles;
import projectzombie.util.math.ColorRange;
import projectzombie.util.math.MathHelpers; import projectzombie.util.math.MathHelpers;
import projectzombie.util.math.TileState; import projectzombie.util.math.TileState;
import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.util.math.random.OpenSimplexNoise;
import projectzombie.util.math.random.RandomHelpers; import projectzombie.util.math.random.RandomHelpers;
import projectzombie.util.math.vec.Vec2d; import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
import projectzombie.util.math.vec.Vec3d;
import projectzombie.world.chunk.Chunk; import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer; import projectzombie.world.layer.Layer;
@ -101,8 +103,8 @@ public class LayerGenCaves extends LayerGen
} }
@Override @Override
public double getLightLevel() { public ColorRange getLightLevel() {
return 0; return new ColorRange(new Vec3d(0, 0, 0), new Vec3d(0, 0, 0));
} }
} }

View File

@ -7,12 +7,13 @@ import projectzombie.entity.Entity;
import projectzombie.entity.EntityZombie; import projectzombie.entity.EntityZombie;
import projectzombie.init.Tiles; import projectzombie.init.Tiles;
import projectzombie.time.GameTimer; import projectzombie.time.GameTimer;
import projectzombie.util.math.MathHelpers; import projectzombie.util.math.ColorRange;
import projectzombie.util.math.TileState; import projectzombie.util.math.TileState;
import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.util.math.random.OpenSimplexNoise;
import projectzombie.util.math.random.RandomHelpers; import projectzombie.util.math.random.RandomHelpers;
import projectzombie.util.math.vec.Vec2d; import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
import projectzombie.util.math.vec.Vec3d;
import projectzombie.world.chunk.Chunk; import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer; import projectzombie.world.layer.Layer;
@ -30,7 +31,9 @@ public class LayerGenEarth extends LayerGen
RandomHelpers.randrange(rand, Chunk.CHUNK_SIZE.my)); RandomHelpers.randrange(rand, Chunk.CHUNK_SIZE.my));
// Get the noise generator // Get the noise generator
OpenSimplexNoise noisegen_n = new OpenSimplexNoise(new Random(seed + layer.id).nextLong()); Random rand_seed = new Random(seed + layer.id);
OpenSimplexNoise noisegen_n = new OpenSimplexNoise(rand_seed.nextLong());
OpenSimplexNoise noisegen_b = new OpenSimplexNoise(rand_seed.nextLong());
// Loop over the layer dimensions and create land // Loop over the layer dimensions and create land
for(int x=0;x<Chunk.CHUNK_SIZE.mx;x++) { for(int x=0;x<Chunk.CHUNK_SIZE.mx;x++) {
@ -41,24 +44,30 @@ public class LayerGenEarth extends LayerGen
int cy = y + c_pos.y * Chunk.CHUNK_SIZE.my; int cy = y + c_pos.y * Chunk.CHUNK_SIZE.my;
// Get the noise value and the position vector // Get the noise value and the position vector
double noise_n = (noisegen_n.eval(cx/10.0, cy/10.0) + 1) * 50; double noise_b1 = noisegen_b.eval(cx/1024.0, cy/1024.0);
double noise_b2 = noisegen_b.eval(cx/1024.0, cy/1024.0);
double noise_b3 = noisegen_b.eval(cx/1024.0, cy/1024.0);
double noise_b4 = (noisegen_b.eval(cx/1024.0, cy/1024.0) + 1) / 20;
double noise_n = (noisegen_n.eval(cx/(10+noise_b4), cy/(10+noise_b4)) + 1) * 50;
Vec2i pos = new Vec2i(x, y); Vec2i pos = new Vec2i(x, y);
// Terrain generation
if(noise_n < 40 + noise_b1 * 10) {
chunk.setFrontTile(Tiles.WATER.getDefaultState(), pos);
chunk.setBackTile(Tiles.DIRT.getDefaultState(), pos);
}
else if(noise_n < 70 - noise_b2 * 10) chunk.setBackTile(Tiles.GRASS.getDefaultState(), pos);
else if(noise_n < 85 - noise_b3 * 10) chunk.setBackTile(Tiles.DIRT.getDefaultState(), pos);
else chunk.setBackTile(Tiles.WALL.getDefaultState(), pos);
// Tree and rock generation // Tree and rock generation
if(!chunk.getBackTile(pos).tile.tileSolid) {
if(rand.nextDouble() > 0.9) chunk.setFrontTile(new TileState(Tiles.TREE, if(rand.nextDouble() > 0.9) chunk.setFrontTile(new TileState(Tiles.TREE,
(short)RandomHelpers.randrange(rand, Short.MAX_VALUE)), pos); (short)RandomHelpers.randrange(rand, Short.MAX_VALUE)), pos);
else if(rand.nextDouble() > 0.99) chunk.setFrontTile(new TileState(Tiles.ROCK, else if(rand.nextDouble() > 0.99) chunk.setFrontTile(new TileState(Tiles.ROCK,
(short)RandomHelpers.randrange(rand, Short.MAX_VALUE)), pos); (short)RandomHelpers.randrange(rand, Short.MAX_VALUE)), pos);
else chunk.setFrontTile(Tiles.VOID.getDefaultState(), pos); else chunk.setFrontTile(Tiles.VOID.getDefaultState(), pos);
// Terrain generation
if(noise_n < 40) {
chunk.setFrontTile(Tiles.WATER.getDefaultState(), pos);
chunk.setBackTile(Tiles.DIRT.getDefaultState(), pos);
} }
else if(noise_n < 70) chunk.setBackTile(Tiles.GRASS.getDefaultState(), pos);
else if(noise_n < 90) chunk.setBackTile(Tiles.DIRT.getDefaultState(), pos);
else chunk.setBackTile(Tiles.STONE.getDefaultState(), pos);
} }
} }
@ -89,9 +98,14 @@ public class LayerGenEarth extends LayerGen
} }
@Override @Override
public double getLightLevel() { public ColorRange getLightLevel()
return MathHelpers.map( {
Math.sin(GameTimer.getTime() / 7200) double light = Math.sin(GameTimer.getTime() / 7200.0);
, -1, 1, 0, 0.8);
ColorRange daylightRange = new ColorRange(
new Vec3d(60/255.0, 74/255.0, 68/255.0),
new Vec3d(205/255.0, 191/255.0, 162/255.0));
return new ColorRange(new Vec3d(0, 0, 0), daylightRange.getColor(light));
} }
} }

View File

@ -6,11 +6,13 @@ import projectzombie.Main;
import projectzombie.entity.Entity; import projectzombie.entity.Entity;
import projectzombie.entity.EntityZombieArmored; import projectzombie.entity.EntityZombieArmored;
import projectzombie.init.Tiles; import projectzombie.init.Tiles;
import projectzombie.util.math.ColorRange;
import projectzombie.util.math.TileState; import projectzombie.util.math.TileState;
import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.util.math.random.OpenSimplexNoise;
import projectzombie.util.math.random.RandomHelpers; import projectzombie.util.math.random.RandomHelpers;
import projectzombie.util.math.vec.Vec2d; import projectzombie.util.math.vec.Vec2d;
import projectzombie.util.math.vec.Vec2i; import projectzombie.util.math.vec.Vec2i;
import projectzombie.util.math.vec.Vec3d;
import projectzombie.world.chunk.Chunk; import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer; import projectzombie.world.layer.Layer;
@ -142,8 +144,8 @@ public class LayerGenLavaCaves extends LayerGen
} }
@Override @Override
public double getLightLevel() { public ColorRange getLightLevel() {
return 0.1; return new ColorRange(new Vec3d(0, 0, 0), new Vec3d(0.06, 0, 0));
} }
} }