add rewind options

This commit is contained in:
RandomityGuy 2023-05-13 21:49:05 +05:30
parent 1f7b117753
commit 497579089f
17 changed files with 138 additions and 62 deletions

View file

@ -43,6 +43,7 @@ typedef OptionsSettings = {
var marbleModel:String; var marbleModel:String;
var marbleShader:String; var marbleShader:String;
var rewindEnabled:Bool; var rewindEnabled:Bool;
var rewindTimescale:Float;
} }
typedef ControlsSettings = { typedef ControlsSettings = {
@ -122,6 +123,7 @@ class Settings {
marbleModel: "data/shapes/balls/ball-superball.dts", marbleModel: "data/shapes/balls/ball-superball.dts",
marbleShader: "Default", marbleShader: "Default",
rewindEnabled: false, rewindEnabled: false,
rewindTimescale: 1,
vsync: #if js true #end vsync: #if js true #end
#if hl #if hl
false false
@ -339,6 +341,8 @@ class Settings {
optionsSettings.fovX = 90; optionsSettings.fovX = 90;
if (optionsSettings.rewindEnabled == false #if js || optionsSettings.rewindEnabled == null #end) if (optionsSettings.rewindEnabled == false #if js || optionsSettings.rewindEnabled == null #end)
optionsSettings.rewindEnabled = false; optionsSettings.rewindEnabled = false;
if (optionsSettings.rewindTimescale == 0 #if js || optionsSettings.rewindTimescale == null #end)
optionsSettings.rewindTimescale = 1;
controlsSettings = json.controls; controlsSettings = json.controls;
if (json.touch != null) { if (json.touch != null) {
touchSettings = json.touch; touchSettings = json.touch;
@ -383,6 +387,9 @@ class Settings {
if (optionsSettings.rewindEnabled == null) { if (optionsSettings.rewindEnabled == null) {
optionsSettings.rewindEnabled = false; optionsSettings.rewindEnabled = false;
} }
if (optionsSettings.rewindTimescale == null) {
optionsSettings.rewindTimescale = 1;
}
#end #end
highscoreName = json.highscoreName; highscoreName = json.highscoreName;
} else { } else {

View file

@ -67,7 +67,6 @@ class EndGameGui extends GuiControl {
var nextLevelPreview = new GuiImage(tmpprevtile); var nextLevelPreview = new GuiImage(tmpprevtile);
nextLevelPreview.position = new Vector(-15, 0); nextLevelPreview.position = new Vector(-15, 0);
nextLevelPreview.extent = new Vector(160, 110); nextLevelPreview.extent = new Vector(160, 110);
nextLevelPreview.doClipping = true;
nextLevel.addChild(nextLevelPreview); nextLevel.addChild(nextLevelPreview);
mission.getNextMission().getPreviewImage(t -> { mission.getNextMission().getPreviewImage(t -> {

View file

@ -37,7 +37,7 @@ class GuiButton extends GuiAnim {
} }
public override function update(dt:Float, mouseState:MouseState) { public override function update(dt:Float, mouseState:MouseState) {
var renderRect = getRenderRectangle(); var renderRect = getHitTestRect();
if (renderRect.inRect(mouseState.position) && !disabled) { if (renderRect.inRect(mouseState.position) && !disabled) {
if (buttonSounds && Key.isPressed(Key.MOUSE_LEFT)) { if (buttonSounds && Key.isPressed(Key.MOUSE_LEFT)) {
AudioManager.playSound(ResourceLoader.getResource("data/sound/buttonpress.wav", ResourceLoader.getAudio, this.soundResources)); AudioManager.playSound(ResourceLoader.getResource("data/sound/buttonpress.wav", ResourceLoader.getAudio, this.soundResources));
@ -73,8 +73,7 @@ class GuiButton extends GuiAnim {
} }
} }
if (!disabled) { if (!disabled) {
if (acceleratorWasPressed && if (acceleratorWasPressed && (accelerator != 0 && hxd.Key.isReleased(accelerator)) || Gamepad.isReleased(gamepadAccelerator)) {
(accelerator != 0 && hxd.Key.isReleased(accelerator)) || Gamepad.isReleased(gamepadAccelerator)) {
if (this.pressedAction != null) { if (this.pressedAction != null) {
this.pressedAction(new GuiEvent(this)); this.pressedAction(new GuiEvent(this));
} }

View file

@ -1,5 +1,6 @@
package gui; package gui;
import format.abc.Data.ABCData;
import h2d.Flow; import h2d.Flow;
import hxd.res.Image; import hxd.res.Image;
import h2d.Graphics; import h2d.Graphics;
@ -58,12 +59,20 @@ class GuiControl {
var _flow:Flow; var _flow:Flow;
var _manualScroll = false;
// var _border:h2d.Graphics = null;
public function new() {} public function new() {}
public function render(scene2d:Scene, ?parent:Flow) { public function render(scene2d:Scene, ?parent:Flow) {
if (this._flow == null) { if (this._flow == null) {
this._flow = new Flow(parent != null ? parent : scene2d); this._flow = new Flow(parent != null ? parent : scene2d);
// this._flow.debug = true;
} }
// if (_border == null) {
// _border = new h2d.Graphics(scene2d);
// }
if (parent == null) { if (parent == null) {
if (scene2d.contains(this._flow)) { if (scene2d.contains(this._flow)) {
scene2d.removeChild(this._flow); scene2d.removeChild(this._flow);
@ -98,7 +107,10 @@ class GuiControl {
public function update(dt:Float, mouseState:MouseState) { public function update(dt:Float, mouseState:MouseState) {
if (!_skipNextEvent) { if (!_skipNextEvent) {
var hitTestRect = getHitTestRect(); var hitTestRect = getHitTestRect(!_manualScroll);
// _border.clear();
// _border.lineStyle(2, 0x0000FF);
// _border.drawRect(hitTestRect.position.x, hitTestRect.position.y, hitTestRect.extent.x, hitTestRect.extent.y);
if (hitTestRect.inRect(mouseState.position)) { if (hitTestRect.inRect(mouseState.position)) {
if (Key.isPressed(Key.MOUSE_LEFT)) { if (Key.isPressed(Key.MOUSE_LEFT)) {
mouseState.button = Key.MOUSE_LEFT; mouseState.button = Key.MOUSE_LEFT;
@ -226,12 +238,21 @@ class GuiControl {
return rect; return rect;
} }
public function getHitTestRect() { public function getHitTestRect(useScroll:Bool = true) {
var thisRect = this.getRenderRectangle(); var thisRect = this.getRenderRectangle();
if (useScroll)
thisRect.position.y -= thisRect.scroll.y;
if (this.parent == null) if (this.parent == null)
return thisRect; return thisRect;
else { else {
return thisRect.intersect(this.parent.getRenderRectangle()); var parRect = this.parent.getRenderRectangle();
// parRect.position.y -= parRect.scroll.y;
var rr = thisRect.intersect(parRect);
if (useScroll) {
thisRect.position.y -= thisRect.scroll.y;
rr.scroll.y = thisRect.scroll.y;
}
return rr;
} }
} }
@ -313,6 +334,7 @@ class GuiControl {
} }
public function dispose() { public function dispose() {
this._flow.remove();
for (c in this.children) { for (c in this.children) {
c.dispose(); c.dispose();
} }

View file

@ -36,43 +36,13 @@ class GuiImage extends GuiControl {
} }
super.render(scene2d, parent); super.render(scene2d, parent);
var renderRect = this.getRenderRectangle(); var renderRect = this.getRenderRectangle();
// var hittestRect = this.getHitTestRect();
// var obj:h2d.Object = bmp;
// if (doClipping) {
// bmpFlow = new Flow();
// bmpFlow.addChild(bmp);
// bmpFlow.overflow = FlowOverflow.Hidden;
// bmpFlow.multiline = true;
// bmpFlow.setPosition(hittestRect.position.x, hittestRect.position.y);
// obj = bmpFlow;
// }
// if (doClipping) {
// var fp = bmpFlow.getProperties(bmp);
// fp.offsetX = -Std.int(hittestRect.position.x - renderRect.position.x);
// fp.offsetY = -Std.int(hittestRect.position.y - renderRect.position.y);
// } else {
// bmp.setPosition(Math.floor(renderRect.position.x), Math.floor(renderRect.position.y));
// }
bmp.width = renderRect.extent.x; bmp.width = renderRect.extent.x;
bmp.height = renderRect.extent.y; bmp.height = renderRect.extent.y;
// if (doClipping) {
// bmpFlow.maxWidth = Std.int(hittestRect.extent.x);
// bmpFlow.maxHeight = Std.int(hittestRect.extent.y);
// }
// if (scene2d.contains(obj)) {
// scene2d.removeChild(obj); // Refresh "layer"
// }
// scene2d.addChild(obj);
} }
public override function dispose() { public override function dispose() {
super.dispose(); super.dispose();
if (this.doClipping) { this.bmp.remove();
bmpFlow.remove();
} else
this.bmp.remove();
} }
public override function onMouseRelease(mouseState:MouseState) { public override function onMouseRelease(mouseState:MouseState) {

View file

@ -28,6 +28,7 @@ class GuiMLText extends GuiControl {
super(); super();
this.text = new HtmlText(font); this.text = new HtmlText(font);
this.text.loadFont = loadFontFunc; this.text.loadFont = loadFontFunc;
this._manualScroll = true;
} }
public override function render(scene2d:Scene, ?parent:h2d.Flow) { public override function render(scene2d:Scene, ?parent:h2d.Flow) {

View file

@ -12,6 +12,8 @@ import src.Util;
class GuiScrollCtrl extends GuiControl { class GuiScrollCtrl extends GuiControl {
public var scrollY:Float = 0; public var scrollY:Float = 0;
public var enabled:Bool = true;
public var childrenHandleScroll:Bool = false;
var maxScrollY:Float; var maxScrollY:Float;
@ -35,6 +37,10 @@ class GuiScrollCtrl extends GuiControl {
var dirty:Bool = true; var dirty:Bool = true;
var prevMousePos:Vector; var prevMousePos:Vector;
var _contentYPositions:Map<h2d.Object, Float> = [];
var deltaY:Float = 0;
public function new(scrollBar:Tile) { public function new(scrollBar:Tile) {
super(); super();
this.scrollTopTile = scrollBar.sub(0, 4, 10, 6); this.scrollTopTile = scrollBar.sub(0, 4, 10, 6);
@ -53,7 +59,7 @@ class GuiScrollCtrl extends GuiControl {
this.scrollBarY.scale(Settings.uiScale); this.scrollBarY.scale(Settings.uiScale);
this.clickInteractive = new Interactive(10 * Settings.uiScale, 1); this.clickInteractive = new Interactive(10 * Settings.uiScale, 1);
this.clickInteractive.onPush = (e) -> { this.clickInteractive.onPush = (e) -> {
if (!this.pressed) { if (!this.pressed && enabled) {
this.pressed = true; this.pressed = true;
this.dirty = true; this.dirty = true;
this.updateScrollVisual(); this.updateScrollVisual();
@ -63,12 +69,14 @@ class GuiScrollCtrl extends GuiControl {
this.clickInteractive.startCapture(e2 -> { this.clickInteractive.startCapture(e2 -> {
if (e2.kind == ERelease) { if (e2.kind == ERelease) {
this.clickInteractive.stopCapture(); this.clickInteractive.stopCapture();
deltaY = 0;
} }
if (e2.kind == EMove) { if (e2.kind == EMove) {
if (prevEY == null) { if (prevEY == null) {
prevEY = e2.relY; prevEY = e2.relY;
} else { } else {
this.scrollY += (e2.relY - prevEY); this.scrollY += (e2.relY - prevEY);
deltaY = (e2.relY - prevEY);
prevEY = e2.relY; prevEY = e2.relY;
this.updateScrollVisual(); this.updateScrollVisual();
} }
@ -77,6 +85,7 @@ class GuiScrollCtrl extends GuiControl {
if (this.pressed) { if (this.pressed) {
this.pressed = false; this.pressed = false;
this.dirty = true; this.dirty = true;
deltaY = 0;
this.updateScrollVisual(); this.updateScrollVisual();
} }
}); });
@ -112,6 +121,10 @@ class GuiScrollCtrl extends GuiControl {
updateScrollVisual(); updateScrollVisual();
super.render(scene2d, parent); super.render(scene2d, parent);
for (i in 0...this._flow.numChildren) {
var ch = this._flow.getChildAt(i);
_contentYPositions.set(ch, ch.y);
}
} }
public function updateScrollVisual() { public function updateScrollVisual() {
@ -166,6 +179,17 @@ class GuiScrollCtrl extends GuiControl {
for (c in this.children) { for (c in this.children) {
c.onScroll(0, scrollY * this.maxScrollY / renderRect.extent.y); c.onScroll(0, scrollY * this.maxScrollY / renderRect.extent.y);
} }
if (this._flow != null && !childrenHandleScroll) {
var actualDelta = deltaY;
if (scrollY != scrollYOld) {
actualDelta -= (scrollYOld - scrollY);
}
for (i in 0...this._flow.numChildren) {
var ch = this._flow.getChildAt(i);
ch.y -= cast actualDelta * this.maxScrollY / renderRect.extent.y;
}
}
} }
public override function dispose() { public override function dispose() {

View file

@ -15,7 +15,7 @@ class GuiSlider extends GuiImage {
public var enabled:Bool = true; public var enabled:Bool = true;
public override function update(dt:Float, mouseState:MouseState) { public override function update(dt:Float, mouseState:MouseState) {
var renderRect = getRenderRectangle(); var renderRect = getHitTestRect();
if (renderRect.inRect(mouseState.position) && enabled) { if (renderRect.inRect(mouseState.position) && enabled) {
if (Key.isDown(Key.MOUSE_LEFT)) { if (Key.isDown(Key.MOUSE_LEFT)) {
sliderValue = (mouseState.position.x - renderRect.position.x - bmp.width / 2) / renderRect.extent.x; sliderValue = (mouseState.position.x - renderRect.position.x - bmp.width / 2) / renderRect.extent.x;

View file

@ -38,6 +38,7 @@ class GuiTextListCtrl extends GuiControl {
super(); super();
this.font = font; this.font = font;
this.texts = texts; this.texts = texts;
this._manualScroll = true;
this.textObjs = []; this.textObjs = [];
for (text in texts) { for (text in texts) {
var tobj = new Text(font); var tobj = new Text(font);
@ -89,7 +90,7 @@ class GuiTextListCtrl extends GuiControl {
public override function render(scene2d:Scene, ?parent:h2d.Flow) { public override function render(scene2d:Scene, ?parent:h2d.Flow) {
var renderRect = this.getRenderRectangle(); var renderRect = this.getRenderRectangle();
var htr = this.getHitTestRect(); var htr = this.getHitTestRect(false);
if (parent != null) { if (parent != null) {
if (parent.contains(g)) if (parent.contains(g))
@ -270,7 +271,7 @@ class GuiTextListCtrl extends GuiControl {
var renderRect = this.getRenderRectangle(); var renderRect = this.getRenderRectangle();
this.scroll = scrollY; this.scroll = scrollY;
var hittestrect = this.getHitTestRect(); var hittestrect = this.getHitTestRect(false);
for (i in 0...textObjs.length) { for (i in 0...textObjs.length) {
var text = textObjs[i]; var text = textObjs[i];
text.y = Math.floor((i * (text.font.size + 4) + 5 + textYOffset * Settings.uiScale - scrollY)); text.y = Math.floor((i * (text.font.size + 4) + 5 + textYOffset * Settings.uiScale - scrollY));

View file

@ -66,6 +66,7 @@ class JukeboxDlg extends GuiImage {
var scroll = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile()); var scroll = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile());
scroll.position = new Vector(51, 39); scroll.position = new Vector(51, 39);
scroll.extent = new Vector(439, 216); scroll.extent = new Vector(439, 216);
scroll.childrenHandleScroll = true;
this.addChild(scroll); this.addChild(scroll);
var songCtrl = new GuiTextListCtrl(markerFelt24, songList); var songCtrl = new GuiTextListCtrl(markerFelt24, songList);

View file

@ -68,7 +68,10 @@ class OptionsDlg extends GuiImage {
onlineBtn.extent = new Vector(134, 65); onlineBtn.extent = new Vector(134, 65);
window.addChild(onlineBtn); window.addChild(onlineBtn);
var generalPanel:GuiScrollCtrl = null;
var applyFunc:Void->Void = () -> { var applyFunc:Void->Void = () -> {
generalPanel.scrollY = 0;
Settings.applySettings(); Settings.applySettings();
}; };
@ -89,9 +92,10 @@ class OptionsDlg extends GuiImage {
} }
window.addChild(applyBtn); window.addChild(applyBtn);
var generalPanel = new GuiControl(); generalPanel = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile());
generalPanel.position = new Vector(30, 88); generalPanel.position = new Vector(30, 88);
generalPanel.extent = new Vector(726, 394); generalPanel.extent = new Vector(726, 364);
generalPanel.maxScrollY = 394;
window.addChild(generalPanel); window.addChild(generalPanel);
var currentTab = "general"; var currentTab = "general";
@ -130,6 +134,8 @@ class OptionsDlg extends GuiImage {
var dropdownparent = currentDropDown.parent; var dropdownparent = currentDropDown.parent;
currentDropDown.parent.removeChild(currentDropDown); currentDropDown.parent.removeChild(currentDropDown);
currentDropDown = null; currentDropDown = null;
if (dropdownparent is GuiScrollCtrl)
cast(dropdownparent, GuiScrollCtrl).enabled = true;
haxe.Timer.delay(() -> setAllBtnState(true), 5); // delay this a bit to avoid update(); haxe.Timer.delay(() -> setAllBtnState(true), 5); // delay this a bit to avoid update();
} }
} }
@ -147,6 +153,8 @@ class OptionsDlg extends GuiImage {
var optDropdownImg = new GuiImage(ResourceLoader.getResource('data/ui/options/dropdown-${size}.png', ResourceLoader.getImage, this.imageResources) var optDropdownImg = new GuiImage(ResourceLoader.getResource('data/ui/options/dropdown-${size}.png', ResourceLoader.getImage, this.imageResources)
.toTile()); .toTile());
var dropDownYPos = yPos + 39;
optDropdownImg.position = new Vector(right ? 552 : 222, yPos + 39); optDropdownImg.position = new Vector(right ? 552 : 222, yPos + 39);
optDropdownImg.extent = new Vector(163, 79 + switch (size) { optDropdownImg.extent = new Vector(163, 79 + switch (size) {
case 'small': 0; case 'small': 0;
@ -163,16 +171,24 @@ class OptionsDlg extends GuiImage {
optDropdown.txtCtrl.text.textColor = 0; optDropdown.txtCtrl.text.textColor = 0;
optDropdown.pressedAction = (sender) -> { optDropdown.pressedAction = (sender) -> {
if (currentDropDown == null) { if (currentDropDown == null) {
var pScroll = parent.getRenderRectangle();
optDropdownImg.position.y = dropDownYPos - pScroll.scroll.y;
parent.addChild(optDropdownImg); parent.addChild(optDropdownImg);
optDropdownImg.render(MarbleGame.canvas.scene2d, @:privateAccess parent._flow); optDropdownImg.render(MarbleGame.canvas.scene2d, @:privateAccess parent._flow);
currentDropDown = optDropdownImg; currentDropDown = optDropdownImg;
if (parent is GuiScrollCtrl)
cast(parent, GuiScrollCtrl).enabled = false;
setAllBtnState(false); setAllBtnState(false);
return; return;
} }
if (currentDropDown == optDropdownImg) { if (currentDropDown == optDropdownImg) {
parent.removeChild(optDropdownImg); parent.removeChild(optDropdownImg);
currentDropDown = null; currentDropDown = null;
haxe.Timer.delay(() -> setAllBtnState(true), 5); // delay this a bit to avoid update(); haxe.Timer.delay(() -> {
setAllBtnState(true);
if (parent is GuiScrollCtrl)
cast(parent, GuiScrollCtrl).enabled = true;
}, 5); // delay this a bit to avoid update();
return; return;
} }
} }
@ -187,7 +203,7 @@ class OptionsDlg extends GuiImage {
case 'xlarge': 97; case 'xlarge': 97;
default: 0; default: 0;
}); });
// optDropdownList.scrollable = true; optDropdownList.scrollable = true;
optDropdownList.textYOffset = -5; optDropdownList.textYOffset = -5;
optDropdownList.onSelectedFunc = (idx) -> { optDropdownList.onSelectedFunc = (idx) -> {
onSelect(idx); onSelect(idx);
@ -224,7 +240,9 @@ class OptionsDlg extends GuiImage {
optSliders.push(optSlider); optSliders.push(optSlider);
} }
makeOption("Screen Resolution:", () -> '${Settings.optionsSettings.screenWidth} x ${Settings.optionsSettings.screenHeight}', 18, generalPanel, var yPos = 18;
makeOption("Screen Resolution:", () -> '${Settings.optionsSettings.screenWidth} x ${Settings.optionsSettings.screenHeight}', yPos, generalPanel,
"xlarge", [ "xlarge", [
"1024 x 800", "1024 x 800",
"1280 x 720", "1280 x 720",
@ -254,45 +272,71 @@ class OptionsDlg extends GuiImage {
Settings.optionsSettings.screenHeight = 1080; Settings.optionsSettings.screenHeight = 1080;
} }
}); });
makeOption("Screen Style:", () -> '${Settings.optionsSettings.isFullScreen ? "Full Screen" : "Windowed"}', 18, generalPanel, "small", makeOption("Screen Style:", () -> '${Settings.optionsSettings.isFullScreen ? "Full Screen" : "Windowed"}', yPos, generalPanel, "small",
["Windowed", "Full Screen"], (idx) -> { ["Windowed", "Full Screen"], (idx) -> {
Settings.optionsSettings.isFullScreen = idx == 1; Settings.optionsSettings.isFullScreen = idx == 1;
}, true); }, true);
makeOption("Frame Rate:", () -> '${Settings.optionsSettings.frameRateVis ? "Visible" : "Hidden"}', 74, generalPanel, "small", ["Visible", "Hidden"],
yPos += 56;
makeOption("Frame Rate:", () -> '${Settings.optionsSettings.frameRateVis ? "Visible" : "Hidden"}', yPos, generalPanel, "small", ["Visible", "Hidden"],
(idx) -> { (idx) -> {
Settings.optionsSettings.frameRateVis = idx == 0; Settings.optionsSettings.frameRateVis = idx == 0;
}); });
makeOption("OoB Insults:", () -> '${Settings.optionsSettings.oobInsults ? "Enabled" : "Disabled"}', 74, generalPanel, "small", makeOption("OoB Insults:", () -> '${Settings.optionsSettings.oobInsults ? "Enabled" : "Disabled"}', yPos, generalPanel, "small",
["Disabled", "Enabled"], (idx) -> { ["Disabled", "Enabled"], (idx) -> {
Settings.optionsSettings.oobInsults = idx == 1; Settings.optionsSettings.oobInsults = idx == 1;
}, true); }, true);
makeOption("Free-Look:", () -> '${Settings.controlsSettings.alwaysFreeLook ? "Enabled" : "Disabled"}', 130, generalPanel, "small",
yPos += 56;
makeOption("Free-Look:", () -> '${Settings.controlsSettings.alwaysFreeLook ? "Enabled" : "Disabled"}', yPos, generalPanel, "small",
["Disabled", "Enabled"], (idx) -> { ["Disabled", "Enabled"], (idx) -> {
Settings.controlsSettings.alwaysFreeLook = idx == 1; Settings.controlsSettings.alwaysFreeLook = idx == 1;
}); });
makeOption("Invert Y:", () -> '${Settings.controlsSettings.invertYAxis ? "Yes" : "No"}', 130, generalPanel, "small", ["No", "Yes"], (idx) -> { makeOption("Invert Y:", () -> '${Settings.controlsSettings.invertYAxis ? "Yes" : "No"}', yPos, generalPanel, "small", ["No", "Yes"], (idx) -> {
Settings.controlsSettings.invertYAxis = idx == 1; Settings.controlsSettings.invertYAxis = idx == 1;
}, true); }, true);
makeOption("Reflective Marble:", () -> '${Settings.optionsSettings.reflectiveMarble ? "Enabled" : "Disabled"}', 186, generalPanel, "small",
yPos += 56;
makeOption("Reflective Marble:", () -> '${Settings.optionsSettings.reflectiveMarble ? "Enabled" : "Disabled"}', yPos, generalPanel, "small",
["Disabled", "Enabled"], (idx) -> { ["Disabled", "Enabled"], (idx) -> {
Settings.optionsSettings.reflectiveMarble = idx == 1; Settings.optionsSettings.reflectiveMarble = idx == 1;
}); });
makeOption("Vertical Sync:", () -> '${Settings.optionsSettings.vsync ? "Enabled" : "Disabled"}', 186, generalPanel, "small", ["Disabled", "Enabled"], makeOption("Vertical Sync:", () -> '${Settings.optionsSettings.vsync ? "Enabled" : "Disabled"}', yPos, generalPanel, "small", ["Disabled", "Enabled"],
(idx) -> { (idx) -> {
Settings.optionsSettings.vsync = idx == 1; Settings.optionsSettings.vsync = idx == 1;
}, true); }, true);
makeSlider("Music Volume:", Settings.optionsSettings.musicVolume, 242, generalPanel, (val) -> {
yPos += 56;
makeOption("Rewind:", () -> '${Settings.optionsSettings.rewindEnabled ? "Enabled" : "Disabled"}', yPos, generalPanel, "small",
["Disabled", "Enabled"], (idx) -> {
Settings.optionsSettings.rewindEnabled = idx == 1;
}, false);
makeSlider("Rewind Speed:", (Settings.optionsSettings.rewindTimescale - 0.1) / (1 - 0.1), yPos, generalPanel, (val) -> {
Settings.optionsSettings.rewindTimescale = cast(0.1 + val * (1 - 0.1));
}, true);
yPos += 56;
makeSlider("Music Volume:", Settings.optionsSettings.musicVolume, yPos, generalPanel, (val) -> {
Settings.optionsSettings.musicVolume = val; Settings.optionsSettings.musicVolume = val;
AudioManager.updateVolumes(); AudioManager.updateVolumes();
}); });
makeSlider("Sound Volume:", Settings.optionsSettings.soundVolume, 242, generalPanel, (val) -> { makeSlider("Sound Volume:", Settings.optionsSettings.soundVolume, yPos, generalPanel, (val) -> {
Settings.optionsSettings.soundVolume = val; Settings.optionsSettings.soundVolume = val;
AudioManager.updateVolumes(); AudioManager.updateVolumes();
}, true); }, true);
makeSlider("Field of View:", (Settings.optionsSettings.fovX - 60) / (140 - 60), 298, generalPanel, (val) -> {
yPos += 56;
makeSlider("Field of View:", (Settings.optionsSettings.fovX - 60) / (140 - 60), yPos, generalPanel, (val) -> {
Settings.optionsSettings.fovX = cast(60 + val * (140 - 60)); Settings.optionsSettings.fovX = cast(60 + val * (140 - 60));
}); });
makeSlider("Mouse Speed:", (Settings.controlsSettings.cameraSensitivity - 0.2) / (3 - 0.2), 298, generalPanel, (val) -> { makeSlider("Mouse Speed:", (Settings.controlsSettings.cameraSensitivity - 0.2) / (3 - 0.2), yPos, generalPanel, (val) -> {
Settings.controlsSettings.cameraSensitivity = cast(0.2 + val * (3 - 0.2)); Settings.controlsSettings.cameraSensitivity = cast(0.2 + val * (3 - 0.2));
}, true); }, true);
@ -319,6 +363,8 @@ class OptionsDlg extends GuiImage {
return "Use PowerUp"; return "Use PowerUp";
if (Settings.controlsSettings.freelook == key && bindingName != "Free Look") if (Settings.controlsSettings.freelook == key && bindingName != "Free Look")
return "Free Look"; return "Free Look";
if (Settings.controlsSettings.rewind == key && bindingName != "Rewind")
return "Rewind";
return null; return null;
} }
@ -409,12 +455,16 @@ class OptionsDlg extends GuiImage {
MarbleGame.canvas.setContent(new TouchCtrlsEditGui()); MarbleGame.canvas.setContent(new TouchCtrlsEditGui());
} }
hotkeysPanel.addChild(remapBtn); hotkeysPanel.addChild(remapBtn);
} else {
makeRemapOption("Rewind:", 326, Util.getKeyForButton2(Settings.controlsSettings.rewind), (key) -> Settings.controlsSettings.rewind = key,
hotkeysPanel, true);
} }
generalBtn.pressedAction = (e) -> { generalBtn.pressedAction = (e) -> {
if (currentTab != "general") { if (currentTab != "general") {
currentTab = "general"; currentTab = "general";
hotkeysPanel.parent.removeChild(hotkeysPanel); hotkeysPanel.parent.removeChild(hotkeysPanel);
generalPanel.scrollY = 0;
window.addChild(generalPanel); window.addChild(generalPanel);
MarbleGame.canvas.render(MarbleGame.canvas.scene2d); // Force refresh MarbleGame.canvas.render(MarbleGame.canvas.scene2d); // Force refresh
} }

View file

@ -185,7 +185,6 @@ class PlayGui {
.toTile()); .toTile());
timerTransparency.position = new Vector(14, -7); timerTransparency.position = new Vector(14, -7);
timerTransparency.extent = new Vector(228, 71); timerTransparency.extent = new Vector(228, 71);
timerTransparency.doClipping = false;
timerCtrl.addChild(timerTransparency); timerCtrl.addChild(timerTransparency);
timerNumbers[0].position = new Vector(23, 0); timerNumbers[0].position = new Vector(23, 0);
@ -463,7 +462,6 @@ class PlayGui {
blastFill = new GuiImage(ResourceLoader.getResource("data/ui/game/blastbar_bargreen.png", ResourceLoader.getImage, this.imageResources).toTile()); blastFill = new GuiImage(ResourceLoader.getResource("data/ui/game/blastbar_bargreen.png", ResourceLoader.getImage, this.imageResources).toTile());
blastFill.position = new Vector(5, 5); blastFill.position = new Vector(5, 5);
blastFill.extent = new Vector(58, 17); blastFill.extent = new Vector(58, 17);
blastFill.doClipping = false;
blastBar.addChild(blastFill); blastBar.addChild(blastFill);
blastFrame = new GuiImage(ResourceLoader.getResource("data/ui/game/blastbar.png", ResourceLoader.getImage, this.imageResources).toTile()); blastFrame = new GuiImage(ResourceLoader.getResource("data/ui/game/blastbar.png", ResourceLoader.getImage, this.imageResources).toTile());

View file

@ -100,6 +100,7 @@ class ReplayCenterGui extends GuiImage {
var scrollCtrl = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile()); var scrollCtrl = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile());
scrollCtrl.position = new Vector(30, 25); scrollCtrl.position = new Vector(30, 25);
scrollCtrl.extent = new Vector(283, 346); scrollCtrl.extent = new Vector(283, 346);
scrollCtrl.childrenHandleScroll = true;
wnd.addChild(scrollCtrl); wnd.addChild(scrollCtrl);
var arial14fontdata = ResourceLoader.getFileEntry("data/font/arial.fnt"); var arial14fontdata = ResourceLoader.getFileEntry("data/font/arial.fnt");

View file

@ -164,6 +164,7 @@ class SearchGui extends GuiImage {
scrollCtrl = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile()); scrollCtrl = new GuiScrollCtrl(ResourceLoader.getResource("data/ui/common/philscroll.png", ResourceLoader.getImage, this.imageResources).toTile());
scrollCtrl.position = new Vector(19, 65); scrollCtrl.position = new Vector(19, 65);
scrollCtrl.extent = new Vector(447, 317); scrollCtrl.extent = new Vector(447, 317);
scrollCtrl.childrenHandleScroll = true;
this.addChild(scrollCtrl); this.addChild(scrollCtrl);
searchMissionList = new GuiTextListCtrl(markerFelt24, displayList); searchMissionList = new GuiTextListCtrl(markerFelt24, displayList);

View file

@ -8,6 +8,7 @@ import shapes.Trapdoor;
import shapes.PushButton; import shapes.PushButton;
import src.Util; import src.Util;
import shapes.Nuke; import shapes.Nuke;
import src.Settings;
class RewindManager { class RewindManager {
var frames:Array<RewindFrame> = []; var frames:Array<RewindFrame> = [];
@ -17,6 +18,7 @@ class RewindManager {
public function new(level:MarbleWorld) { public function new(level:MarbleWorld) {
this.level = level; this.level = level;
this.timeScale = Settings.optionsSettings.rewindTimescale;
} }
public function recordFrame() { public function recordFrame() {

View file

@ -115,7 +115,7 @@ class MovementInputEdit extends GuiGraphics {
state = 0; state = 0;
} }
public override function getHitTestRect() { public override function getHitTestRect(useScroll:Bool = true) {
var thisRect = this.getRenderRectangle(); var thisRect = this.getRenderRectangle();
if (selected) { if (selected) {

View file

@ -44,7 +44,7 @@ class TouchEditButton extends GuiGraphics {
this.radius = radius; this.radius = radius;
} }
public override function getHitTestRect() { public override function getHitTestRect(useScroll:Bool = true) {
var thisRect = this.getRenderRectangle(); var thisRect = this.getRenderRectangle();
thisRect.position = thisRect.position.sub(new Vector(radius, radius)); thisRect.position = thisRect.position.sub(new Vector(radius, radius));