From 135d6ef185bbcf9162761d49bc3061fdd9f75321 Mon Sep 17 00:00:00 2001 From: jsrobson10 Date: Sun, 5 Jul 2020 09:30:21 +1000 Subject: [PATCH] Added wind, fixed some issues with particles --- .classpath | 2 +- src/projectzombie/display/DisplayRender.java | 3 - .../display/DisplayRenderUI.java | 2 +- src/projectzombie/entity/EntityTnt.java | 32 ++--- .../entity/particle/ParticleBreak.java | 129 +++++++++++++----- .../entity/particle/ParticleLava.java | 34 ++--- .../entity/particle/ParticleSmoke.java | 1 + .../entity/particle/ParticleSmokeTrail.java | 106 ++++++++++++++ .../entity/particle/ParticleSpark.java | 45 ------ .../entity/player/EntityPlayer.java | 7 +- src/projectzombie/init/Models.java | 4 +- .../mainloop/MainloopEventHandler.java | 5 + src/projectzombie/tiles/TileLava.java | 6 +- .../util/math/random/NoiseGenerator.java | 7 + .../math/random/NoiseGeneratorSimplex.java | 20 +++ src/projectzombie/world/layer/Layer.java | 3 +- .../world/layer/layergen/LayerGen.java | 5 + .../world/layer/layergen/LayerGenCaves.java | 12 +- .../world/layer/layergen/LayerGenEarth.java | 27 +++- src/resources/shader/environmentRenderer.fsh | 2 +- src/resources/shader/environmentRenderer.vsh | 2 +- .../texture/particle/smoke_trail.png | Bin 557 -> 2562 bytes 22 files changed, 308 insertions(+), 146 deletions(-) create mode 100755 src/projectzombie/entity/particle/ParticleSmokeTrail.java delete mode 100755 src/projectzombie/entity/particle/ParticleSpark.java create mode 100644 src/projectzombie/util/math/random/NoiseGenerator.java create mode 100644 src/projectzombie/util/math/random/NoiseGeneratorSimplex.java diff --git a/.classpath b/.classpath index 7b9447b..344bafb 100755 --- a/.classpath +++ b/.classpath @@ -41,6 +41,6 @@ - + diff --git a/src/projectzombie/display/DisplayRender.java b/src/projectzombie/display/DisplayRender.java index a4d309c..f0ceda6 100755 --- a/src/projectzombie/display/DisplayRender.java +++ b/src/projectzombie/display/DisplayRender.java @@ -49,9 +49,6 @@ public class DisplayRender Matrix4 rotated = Matrix4.rotate(-camera.angle, 0, 1, 0); Matrix4 billboard = Matrix4.multiply(Matrix4.rotate(-45, 1, 0, 0), rotated); - // Process all the light sources - //DynamicLighting.update(); - Main.window.environmentRenderer.use(); GL33.glUniformMatrix4fv(Main.window.glsl_billboard, true, billboard.getArray()); GL33.glUniformMatrix4fv(Main.window.glsl_projection, true, projection.getArray()); diff --git a/src/projectzombie/display/DisplayRenderUI.java b/src/projectzombie/display/DisplayRenderUI.java index 547b5a1..21663bb 100755 --- a/src/projectzombie/display/DisplayRenderUI.java +++ b/src/projectzombie/display/DisplayRenderUI.java @@ -89,7 +89,7 @@ public class DisplayRenderUI model_health_f.render(); double temperature = MathHelpers.smoothStep(Main.player.getTemperature()); - double hydration = MathHelpers.smoothStep(1 - Main.player.getHydration()); + double hydration = MathHelpers.smoothStep(1 - Main.player.getHydration()) * 0.75; GL33.glUniform2f(Main.window.glsl_tex_cut, 0, 0); diff --git a/src/projectzombie/entity/EntityTnt.java b/src/projectzombie/entity/EntityTnt.java index f7f31d9..f8d6b92 100755 --- a/src/projectzombie/entity/EntityTnt.java +++ b/src/projectzombie/entity/EntityTnt.java @@ -5,7 +5,7 @@ import bdf.types.BdfObject; import gl_engine.MathHelpers; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; -import projectzombie.entity.particle.ParticleSpark; +import projectzombie.entity.particle.ParticleSmokeTrail; import projectzombie.init.Models; import projectzombie.model.Model; import projectzombie.world.chunk.Chunk; @@ -17,17 +17,17 @@ public class EntityTnt extends Entity implements EntityHoldsEntities protected int explode_time; private int explode_radius; private double explode_damage; - private ParticleSpark[] smoke_particles; + private ParticleSmokeTrail smoke_particles; @Override public Entity[] getEntities() { - return smoke_particles; + return new Entity[] {smoke_particles}; } public EntityTnt(BdfObject bdf) { super(bdf); - this.smoke_particles = new ParticleSpark[50]; + this.smoke_particles = new ParticleSmokeTrail(this, 1); } @Override @@ -59,7 +59,7 @@ public class EntityTnt extends Entity implements EntityHoldsEntities velocity = velocity.add(new Vec3d(v.x, v.y, 0.01)); this.explode_radius = explode_radius; this.explode_damage = explode_damage; - this.smoke_particles = new ParticleSpark[100]; + this.smoke_particles = new ParticleSmokeTrail(this, 1); // Set to 2.5 seconds this.explode_time = 250; @@ -74,25 +74,13 @@ public class EntityTnt extends Entity implements EntityHoldsEntities public void tick(Chunk chunk, Layer layer) { super.tick(chunk, layer); - int dead_particle = 0; - int dead_particle_count = 0; - - for(int i=0;i 32) { + count = 0; + } this.hasGravity = false; @@ -65,8 +90,6 @@ public class ParticleBreak extends EntityParticle implements IModel for(int i=0;i 0.75) { + dead += 1; + } + } + + protected void onAllDead() { + if(getPos().squareDistance(Main.player.getPos()) > 32) { + kill(); + } + } + + protected boolean isStill(Break particle) { + return particle.pos.y < 0; + } + + protected void onStill(Break particle) { + particle.moving = false; + particle.pos.y = still_ypos; + still += 1; + } + @Override public void tick(Chunk chunk, Layer layer) { super.tick(chunk, layer); + if(isDead()) { + return; + } + time -= 1; if(dead == particles.length - 1) { - kill(); + onAllDead(); return; } - if(time < 0 && still == particles.length) { - if(rand.nextDouble() > 0.75) { - dead += 1; - } + if(still == particles.length) { + onAllStill(); return; } - for(int i=0;i= particles.length) { + dead = particles.length - 1; + kill(); + } + } + } + + public void stopParticles() { + generating_particles = false; + } + + public boolean noMoreParticles() { + return dead == particles.length - 1; + } + +} diff --git a/src/projectzombie/entity/particle/ParticleSpark.java b/src/projectzombie/entity/particle/ParticleSpark.java deleted file mode 100755 index 6716b67..0000000 --- a/src/projectzombie/entity/particle/ParticleSpark.java +++ /dev/null @@ -1,45 +0,0 @@ -package projectzombie.entity.particle; - -import java.util.Random; - -import gl_engine.vec.Vec3d; -import projectzombie.entity.EntityParticle; -import projectzombie.init.Models; -import projectzombie.model.Model; -import projectzombie.world.chunk.Chunk; -import projectzombie.world.layer.Layer; - -public class ParticleSpark extends EntityParticle -{ - private int time; - - private static final Random rand = new Random(); - - public ParticleSpark(Vec3d pos) { - super(pos, new Vec3d( - rand.nextDouble() * 0.02 - 0.01, - rand.nextDouble() * 0.02 - 0.01, - rand.nextDouble() * 0.02)); - - time = 100; - } - - @Override - public void tick(Chunk chunk, Layer layer) { - super.tick(chunk, layer); - - // Reduce the time - time -= 1; - - // Kill if at the end of life - if(time <= 0 || DISABLED) { - kill(); - } - } - - @Override - public Model getModel() { - return Models.PARTICLE_SMOKE_TRAIL; - } - -} diff --git a/src/projectzombie/entity/player/EntityPlayer.java b/src/projectzombie/entity/player/EntityPlayer.java index d1386f7..16db5c6 100755 --- a/src/projectzombie/entity/player/EntityPlayer.java +++ b/src/projectzombie/entity/player/EntityPlayer.java @@ -110,6 +110,7 @@ public class EntityPlayer extends Entity implements EntityAlive, EntityInventory inventory.addItem(new ItemStack(Items.SPAWN_DUMMY, 999, (short)0)); inventory.addItem(new ItemStack(Items.SPAWN_ZOMBIE, 999, (short)0)); inventory.addItem(new ItemStack(Items.LANTERN, 999, (short)0)); + inventory.addItem(new ItemStack(Items.FLARE, 999, (short)0)); } @Override @@ -135,6 +136,10 @@ public class EntityPlayer extends Entity implements EntityAlive, EntityInventory { chunk = layer.getChunk(getPos().xz()); + temperature = 0.5; + health = health_max; + hydration = 1; + if(chunk != null && chunk.c_pos != null && (last_chunk == null || !chunk.c_pos.equal(last_chunk))) { last_chunk = chunk.c_pos; DisplayLighting.setDirty(); @@ -188,7 +193,7 @@ public class EntityPlayer extends Entity implements EntityAlive, EntityInventory chunk.getLightLevel(getPos().xz().toInt()) * 0.6) - temperature; temperature += temp_diff / 1000; - hydration -= MathHelpers.smoothStep(Math.abs(temperature - 0.4) + 0.1) / 1000; + hydration -= MathHelpers.smoothStep(Math.abs(temperature - 0.4) + 0.1) / 20000; if(temperature < 0.3) { health -= 0.3 - temperature; diff --git a/src/projectzombie/init/Models.java b/src/projectzombie/init/Models.java index 475a471..532e97a 100755 --- a/src/projectzombie/init/Models.java +++ b/src/projectzombie/init/Models.java @@ -51,9 +51,7 @@ public class Models public static final Model ENTITY_GRAPPLING_HOOK = new ModelVertical(Resources.ATLAS.get("/entity/grappling_hook.png")); public static final Model PARTICLE_BLOOD = new ModelVertical(Resources.ATLAS.get("/particle/blood.png"), new Vec2d(1, 1)); - public static final Model PARTICLE_LAVA = new ModelVertical(Resources.ATLAS.get("/particle/lava.png"), new Vec2d(0.1, 0.1)); - public static final Model PARTICLE_WATER = new ModelVertical(Resources.ATLAS.get("/particle/water.png"), new Vec2d(0.1, 0.1)); - public static final Model PARTICLE_SMOKE_TRAIL = new ModelVertical(Resources.ATLAS.get("/particle/smoke_trail.png"), new Vec2d(0.1, 0.1)); + public static final Model PARTICLE_SMOKE_TRAIL = new ModelVertical(Resources.ATLAS.get("/particle/smoke_trail.png"), new Vec2d(1, 1)); public static final Model PARTICLE_BULLET = new ModelVertical(Resources.ATLAS.get("/particle/bullet.png"), new Vec2d(0.1, 0.1)); public static final ModelRandom PARTICLE_SMOKE_RANDOM = new ModelRandom( diff --git a/src/projectzombie/mainloop/MainloopEventHandler.java b/src/projectzombie/mainloop/MainloopEventHandler.java index df27447..070511c 100755 --- a/src/projectzombie/mainloop/MainloopEventHandler.java +++ b/src/projectzombie/mainloop/MainloopEventHandler.java @@ -31,6 +31,11 @@ public class MainloopEventHandler implements IMainloopEvent, IMainloopTask @Override public void onLate() { mspf += 1; + + // Dont let the fps go past 1 frame every 10 seconds + if(mspf > 10000) { + mspf = 10000; + } } @Override diff --git a/src/projectzombie/tiles/TileLava.java b/src/projectzombie/tiles/TileLava.java index e89ea98..cc80a08 100755 --- a/src/projectzombie/tiles/TileLava.java +++ b/src/projectzombie/tiles/TileLava.java @@ -49,8 +49,10 @@ public class TileLava extends Tile public void tickRandomly(Layer layer, Chunk chunk, TileState state, Vec2i pos) { super.tickRandomly(layer, chunk, state, pos); - chunk.spawnEntity(new ParticleLava(new Vec3d( - pos.x + rand.nextDouble(), 0, pos.y + rand.nextDouble()), new Vec3d(0, 0, 0))); + if(rand.nextDouble() > 0.98) { + chunk.spawnEntity(new ParticleLava(new Vec3d( + pos.x + rand.nextDouble(), 0, pos.y + rand.nextDouble()), new Vec3d(0, 0, 0))); + } } } diff --git a/src/projectzombie/util/math/random/NoiseGenerator.java b/src/projectzombie/util/math/random/NoiseGenerator.java new file mode 100644 index 0000000..188d438 --- /dev/null +++ b/src/projectzombie/util/math/random/NoiseGenerator.java @@ -0,0 +1,7 @@ +package projectzombie.util.math.random; + +public interface NoiseGenerator +{ + public double eval(double x, double y); + public double eval(double x, double y, double z); +} diff --git a/src/projectzombie/util/math/random/NoiseGeneratorSimplex.java b/src/projectzombie/util/math/random/NoiseGeneratorSimplex.java new file mode 100644 index 0000000..1fcd798 --- /dev/null +++ b/src/projectzombie/util/math/random/NoiseGeneratorSimplex.java @@ -0,0 +1,20 @@ +package projectzombie.util.math.random; + +public class NoiseGeneratorSimplex implements NoiseGenerator +{ + private OpenSimplexNoise simplex; + + public NoiseGeneratorSimplex(long seed) { + simplex = new OpenSimplexNoise(seed); + } + + @Override + public double eval(double x, double y) { + return simplex.eval(x, y); + } + + @Override + public double eval(double x, double y, double z) { + return simplex.eval(x, y, z); + } +} diff --git a/src/projectzombie/world/layer/Layer.java b/src/projectzombie/world/layer/Layer.java index 09c2c49..ff0b906 100755 --- a/src/projectzombie/world/layer/Layer.java +++ b/src/projectzombie/world/layer/Layer.java @@ -18,6 +18,7 @@ import projectzombie.init.LayerGenerators; import projectzombie.util.math.TileState; import projectzombie.util.math.map.Map2D; import projectzombie.util.math.map.Map2DElement; +import projectzombie.util.math.random.NoiseGenerator; import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.world.chunk.Chunk; import projectzombie.world.layer.layergen.LayerGen; @@ -26,7 +27,7 @@ public class Layer implements IBdfClassManager { public Map2D chunks; private Map2D dirty_chunks; - public OpenSimplexNoise[] noise_gens; + public NoiseGenerator[] noise_gens; public LayerGen layergen; private Random rand; public long lseed; diff --git a/src/projectzombie/world/layer/layergen/LayerGen.java b/src/projectzombie/world/layer/layergen/LayerGen.java index d9ce483..c03786c 100755 --- a/src/projectzombie/world/layer/layergen/LayerGen.java +++ b/src/projectzombie/world/layer/layergen/LayerGen.java @@ -4,6 +4,7 @@ import java.util.Random; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec2i; +import gl_engine.vec.Vec3d; import projectzombie.util.math.ColorRange; import projectzombie.util.math.TileState; import projectzombie.util.math.map.IMap2D; @@ -15,6 +16,10 @@ public abstract class LayerGen implements IMap2D public int id; public boolean destroyOnLeave = false; + public Vec3d getWind(Layer layer, Vec2d pos) { + return new Vec3d(0, 0, 0); + } + 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); diff --git a/src/projectzombie/world/layer/layergen/LayerGenCaves.java b/src/projectzombie/world/layer/layergen/LayerGenCaves.java index c041d71..4f2f2ea 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenCaves.java +++ b/src/projectzombie/world/layer/layergen/LayerGenCaves.java @@ -12,6 +12,8 @@ import projectzombie.entity.EntityZombie; import projectzombie.init.Tiles; import projectzombie.util.math.ColorRange; import projectzombie.util.math.TileState; +import projectzombie.util.math.random.NoiseGenerator; +import projectzombie.util.math.random.NoiseGeneratorSimplex; import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.util.math.random.RandomHelpers; import projectzombie.world.chunk.Chunk; @@ -24,7 +26,7 @@ public class LayerGenCaves extends LayerGen public double getTemperatureStatic(Layer layer, Vec2d pos) { // Get the noise generator - OpenSimplexNoise terrain_noise = layer.noise_gens[0]; + NoiseGenerator terrain_noise = layer.noise_gens[0]; return MathHelpers.map(terrain_noise.eval(pos.x/64.0, pos.y/64.0), -1, 1, 0, 0.6); } @@ -37,7 +39,7 @@ public class LayerGenCaves extends LayerGen public double getHumidity(Layer layer, Vec2d pos) { // Get the noise generator - OpenSimplexNoise terrain_noise = layer.noise_gens[1]; + NoiseGenerator terrain_noise = layer.noise_gens[1]; return MathHelpers.map(terrain_noise.eval(pos.x/64.0, pos.y/64.0), -1, 1, 0.3, 0.8); } @@ -47,9 +49,9 @@ public class LayerGenCaves extends LayerGen Random rand = new Random(layer.seed); - layer.noise_gens = new OpenSimplexNoise[] { - new OpenSimplexNoise(rand.nextLong()), - new OpenSimplexNoise(rand.nextLong()) + layer.noise_gens = new NoiseGenerator[] { + new NoiseGeneratorSimplex(rand.nextLong()), + new NoiseGeneratorSimplex(rand.nextLong()) }; } diff --git a/src/projectzombie/world/layer/layergen/LayerGenEarth.java b/src/projectzombie/world/layer/layergen/LayerGenEarth.java index 630a532..d243b2b 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenEarth.java +++ b/src/projectzombie/world/layer/layergen/LayerGenEarth.java @@ -13,6 +13,8 @@ import projectzombie.init.Tiles; import projectzombie.time.GameTimer; import projectzombie.util.math.ColorRange; import projectzombie.util.math.TileState; +import projectzombie.util.math.random.NoiseGenerator; +import projectzombie.util.math.random.NoiseGeneratorSimplex; import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.util.math.random.RandomHelpers; import projectzombie.world.chunk.Chunk; @@ -20,12 +22,19 @@ import projectzombie.world.layer.Layer; public class LayerGenEarth extends LayerGen { + @Override + public Vec3d getWind(Layer layer, Vec2d pos) { + double t = GameTimer.getTime() / 1000.0; + return new Vec3d( + layer.noise_gens[2].eval(pos.x / 100, pos.y / 100, t) * 0.02, 0, + layer.noise_gens[3].eval(pos.x / 100, pos.y / 100, t) * 0.02); + } @Override public double getTemperatureStatic(Layer layer, Vec2d pos) { // Get the noise generator - OpenSimplexNoise terrain_noise = layer.noise_gens[0]; + NoiseGenerator terrain_noise = layer.noise_gens[0]; return MathHelpers.map(terrain_noise.eval(pos.x/64.0, pos.y/64.0), -1, 1, 0, 0.8); } @@ -34,7 +43,7 @@ public class LayerGenEarth extends LayerGen { // Get the noise generator double light = (MathHelpers.sin(GameTimer.getTime() / 7200.0 - MathHelpers.PI / 4) + 1) * 0.2; - OpenSimplexNoise terrain_noise = layer.noise_gens[0]; + NoiseGenerator terrain_noise = layer.noise_gens[0]; return MathHelpers.map(terrain_noise.eval(pos.x/64.0, pos.y/64.0), -1, 1, 0, 0.6 + light); } @@ -42,7 +51,7 @@ public class LayerGenEarth extends LayerGen public double getHumidity(Layer layer, Vec2d pos) { // Get the noise generator - OpenSimplexNoise terrain_noise = layer.noise_gens[1]; + NoiseGenerator terrain_noise = layer.noise_gens[1]; return MathHelpers.map(terrain_noise.eval(pos.x/64.0, pos.y/64.0), -1, 1, 0, 1); } @@ -52,9 +61,13 @@ public class LayerGenEarth extends LayerGen Random rand = new Random(layer.seed); - layer.noise_gens = new OpenSimplexNoise[] { - new OpenSimplexNoise(rand.nextLong()), - new OpenSimplexNoise(rand.nextLong()) + layer.noise_gens = new NoiseGenerator[] + { + new NoiseGeneratorSimplex(rand.nextLong()), + new NoiseGeneratorSimplex(rand.nextLong()), + + new NoiseGeneratorSimplex(rand.nextLong()), + new NoiseGeneratorSimplex(rand.nextLong()), }; } @@ -69,7 +82,7 @@ public class LayerGenEarth extends LayerGen RandomHelpers.randrange(rand, Chunk.CHUNK_SIZE.my)); // Get the noise generator - OpenSimplexNoise noise_terrain = layer.noise_gens[0]; + NoiseGenerator noise_terrain = layer.noise_gens[0]; // Loop over the layer dimensions and create land for(int x=0;x> 4, 2) == 1 ? billboard : (mod(type, 2) == 1 ? rotated : mat4(1))) * + vec4 pos = vec4(aPos, 1) * (mod(type >> 3, 2) == 1 ? billboard : (mod(type, 2) == 1 ? rotated : mat4(1))) * translate(aChunkOffset) * model; gl_Position = pos * projection; diff --git a/src/resources/texture/particle/smoke_trail.png b/src/resources/texture/particle/smoke_trail.png index 6ed752724ee09d4f5d0d4a2921762c0958977f7c..10d4ff6492bf1ae431e525472209f7bf9befb45f 100644 GIT binary patch delta 2509 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 delta 505 zcmZn?S<6!28Q|y6%O%Cdz`(%k>ERN@z`(!+!Wp(_C)#=(c91z5AG|e4i?2+e@I=5|oi4A!D_SB8omPlOl^X2)!ad7GMOUw{ zDf{5T{-dj!yEm`nTi2xUgYnUm7fW6!ss7W~+*051@xc!H_wQ`q-D7lGe8yyTHq(VK zt7du~IqFju%Clz?yWPR8^g$;6`-hKT^-gWxbN;X8uPbwoGR*g|InA@# zYmcMM?KM(!zIPs8qp|wP^CQV>u@inweBE_Ae-1Yvw~cYmvf$505|cJwIOxT`dC^Ki ze_{6!-{m!mk2lqys_fnzwr=A!+n?OdmbIxfUz@Z~JfJj9!Lg-D%1dK$m&RHvO|hUY z^4~x3Th?{PaP9O;coN~jDwT4a{~!DQ-CI8ePtFU{;49gGJc=ed6S))Rsk_VdQXY&T8i-*JbLZ9dP