diff --git a/src/Marble.hx b/src/Marble.hx index ad99f7c7..ccbc10d1 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -40,11 +40,11 @@ class Move { } final bounceParticleOptions:ParticleEmitterOptions = { - ejectionPeriod: 1, + ejectionPeriod: 80, ambientVelocity: new Vector(0, 0, 0.0), - ejectionVelocity: 2.6, - velocityVariance: 0.25 * 0.5, - emitterLifetime: 4, + ejectionVelocity: 3, + velocityVariance: 0.25, + emitterLifetime: 250, inheritedVelFactor: 0, particleOptions: { texture: 'particles/star.png', @@ -54,7 +54,7 @@ final bounceParticleOptions:ParticleEmitterOptions = { spinRandomMax: 90, lifetime: 500, lifetimeVariance: 100, - dragCoefficient: 0.5, + dragCoefficient: 1, acceleration: -2, colors: [new Vector(0.9, 0, 0, 1), new Vector(0.9, 0.9, 0, 1), new Vector(0.9, 0.9, 0, 0)], sizes: [0.25, 0.25, 0.25], diff --git a/src/ParticleSystem.hx b/src/ParticleSystem.hx index 9360d033..46ebc4b4 100644 --- a/src/ParticleSystem.hx +++ b/src/ParticleSystem.hx @@ -78,38 +78,55 @@ class Particle { return; } + var t = this.currentAge / (this.lifeTime / 1000); + + for (i in 1...4) { + if (this.o.times.length > i) { + if (this.o.times[i] >= t) { + var firstPart = t - this.o.times[i - 1]; + var total = this.o.times[i] - this.o.times[i - 1]; + + firstPart /= total; + + this.color = Util.lerpThreeVectors(this.o.colors[i - 1], this.o.colors[i], firstPart); + this.scale = Util.lerp(this.o.sizes[i - 1], this.o.sizes[i], firstPart); + break; + } + } + } + // var velElapsed = elapsed / 1000; - // velElapsed *= 0.001; + // // velElapsed *= 0.001; // velElapsed = Math.pow(velElapsed, (1 - this.o.dragCoefficient)); // Somehow slow down velocity over time based on the drag coefficient // // Compute the position - // var pos = this.position.add(this.vel.multiply(velElapsed + this.o.acceleration * (velElapsed * velElapsed) / 2)); - // this.position = pos; + // // var pos = this.position.add(this.vel.multiply(velElapsed + this.o.acceleration * (velElapsed * velElapsed) / 2)); + // // this.position = pos; - this.rotation = (this.initialSpin + this.o.spinSpeed * elapsed / 1000) * Math.PI / 180; + // this.rotation = (this.initialSpin + this.o.spinSpeed * elapsed / 1000) * Math.PI / 180; - // Check where we are in the times array - var indexLow = 0; - var indexHigh = 1; - for (i in 2...this.o.times.length) { - if (this.o.times[indexHigh] >= completion) - break; + // // Check where we are in the times array + // var indexLow = 0; + // var indexHigh = 1; + // for (i in 2...this.o.times.length) { + // if (this.o.times[indexHigh] >= completion) + // break; - indexLow = indexHigh; - indexHigh = i; - } + // indexLow = indexHigh; + // indexHigh = i; + // } - if (this.o.times.length == 1) - indexHigh = indexLow; - var t = (completion - this.o.times[indexLow]) / (this.o.times[indexHigh] - this.o.times[indexLow]); + // if (this.o.times.length == 1) + // indexHigh = indexLow; + // var t = (completion - this.o.times[indexLow]) / (this.o.times[indexHigh] - this.o.times[indexLow]); - // Adjust color - var color = Util.lerpThreeVectors(this.o.colors[indexLow], this.o.colors[indexHigh], t); - this.color = color; - // this.material.opacity = color.a * * 1.5; // Adjusted because additive mixing can be kind of extreme + // // Adjust color + // var color = Util.lerpThreeVectors(this.o.colors[indexLow], this.o.colors[indexHigh], t); + // this.color = color; + // // this.material.opacity = color.a * * 1.5; // Adjusted because additive mixing can be kind of extreme - // Adjust sizing - this.scale = Util.lerp(this.o.sizes[indexLow], this.o.sizes[indexHigh], t); + // // Adjust sizing + // this.scale = Util.lerp(this.o.sizes[indexLow], this.o.sizes[indexHigh], t); } } @@ -192,7 +209,7 @@ class ParticleEmitter { this.emit(time); } - public function tick(time:Float) { + public function tick(time:Float, dt:Float) { // Cap the amount of particles emitted in such a case to prevent lag if (time - this.lastEmitTime >= 1000) this.lastEmitTime = time - 1000; @@ -217,9 +234,12 @@ class ParticleEmitter { // This isn't necessarily uniform but it's fine for the purpose. var randomPointOnSphere = new Vector(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1).normalized(); // Compute the total velocity - var vel = this.vel.multiply(this.o.inheritedVelFactor) - .add(randomPointOnSphere.multiply(this.o.ejectionVelocity + this.o.velocityVariance * (Math.random() * 2 - 1))) - .add(this.o.ambientVelocity); + var initialVel = this.o.ejectionVelocity; + initialVel += (this.o.velocityVariance * 2 * Math.random()) - this.o.velocityVariance; + var vel = this.vel.multiply(this.o.inheritedVelFactor).add(randomPointOnSphere.multiply(initialVel)).add(this.o.ambientVelocity); + // var vel = this.vel.multiply(this.o.inheritedVelFactor) + // .add(randomPointOnSphere.multiply(this.o.ejectionVelocity + this.o.velocityVariance * (Math.random() * 2 - 1))) + // .add(this.o.ambientVelocity); var particle = new Particle(this.o.particleOptions, this.manager, this.data, time, pos, vel); this.manager.addParticle(data, particle); } @@ -260,7 +280,7 @@ class ParticleManager { for (instance in batch.instances) instance.update(currentTime, dt); } - this.tick(); + this.tick(dt); for (obj => batch in particlebatches) { batch.meshBatch.begin(batch.instances.length); for (instance in batch.instances) { @@ -348,12 +368,12 @@ class ParticleManager { this.removeEmitter(emitter); } - public function tick() { + public function tick(dt:Float) { var time = this.getTime(); for (emitter in this.emitters) { if (emitter.getPos != null) emitter.setPos(emitter.getPos(), time); - emitter.tick(time); + emitter.tick(time, dt); // Remove the artifact that was created in a different future cause we rewinded and now we shifted timelines if (emitter.creationTime > time) { this.removeEmitter(emitter); diff --git a/src/collision/CollisionHull.hx b/src/collision/CollisionHull.hx index a6d36a9a..47ff5c52 100644 --- a/src/collision/CollisionHull.hx +++ b/src/collision/CollisionHull.hx @@ -8,9 +8,10 @@ import h3d.Vector; class CollisionHull extends CollisionEntity { var hull:ConvexHull; - var friction = 1.0; - var restitution = 1.0; - var force = 0.0; + + public var friction = 1.0; + public var restitution = 1.0; + public var force = 0.0; public function new(go:GameObject) { super(go); diff --git a/src/shapes/LandMine.hx b/src/shapes/LandMine.hx index ebe706e8..eddf49da 100644 --- a/src/shapes/LandMine.hx +++ b/src/shapes/LandMine.hx @@ -1,5 +1,6 @@ package shapes; +import collision.CollisionHull; import collision.CollisionInfo; import src.DtsObject; import src.Util; @@ -9,9 +10,9 @@ import h3d.Vector; import src.ResourceLoader; final landMineParticle:ParticleEmitterOptions = { - ejectionPeriod: 0.2, + ejectionPeriod: 2, ambientVelocity: new Vector(0, 0, 0), - ejectionVelocity: 2, + ejectionVelocity: 3, velocityVariance: 1, emitterLifetime: 50, inheritedVelFactor: 0.2, @@ -23,7 +24,7 @@ final landMineParticle:ParticleEmitterOptions = { spinRandomMax: 90, lifetime: 1000, lifetimeVariance: 150, - dragCoefficient: 0.8, + dragCoefficient: 2, acceleration: 0, colors: [new Vector(0.56, 0.36, 0.26, 1), new Vector(0.56, 0.36, 0.26, 0)], sizes: [0.5, 1], @@ -32,11 +33,11 @@ final landMineParticle:ParticleEmitterOptions = { }; final landMineSmokeParticle:ParticleEmitterOptions = { - ejectionPeriod: 0.5, + ejectionPeriod: 2, ambientVelocity: new Vector(0, 0, 0), - ejectionVelocity: 0.8, - velocityVariance: 0.4, - emitterLifetime: 50, + ejectionVelocity: 4, + velocityVariance: 0.5, + emitterLifetime: 250, inheritedVelFactor: 0.25, particleOptions: { texture: 'particles/smoke.png', @@ -46,7 +47,7 @@ final landMineSmokeParticle:ParticleEmitterOptions = { spinRandomMax: 90, lifetime: 1200, lifetimeVariance: 300, - dragCoefficient: 0.85, + dragCoefficient: 10, acceleration: -8, colors: [ new Vector(0.56, 0.36, 0.26, 1), @@ -59,10 +60,10 @@ final landMineSmokeParticle:ParticleEmitterOptions = { }; final landMineSparksParticle:ParticleEmitterOptions = { - ejectionPeriod: 0.4, + ejectionPeriod: 3, ambientVelocity: new Vector(0, 0, 0), - ejectionVelocity: 13 / 4, - velocityVariance: 6.75 / 4, + ejectionVelocity: 13, + velocityVariance: 6.75, emitterLifetime: 100, inheritedVelFactor: 0.2, particleOptions: { @@ -73,8 +74,8 @@ final landMineSparksParticle:ParticleEmitterOptions = { spinRandomMax: 90, lifetime: 500, lifetimeVariance: 350, - dragCoefficient: 0.75, - acceleration: -8, + dragCoefficient: 1, + acceleration: 0, colors: [ new Vector(0.6, 0.4, 0.3, 1), new Vector(0.6, 0.4, 0.3, 1), @@ -111,6 +112,23 @@ class LandMine extends DtsObject { landMineSparkParticleData.texture = ResourceLoader.getTexture("data/particles/spark.png"); } + override function onMarbleContact(time:Float, ?contact:CollisionInfo) { + if (this.isCollideable) { + // marble.velocity = marble.velocity.add(vec); + this.disappearTime = this.level.currentTime; + this.setCollisionEnabled(false); + + // if (!this.level.rewinding) + // AudioManager.play(this.sounds[0]); + this.level.particleManager.createEmitter(landMineParticle, landMineParticleData, this.getAbsPos().getPosition()); + this.level.particleManager.createEmitter(landMineSmokeParticle, landMineSmokeParticleData, this.getAbsPos().getPosition()); + this.level.particleManager.createEmitter(landMineSparksParticle, landMineSparkParticleData, this.getAbsPos().getPosition()); + } + // Normally, we would add a light here, but that's too expensive for THREE, apparently. + + // this.level.replay.recordMarbleContact(this); + } + function computeExplosionStrength(r:Float) { // Figured out through testing by RandomityGuy if (r >= 10.25) @@ -125,29 +143,6 @@ class LandMine extends DtsObject { return v; } - override function onMarbleContact(time:Float, ?contact:CollisionInfo) { - var marble = this.level.marble; - var minePos = this.getAbsPos().getPosition(); - var off = marble.getAbsPos().getPosition().sub(minePos); - var vec = off.normalized(); // Use the last pos so that it's a little less RNG - - // Add velocity to the marble - var explosionStrength = this.computeExplosionStrength(off.length()); - marble.velocity = marble.velocity.add(vec.multiply(explosionStrength)); - this.disappearTime = level.currentTime; - this.isCollideable = false; - // this.setCollisionEnabled(false); - - // if (!this.level.rewinding) - // AudioManager.play(this.sounds[0]); - this.level.particleManager.createEmitter(landMineParticle, landMineParticleData, this.getAbsPos().getPosition()); - this.level.particleManager.createEmitter(landMineSmokeParticle, landMineSmokeParticleData, this.getAbsPos().getPosition()); - this.level.particleManager.createEmitter(landMineSparksParticle, landMineSparkParticleData, this.getAbsPos().getPosition()); - // Normally, we would add a light here, but that's too expensive for THREE, apparently. - - // this.level.replay.recordMarbleContact(this); - } - override function update(currentTime:Float, dt:Float) { super.update(currentTime, dt); if (currentTime >= this.disappearTime + 5 || currentTime < this.disappearTime) { @@ -156,6 +151,19 @@ class LandMine extends DtsObject { this.setHide(true); } + if (this.isCollideable) { + var marble = this.level.marble; + var minePos = this.getAbsPos().getPosition(); + var off = marble.getAbsPos().getPosition().sub(minePos); + + var strength = computeExplosionStrength(off.length()); + + for (collider in this.colliders) { + var hull:CollisionHull = cast collider; + hull.force = strength; + } + } + var opacity = Util.clamp((currentTime - (this.disappearTime + 5)), 0, 1); this.setOpacity(opacity); } diff --git a/src/shapes/SuperJump.hx b/src/shapes/SuperJump.hx index 57852d59..d01da720 100644 --- a/src/shapes/SuperJump.hx +++ b/src/shapes/SuperJump.hx @@ -8,8 +8,8 @@ import src.DtsObject; final superJumpParticleOptions:src.ParticleSystem.ParticleEmitterOptions = { ejectionPeriod: 10, ambientVelocity: new Vector(0, 0, 0.05), - ejectionVelocity: 1 * 0.5, - velocityVariance: 0.25 * 0.5, + ejectionVelocity: 0.5, + velocityVariance: 0.125, emitterLifetime: 1000, inheritedVelFactor: 0.1, particleOptions: { @@ -22,7 +22,7 @@ final superJumpParticleOptions:src.ParticleSystem.ParticleEmitterOptions = { lifetimeVariance: 150, dragCoefficient: 0.25, acceleration: 0, - colors: [new Vector(0, 0.5, 1, 0), new Vector(0, 0.6, 1, 1), new Vector(0, 0.5, 1, 0)], + colors: [new Vector(0, 0.5, 1, 0), new Vector(0, 0.6, 1, 1), new Vector(0, 0.6, 1, 0)], sizes: [0.25, 0.25, 0.5], times: [0, 0.75, 1] } diff --git a/src/shapes/SuperSpeed.hx b/src/shapes/SuperSpeed.hx index ed79cbea..524ac5ff 100644 --- a/src/shapes/SuperSpeed.hx +++ b/src/shapes/SuperSpeed.hx @@ -10,8 +10,8 @@ import src.DtsObject; final superSpeedParticleOptions:ParticleEmitterOptions = { ejectionPeriod: 5, ambientVelocity: new Vector(0, 0, 0.2), - ejectionVelocity: 1 * 0.5, - velocityVariance: 0.25 * 0.5, + ejectionVelocity: 1, + velocityVariance: 0.25, emitterLifetime: 1100, inheritedVelFactor: 0.25, particleOptions: {