mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
rewind support for everything else
This commit is contained in:
parent
35d215412f
commit
3aaa419bd4
5 changed files with 92 additions and 4 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue