diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index b3da56f65..0578c37ef 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -199,6 +199,26 @@ class Preferences public static var lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame"); #end + /** + * If >0, the game will display a semi-opaque background under the notes. + * `0` for no background, `100` for solid black if you're freaky like that + * @default `0` + */ + public static var strumlineBackgroundOpacity(get, set):Int; + + static function get_strumlineBackgroundOpacity():Int + { + return (Save?.instance?.options?.strumlineBackgroundOpacity ?? 0); + } + + static function set_strumlineBackgroundOpacity(value:Int):Int + { + var save:Save = Save.instance; + save.options.strumlineBackgroundOpacity = value; + save.flush(); + return value; + } + /** * Loads the user's preferences from the save data and apply them. */ diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index e894f9c62..497b99986 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -8,6 +8,7 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.util.FlxSort; +import funkin.graphics.FunkinSprite; import funkin.play.notes.NoteHoldCover; import funkin.play.notes.NoteSplash; import funkin.play.notes.NoteSprite; @@ -85,6 +86,8 @@ class Strumline extends FlxSpriteGroup public var onNoteIncoming:FlxTypedSignalVoid>; + var background:FunkinSprite; + var strumlineNotes:FlxTypedSpriteGroup; var noteSplashes:FlxTypedSpriteGroup; var noteHoldCovers:FlxTypedSpriteGroup; @@ -108,6 +111,8 @@ class Strumline extends FlxSpriteGroup var heldKeys:Array = []; + static final BACKGROUND_PAD:Int = 16; + public function new(noteStyle:NoteStyle, isPlayer:Bool) { super(); @@ -144,6 +149,13 @@ class Strumline extends FlxSpriteGroup this.noteSplashes.zIndex = 50; this.add(this.noteSplashes); + this.background = new FunkinSprite(0, 0).makeSolidColor(Std.int(this.width + BACKGROUND_PAD * 2), FlxG.height, 0xFF000000); + // Convert the percent to a number between 0 and 1. + this.background.alpha = Preferences.strumlineBackgroundOpacity / 100.0; + this.background.scrollFactor.set(0, 0); + this.background.x = -BACKGROUND_PAD; + this.add(this.background); + this.refresh(); this.onNoteIncoming = new FlxTypedSignalVoid>(); @@ -168,6 +180,16 @@ class Strumline extends FlxSpriteGroup this.active = true; } + override function set_y(value:Float):Float + { + super.set_y(value); + + // Keep the background on the screen. + if (this.background != null) this.background.y = 0; + + return value; + } + public function refresh():Void { sort(SortUtil.byZIndex, FlxSort.ASCENDING); @@ -978,4 +1000,42 @@ class Strumline extends FlxSpriteGroup { return FlxSort.byValues(order, a?.strumTime, b?.strumTime); } + + override function findMinYHelper() + { + var value = Math.POSITIVE_INFINITY; + for (member in group.members) + { + if (member == null) continue; + // SKIP THE BACKGROUND + if (member == this.background) continue; + + var minY:Float; + if (member.flixelType == SPRITEGROUP) minY = (cast member : FlxSpriteGroup).findMinY(); + else + minY = member.y; + + if (minY < value) value = minY; + } + return value; + } + + override function findMaxYHelper() + { + var value = Math.NEGATIVE_INFINITY; + for (member in group.members) + { + if (member == null) continue; + // SKIP THE BACKGROUND + if (member == this.background) continue; + + var maxY:Float; + if (member.flixelType == SPRITEGROUP) maxY = (cast member : FlxSpriteGroup).findMaxY(); + else + maxY = member.y + member.height; + + if (maxY > value) value = maxY; + } + return value; + } } diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 5db295301..c7bf52fa4 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -101,6 +101,7 @@ class Save zoomCamera: true, debugDisplay: false, autoPause: true, + strumlineBackgroundOpacity: 0, inputOffset: 0, audioVisualOffset: 0, unlockedFramerate: false, @@ -1349,7 +1350,14 @@ typedef SaveDataOptions = var autoPause:Bool; /** - * Offset the user's inputs by this many ms. + * If >0, the game will display a semi-opaque background under the notes. + * `0` for no background, `100` for solid black if you're freaky like that + * @default `0` + */ + var strumlineBackgroundOpacity:Int; + + /** + * Offset the users inputs by this many ms. * @default `0` */ var inputOffset:Int; diff --git a/source/funkin/ui/options/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx index fb4980762..dfd4dafb6 100644 --- a/source/funkin/ui/options/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -60,6 +60,9 @@ class PreferencesMenu extends Page createPrefItemCheckbox('Downscroll', 'Enable to make notes move downwards', function(value:Bool):Void { Preferences.downscroll = value; }, Preferences.downscroll); + createPrefItemPercentage('Strumline Background', 'Give the strumline a semi-transparent background', function(value:Int):Void { + Preferences.strumlineBackgroundOpacity = value; + }, Preferences.strumlineBackgroundOpacity); createPrefItemCheckbox('Flashing Lights', 'Disable to dampen flashing effects', function(value:Bool):Void { Preferences.flashingLights = value; }, Preferences.flashingLights);