diff --git a/assets/images/menuContrast.png b/assets/images/menuContrast.png new file mode 100644 index 00000000..f8d72201 Binary files /dev/null and b/assets/images/menuContrast.png differ diff --git a/assets/images/menuTransparent.png b/assets/images/menuTransparent.png new file mode 100644 index 00000000..a459df04 Binary files /dev/null and b/assets/images/menuTransparent.png differ diff --git a/buildnumber.txt b/buildnumber.txt index c954f9c6..b14de3ad 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -394 \ No newline at end of file +421 \ No newline at end of file diff --git a/source/funkin/menus/PauseSubState.hx b/source/funkin/menus/PauseSubState.hx index e8fefb43..bb41d2e2 100644 --- a/source/funkin/menus/PauseSubState.hx +++ b/source/funkin/menus/PauseSubState.hx @@ -12,12 +12,13 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.util.FlxColor; import funkin.ui.Alphabet; +import funkin.options.keybinds.KeybindsOptions; class PauseSubState extends MusicBeatSubstate { var grpMenuShit:FlxTypedGroup; - var menuItems:Array = ['Resume', 'Restart Song', 'Exit to menu']; + var menuItems:Array = ['Resume', 'Restart Song', 'Change Controls', 'Options','Exit to menu']; var curSelected:Int = 0; var pauseMusic:FlxSound; @@ -107,6 +108,9 @@ class PauseSubState extends MusicBeatSubstate close(); case "Restart Song": FlxG.resetState(); + case "Change Controls": + persistentDraw = false; + openSubState(new KeybindsOptions()); case "Exit to menu": FlxG.switchState(new MainMenuState()); } diff --git a/source/funkin/options/OptionsMenu.hx b/source/funkin/options/OptionsMenu.hx index fc811102..cca5e8d1 100644 --- a/source/funkin/options/OptionsMenu.hx +++ b/source/funkin/options/OptionsMenu.hx @@ -15,7 +15,7 @@ class OptionsMenu extends MusicBeatState { { name: 'Controls', desc: 'Change Controls for Player 1 and Player 2!', - state: funkin.options.KeybindsOptions + state: funkin.options.keybinds.KeybindsOptions }, { name: 'Visuals', diff --git a/source/funkin/options/keybinds/ChangeKeybindSubState.hx b/source/funkin/options/keybinds/ChangeKeybindSubState.hx new file mode 100644 index 00000000..885b73ff --- /dev/null +++ b/source/funkin/options/keybinds/ChangeKeybindSubState.hx @@ -0,0 +1,45 @@ +package funkin.options.keybinds; + +import flixel.FlxCamera; +import flixel.effects.FlxFlicker; +import funkin.system.Controls; +import funkin.options.Options; +import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; +import flixel.addons.transition.FlxTransitionableState; +import flixel.group.FlxGroup.FlxTypedGroup; +import funkin.ui.Alphabet; +import flixel.util.FlxColor; +import flixel.input.keyboard.FlxKey; +import flixel.math.FlxMath; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxG; + +class ChangeKeybindSubState extends MusicBeatSubstate { + var callback:FlxKey->Void; + var cancelCallback:Void->Void; + public override function new(callback:FlxKey->Void, cancelCallback:Void->Void) { + this.callback = callback; + this.cancelCallback = cancelCallback; + super(); + } + public override function create() { + super.create(); + + } + + public override function update(elapsed:Float) { + super.update(elapsed); + var key:FlxKey = FlxG.keys.firstJustReleased(); + if (cast(key, Int) <= 0) return; + + if (key == ESCAPE && !FlxG.keys.pressed.SHIFT) { + close(); + cancelCallback(); + return; + } + close(); + callback(key); + return; + } +} \ No newline at end of file diff --git a/source/funkin/options/keybinds/KeybindSetting.hx b/source/funkin/options/keybinds/KeybindSetting.hx new file mode 100644 index 00000000..bae5422c --- /dev/null +++ b/source/funkin/options/keybinds/KeybindSetting.hx @@ -0,0 +1,104 @@ +package funkin.options.keybinds; + +import flixel.FlxCamera; +import flixel.effects.FlxFlicker; +import funkin.system.Controls; +import funkin.options.Options; +import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; +import flixel.addons.transition.FlxTransitionableState; +import flixel.group.FlxGroup.FlxTypedGroup; +import funkin.ui.Alphabet; +import flixel.util.FlxColor; +import flixel.input.keyboard.FlxKey; +import flixel.math.FlxMath; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxG; + +using StringTools; + +class KeybindSetting extends FlxTypedSpriteGroup { + public var title:Alphabet; + public var bind1:Alphabet; + public var bind2:Alphabet; + public var icon:FlxSprite; + + public var changingKeybind:Int = -1; + public var p2Selected:Bool = false; + public var value:String; + + public var option1:Null; + public var option2:Null; + public function new(x:Float, y:Float, name:String, value:String, ?sparrowIcon:String, ?sparrowAnim:String) { + super(); + this.value = value; + title = new Alphabet(0, 0, name, true); + title.setPosition(100, 0); + add(title); + + var controlArrayP1:Array = Reflect.field(Options, 'P1_${value}'); + var controlArrayP2:Array = Reflect.field(Options, 'P2_${value}'); + + option1 = controlArrayP1[0]; + option2 = controlArrayP2[0]; + + for(i in 1...3) { + var b = null; + if (i == 1) + b = bind1 = new Alphabet(0, 0, "", false); + else + b = bind2 = new Alphabet(0, 0, "", false); + + b.setPosition(FlxG.width * (0.25 * (i+1)) - x, -60); + add(b); + } + updateText(); + + if (sparrowIcon != null) { + icon = new FlxSprite(); + icon.frames = Paths.getSparrowAtlas(sparrowIcon); + icon.antialiasing = true; + icon.animation.addByPrefix('icon', sparrowAnim, 24, true); + icon.animation.play('icon'); + icon.setGraphicSize(75, 75); + icon.updateHitbox(); + var min = Math.min(icon.scale.x, icon.scale.y); + icon.scale.set(min, min); + add(icon); + } + + setPosition(x, y); + } + + public override function update(elapsed:Float) { + super.update(elapsed); + bind1.alpha = (p2Selected ? 0.6 : 1) / alpha; + bind2.alpha = (p2Selected ? 1 : 0.6) / alpha; + bind1.alpha *= alpha; + bind2.alpha *= alpha; + } + + public function changeKeybind(callback:Void->Void, cancelCallback:Void->Void, p2:Bool = false) { + KeybindsOptions.instance.persistentDraw = true; + KeybindsOptions.instance.persistentUpdate = false; + + KeybindsOptions.instance.openSubState(new ChangeKeybindSubState(function(key:FlxKey) { + if (p2) + Reflect.setField(Options, 'P2_$value', [option2 = key]); + else + Reflect.setField(Options, 'P1_$value', [option1 = key]); + updateText(); + callback(); + }, function() { + if (p2) + Reflect.setField(Options, 'P2_$value', [option2 = 0]); + else + Reflect.setField(Options, 'P1_$value', [option1 = 0]); + })); + } + + public function updateText() { + bind1.text = '${CoolUtil.keyToString(option1)}'; + bind2.text = '${CoolUtil.keyToString(option2)}'; + } +} \ No newline at end of file diff --git a/source/funkin/options/KeybindsOptions.hx b/source/funkin/options/keybinds/KeybindsOptions.hx similarity index 61% rename from source/funkin/options/KeybindsOptions.hx rename to source/funkin/options/keybinds/KeybindsOptions.hx index 3de4412f..ad3382ed 100644 --- a/source/funkin/options/KeybindsOptions.hx +++ b/source/funkin/options/keybinds/KeybindsOptions.hx @@ -1,5 +1,6 @@ -package funkin.options; +package funkin.options.keybinds; +import flixel.FlxCamera; import flixel.effects.FlxFlicker; import funkin.system.Controls; import funkin.options.Options; @@ -16,7 +17,9 @@ import flixel.FlxG; using StringTools; -class KeybindsOptions extends MusicBeatState { +class KeybindsOptions extends MusicBeatSubstate { + public static var instance:KeybindsOptions; + public var categories = [ { name: 'Notes', @@ -62,6 +65,9 @@ class KeybindsOptions extends MusicBeatState { } ]; + public var settingCam:FlxCamera; + + public var p2Selected:Bool = false; public var curSelected:Int = -1; public var canSelect:Bool = true; public var alphabets:FlxTypedGroup; @@ -75,11 +81,16 @@ class KeybindsOptions extends MusicBeatState { ]; public var camFollow:FlxObject = new FlxObject(0, 0, 2, 2); + var isSubState:Bool = false; + public override function create() { super.create(); + instance = this; + + isSubState = FlxG.state != this; alphabets = new FlxTypedGroup(); - bg = new FlxSprite(-80).loadGraphic(Paths.image('menuBGBlue')); + bg = new FlxSprite(-80).loadGraphic(Paths.image(isSubState ? 'menuTransparent' : 'menuBGBlue')); coloredBG = new FlxSprite(-80).loadGraphic(Paths.image('menuDesat')); for(bg in [bg, coloredBG]) { bg.scrollFactor.set(); @@ -91,6 +102,20 @@ class KeybindsOptions extends MusicBeatState { } coloredBG.alpha = 0; + if (isSubState) { + // is substate, opened from pause menu + if (settingCam == null) { + settingCam = new FlxCamera(); + settingCam.bgColor = 0xAA000000; + FlxG.cameras.add(settingCam, false); + } + cameras = [settingCam]; + bg.alpha = 0; + settingCam.follow(camFollow, LOCKON, 0.125); + } else { + FlxG.camera.follow(camFollow, LOCKON, 0.125); + } + var k:Int = 0; for(category in categories) { k++; @@ -120,6 +145,8 @@ class KeybindsOptions extends MusicBeatState { } var text = new KeybindSetting(100, k * 75, e.name, e.control, sparrowIcon, sparrowAnim); + if (!isSubState) + text.bind1.color = text.bind2.color = FlxColor.BLACK; alphabets.add(text); k++; } @@ -127,48 +154,72 @@ class KeybindsOptions extends MusicBeatState { add(alphabets); changeSelection(1); - FlxG.camera.follow(camFollow, LOCKON, 0.125); add(camFollow); } + public override function destroy() { + super.destroy(); + if (settingCam != null) FlxG.cameras.remove(settingCam); + instance = null; + } + + var skipThisFrame:Bool = true; + public override function update(elapsed:Float) { super.update(elapsed); - if (curSelected < 4) { - if (coloredBG.alpha == 0) - coloredBG.color = noteColors[curSelected]; - else - coloredBG.color = CoolUtil.lerpColor(coloredBG.color, noteColors[curSelected], 0.0625); - coloredBG.alpha = lerp(coloredBG.alpha, 1, 0.0625); - } else - coloredBG.alpha = lerp(coloredBG.alpha, 0, 0.0625); + if (isSubState) { + bg.alpha = lerp(bg.alpha, 0.1, 0.125); + } else { + if (curSelected < 4) { + if (coloredBG.alpha == 0) + coloredBG.color = noteColors[curSelected]; + else + coloredBG.color = CoolUtil.lerpColor(coloredBG.color, noteColors[curSelected], 0.0625); + + coloredBG.alpha = lerp(coloredBG.alpha, 1, 0.0625); + } else + coloredBG.alpha = lerp(coloredBG.alpha, 0, 0.0625); + } - super.update(elapsed); if (canSelect) { changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0)); if (controls.BACK) { FlxTransitionableState.skipNextTransIn = true; FlxTransitionableState.skipNextTransOut = true; - FlxG.switchState(new OptionsMenu()); + if (isSubState) + close(); + else + FlxG.switchState(new OptionsMenu()); controls.setKeyboardScheme(Solo); return; } - if (controls.ACCEPT) { + if (controls.ACCEPT && !skipThisFrame) { if (alphabets.members[curSelected] != null) { canSelect = false; CoolUtil.playMenuSFX(1); FlxFlicker.flicker(alphabets.members[curSelected], 0.4, 0.1, true, false, function(t) { - alphabets.members[curSelected].changeKeybind(false); + alphabets.members[curSelected].changeKeybind(function() { + canSelect = true; + }, function() { + canSelect = true; + }, p2Selected); }); } } - } else { - if (alphabets.members[curSelected].changingKeybind < 0) - canSelect = true; + + if (controls.LEFT_P || controls.RIGHT_P) { + if (alphabets.members[curSelected] != null) { + CoolUtil.playMenuSFX(0); + alphabets.members[curSelected].p2Selected = (p2Selected = !p2Selected); + } + } } + super.update(elapsed); + skipThisFrame = false; } @@ -181,6 +232,7 @@ class KeybindsOptions extends MusicBeatState { }); if (alphabets.members[curSelected] != null) { var alphabet = alphabets.members[curSelected]; + alphabet.p2Selected = p2Selected; alphabet.alpha = 1; var minH = FlxG.height / 2; var maxH = alphabets.members[alphabets.length-1].y + alphabets.members[alphabets.length-1].height - (FlxG.height / 2); @@ -190,92 +242,4 @@ class KeybindsOptions extends MusicBeatState { camFollow.setPosition(FlxG.width / 2, FlxG.height / 2); } } -} - -class KeybindSetting extends FlxTypedSpriteGroup { - public var title:Alphabet; - public var bind1:Alphabet; - public var bind2:Alphabet; - public var icon:FlxSprite; - - public var changingKeybind:Int = -1; - public var value:String; - - public var option1:Null; - public var option2:Null; - public function new(x:Float, y:Float, name:String, value:String, ?sparrowIcon:String, ?sparrowAnim:String) { - super(); - this.value = value; - title = new Alphabet(0, 0, name, true); - title.setPosition(100, 0); - add(title); - - - var controlArrayP1:Array = Reflect.field(Options, 'P1_${value}'); - var controlArrayP2:Array = Reflect.field(Options, 'P2_${value}'); - - option1 = controlArrayP1[0]; - option2 = controlArrayP2[0]; - - for(i in 1...3) { - var b = null; - if (i == 1) - b = bind1 = new Alphabet(0, 0, "", false); - else - b = bind2 = new Alphabet(0, 0, "", false); - - b.setPosition(FlxG.width * (0.25 * (i+1)) - x, -60); - add(b); - } - updateText(); - - if (sparrowIcon != null) { - icon = new FlxSprite(); - icon.frames = Paths.getSparrowAtlas(sparrowIcon); - icon.antialiasing = true; - icon.animation.addByPrefix('icon', sparrowAnim, 24, true); - icon.animation.play('icon'); - icon.setGraphicSize(75, 75); - icon.updateHitbox(); - var min = Math.min(icon.scale.x, icon.scale.y); - icon.scale.set(min, min); - add(icon); - } - - setPosition(x, y); - } - - public override function update(elapsed:Float) { - super.update(elapsed); - if (changingKeybind >= 0) { - var key:FlxKey = FlxG.keys.firstJustReleased(); - if (cast(key, Int) <= 0) return; - if (key == ESCAPE && !FlxG.keys.pressed.SHIFT) { - changingKeybind = -1; - return; - } - if (changingKeybind == 0) { - option1 = key; - Reflect.setField(Options, 'P1_$value', [option1]); - } else { - option2 = key; - Reflect.setField(Options, 'P2_$value', [option2]); - } - changingKeybind = -1; - updateText(); - return; - } - } - - public function changeKeybind(p2:Bool = false) { - FlxG.state.persistentDraw = true; - FlxG.state.persistentUpdate = true; - - changingKeybind = p2 ? 1 : 0; - } - - public function updateText() { - bind1.text = '${CoolUtil.keyToString(option1)}'; - bind2.text = '${CoolUtil.keyToString(option2)}'; - } } \ No newline at end of file diff --git a/source/funkin/system/MusicBeatState.hx b/source/funkin/system/MusicBeatState.hx index c048188d..2498e0a1 100644 --- a/source/funkin/system/MusicBeatState.hx +++ b/source/funkin/system/MusicBeatState.hx @@ -46,9 +46,6 @@ class MusicBeatState extends FlxUIState override function create() { - if (transIn != null) - trace('reg ' + transIn.region); - super.create(); } diff --git a/source/funkin/ui/Alphabet.hx b/source/funkin/ui/Alphabet.hx index 34d88826..e297b458 100644 --- a/source/funkin/ui/Alphabet.hx +++ b/source/funkin/ui/Alphabet.hx @@ -11,6 +11,7 @@ import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup; import flixel.math.FlxMath; import flixel.util.FlxTimer; +import flixel.util.FlxColor; using StringTools; @@ -45,6 +46,16 @@ class Alphabet extends FlxSpriteGroup var isBold:Bool = false; + private override function set_color(c:Int):Int { + for(e in group.members) { + if (e is AlphaCharacter) { + var char = cast(e, AlphaCharacter); + char.setColor(c, isBold); + } + } + return super.set_color(c); + } + public function refreshAlphabetXML(path:String) { trace("Needs refresh!!"); AlphaCharacter.__alphaPath = path; @@ -130,6 +141,8 @@ class Alphabet extends FlxSpriteGroup // anim not found if (!letter.visible) xPos += 40; + + letter.setColor(color, isBold); add(letter); lastSprite = letter; @@ -262,6 +275,7 @@ class Alphabet extends FlxSpriteGroup e.destroy(); @:privateAccess group.members = []; + _sprites = cast group.members; lastSprite = null; addText(); } @@ -276,6 +290,17 @@ class AlphaCharacter extends FlxSprite public var row:Int = 0; + public function setColor(c:FlxColor, isBold:Bool) { + if (isBold) { + colorTransform.redMultiplier = c.redFloat; + colorTransform.greenMultiplier = c.greenFloat; + colorTransform.blueMultiplier = c.blueFloat; + } else { + colorTransform.redOffset = c.red; + colorTransform.greenOffset = c.green; + colorTransform.blueOffset = c.blue; + } + } public function new(x:Float, y:Float) { super(x, y);