rewind support for everything else

This commit is contained in:
RandomityGuy 2023-05-07 19:25:38 +05:30
parent 35d215412f
commit 3aaa419bd4
5 changed files with 92 additions and 4 deletions

View file

@ -30,6 +30,8 @@ class Main extends hxd.App {
var frameByFrame:Bool = false;
// var timeAccumulator:Float = 0.0;
override function init() {
super.init();
@ -119,6 +121,11 @@ class Main extends hxd.App {
ProfilerUI.measure("updateBegin");
// try {
// timeAccumulator += dt;
// while (timeAccumulator > 1 / 60) {
// marbleGame.update(1 / 60);
// timeAccumulator -= 1 / 60;
// }
marbleGame.update(dt);
// } catch (e) {
// Console.error(e.message);

View file

@ -1811,7 +1811,7 @@ class Marble extends GameObject {
this.omega = expectedOmega;
}
if (this.controllable) {
if (this.controllable && !this.level.rewinding) {
this.camera.update(timeState.currentAttemptTime, timeState.dt);
}

View file

@ -1014,9 +1014,9 @@ class MarbleWorld extends Scheduler {
}
if (this.rewinding) {
var rframe = rewindManager.getNextRewindFrame(timeState.currentAttemptTime - dt);
var rframe = rewindManager.getNextRewindFrame(timeState.currentAttemptTime - dt * rewindManager.timeScale);
if (rframe != null) {
var actualDt = timeState.currentAttemptTime - rframe.timeState.currentAttemptTime - dt;
var actualDt = timeState.currentAttemptTime - rframe.timeState.currentAttemptTime - dt * rewindManager.timeScale;
dt = actualDt;
rewindManager.applyFrame(rframe);
}
@ -1084,11 +1084,15 @@ class MarbleWorld extends Scheduler {
for (marble in marbles) {
marble.update(timeState, collisionWorld, this.pathedInteriors);
}
if (this.rewinding) {
// Update camera separately
marble.camera.update(timeState.currentAttemptTime, realDt);
}
ProfilerUI.measure("updateInstances");
this.instanceManager.render();
ProfilerUI.measure("updateParticles");
if (this.rewinding) {
this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt);
this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt * rewindManager.timeScale);
} else
this.particleManager.update(1000 * timeState.timeSinceLoad, dt);
ProfilerUI.measure("updatePlayGui");

View file

@ -1,10 +1,14 @@
package rewind;
import mis.MissionElement.MissionElementBase;
import triggers.CheckpointTrigger;
import src.PathedInterior.PIState;
import shapes.PowerUp;
import h3d.Vector;
import h3d.Quat;
import src.TimeState;
import src.DtsObject;
import shapes.Gem;
@:publicFields
class RewindFrame {
@ -29,6 +33,20 @@ class RewindFrame {
var currentUp:Vector;
var trapdoorStates:Array<{lastContactTime:Float, lastDirection:Int, lastCompletion:Float}>;
var lastContactNormal:Vector;
var blastAmt:Float;
var oobState:{
oob:Bool,
timeState:TimeState
};
var checkpointState:{
currentCheckpoint:{obj:DtsObject, elem:MissionElementBase},
currentCheckpointTrigger:CheckpointTrigger,
checkpointCollectedGems:Map<Gem, Bool>,
checkpointHeldPowerup:PowerUp,
checkpointUp:Vector,
checkpointBlast:Float
};
public function new() {}
@ -79,5 +97,21 @@ class RewindFrame {
lastCompletion: s.lastCompletion,
});
}
c.blastAmt = blastAmt;
c.oobState = {
oob: oobState.oob,
timeState: oobState.timeState.clone()
};
c.checkpointState = {
currentCheckpoint: checkpointState.currentCheckpoint != null ? {
obj: checkpointState.currentCheckpoint.obj,
elem: checkpointState.currentCheckpoint.elem,
} : null,
currentCheckpointTrigger: checkpointState.currentCheckpointTrigger,
checkpointCollectedGems: checkpointState.checkpointCollectedGems.copy(),
checkpointHeldPowerup: checkpointState.checkpointHeldPowerup,
checkpointUp: checkpointState.checkpointUp != null ? checkpointState.checkpointUp.clone() : null,
checkpointBlast: checkpointState.checkpointBlast,
};
}
}

View file

@ -4,12 +4,16 @@ import shapes.PowerUp;
import shapes.LandMine;
import src.MarbleWorld;
import shapes.Trapdoor;
import shapes.PushButton;
import src.Util;
import shapes.Nuke;
class RewindManager {
var frames:Array<RewindFrame> = [];
var level:MarbleWorld;
public var timeScale:Float = 1;
public function new(level:MarbleWorld) {
this.level = level;
}
@ -63,10 +67,18 @@ class RewindManager {
var pow:PowerUp = cast dts;
rf.powerupStates.push(pow.lastPickUpTime);
}
if (dts is PushButton) {
var pow:PushButton = cast dts;
rf.powerupStates.push(pow.lastContactTime);
}
if (dts is LandMine) {
var lm:LandMine = cast dts;
rf.landMineStates.push(lm.disappearTime);
}
if (dts is Nuke) {
var lm:Nuke = cast dts;
rf.landMineStates.push(lm.disappearTime);
}
if (dts is Trapdoor) {
var td:Trapdoor = cast dts;
rf.trapdoorStates.push({
@ -76,6 +88,19 @@ class RewindManager {
});
}
}
rf.blastAmt = level.blastAmount;
rf.oobState = {
oob: level.outOfBounds,
timeState: level.outOfBoundsTime != null ? level.outOfBoundsTime.clone() : null
};
rf.checkpointState = {
currentCheckpoint: @:privateAccess level.currentCheckpoint,
currentCheckpointTrigger: @:privateAccess level.currentCheckpointTrigger,
checkpointBlast: @:privateAccess level.cheeckpointBlast,
checkpointCollectedGems: @:privateAccess level.checkpointCollectedGems.copy(),
checkpointHeldPowerup: @:privateAccess level.checkpointHeldPowerup,
checkpointUp: @:privateAccess level.checkpointUp != null ? @:privateAccess level.checkpointUp.clone() : null,
};
frames.push(rf);
}
@ -159,10 +184,18 @@ class RewindManager {
var pow:PowerUp = cast dts;
pow.lastPickUpTime = pstates.shift();
}
if (dts is PushButton) {
var pow:PushButton = cast dts;
pow.lastContactTime = pstates.shift();
}
if (dts is LandMine) {
var lm:LandMine = cast dts;
lm.disappearTime = lmstates.shift();
}
if (dts is Nuke) {
var lm:Nuke = cast dts;
lm.disappearTime = lmstates.shift();
}
if (dts is Trapdoor) {
var td:Trapdoor = cast dts;
var tdState = tstates.shift();
@ -171,6 +204,16 @@ class RewindManager {
td.lastContactTime = tdState.lastContactTime;
}
}
level.outOfBounds = rf.oobState.oob;
level.marble.camera.oob = rf.oobState.oob;
level.outOfBoundsTime = rf.oobState.timeState != null ? rf.oobState.timeState.clone() : null;
level.blastAmount = rf.blastAmt;
@:privateAccess level.checkpointUp = rf.checkpointState.checkpointUp;
@:privateAccess level.checkpointCollectedGems = rf.checkpointState.checkpointCollectedGems;
@:privateAccess level.cheeckpointBlast = rf.checkpointState.checkpointBlast;
@:privateAccess level.checkpointHeldPowerup = rf.checkpointState.checkpointHeldPowerup;
@:privateAccess level.currentCheckpoint = rf.checkpointState.currentCheckpoint;
@:privateAccess level.currentCheckpointTrigger = rf.checkpointState.currentCheckpointTrigger;
}
public function getNextRewindFrame(absTime:Float):RewindFrame {