mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-04-01 07:16:54 +00:00
use different implementation
This commit is contained in:
parent
e3159745fb
commit
3b3b9d97ba
|
@ -152,6 +152,32 @@ class AtlasText extends FlxTypedSpriteGroup<AtlasChar>
|
|||
}
|
||||
}
|
||||
|
||||
public function getWidth():Int
|
||||
{
|
||||
var width = 0;
|
||||
for (char in this.text.split(""))
|
||||
{
|
||||
switch (char)
|
||||
{
|
||||
case " ":
|
||||
{
|
||||
width += 40;
|
||||
}
|
||||
case "\n":
|
||||
{}
|
||||
case char:
|
||||
{
|
||||
var sprite = new AtlasChar(atlas, char);
|
||||
sprite.revive();
|
||||
sprite.char = char;
|
||||
sprite.alpha = 1;
|
||||
width += Std.int(sprite.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
override function toString()
|
||||
{
|
||||
return "InputItem, " + FlxStringUtil.getDebugString([
|
||||
|
|
|
@ -3,23 +3,18 @@ package funkin.ui.options;
|
|||
import flixel.FlxCamera;
|
||||
import flixel.FlxObject;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.math.FlxMath;
|
||||
import flixel.effects.FlxFlicker;
|
||||
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
|
||||
import funkin.ui.AtlasText.AtlasFont;
|
||||
import funkin.ui.options.OptionsState.Page;
|
||||
import funkin.ui.options.items.CheckboxPreferenceItem;
|
||||
import funkin.ui.options.items.NumberPreferenceItem;
|
||||
import funkin.graphics.FunkinCamera;
|
||||
import funkin.audio.FunkinSound;
|
||||
import funkin.ui.TextMenuList.TextMenuItem;
|
||||
|
||||
class PreferencesMenu extends Page
|
||||
{
|
||||
/**
|
||||
* Wether you can select a different option
|
||||
*/
|
||||
public static var allowScrolling:Bool = true;
|
||||
|
||||
var curSelected:Int = 0;
|
||||
var prefs:FlxTypedSpriteGroup<PreferenceItem>;
|
||||
var items:TextMenuList;
|
||||
var preferenceItems:FlxTypedSpriteGroup<FlxSprite>;
|
||||
|
||||
var menuCamera:FlxCamera;
|
||||
var camFollow:FlxObject;
|
||||
|
@ -33,27 +28,22 @@ class PreferencesMenu extends Page
|
|||
menuCamera.bgColor = 0x0;
|
||||
camera = menuCamera;
|
||||
|
||||
prefs = new FlxTypedSpriteGroup<PreferenceItem>();
|
||||
add(prefs);
|
||||
add(items = new TextMenuList());
|
||||
add(preferenceItems = new FlxTypedSpriteGroup<FlxSprite>());
|
||||
|
||||
createPrefItems();
|
||||
|
||||
camFollow = new FlxObject(FlxG.width / 2, 0, 140, 70);
|
||||
if (items != null) camFollow.y = items.selectedItem.y;
|
||||
|
||||
menuCamera.follow(camFollow, null, 0.06);
|
||||
var margin = 160;
|
||||
menuCamera.deadzone.set(0, margin, menuCamera.width, 40);
|
||||
menuCamera.minScrollY = 0;
|
||||
|
||||
changeSelection(0);
|
||||
}
|
||||
|
||||
function addPref(pref:PreferenceItem):Void
|
||||
{
|
||||
pref.x = 0;
|
||||
pref.y = 120 * prefs.length;
|
||||
pref.ID = prefs.length;
|
||||
prefs.add(pref);
|
||||
items.onChange.add(function(selected) {
|
||||
camFollow.y = selected.y;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,287 +52,78 @@ class PreferencesMenu extends Page
|
|||
function createPrefItems():Void
|
||||
{
|
||||
#if !web
|
||||
var pref:NumberedPreferenceItem = new NumberedPreferenceItem("FPS", "The framerate that the game is running on", Preferences.framerate,
|
||||
function(value:Float):Void {
|
||||
Preferences.framerate = Std.int(value);
|
||||
});
|
||||
pref.minValue = 60;
|
||||
pref.maxValue = 360;
|
||||
pref.changeRate = 1;
|
||||
pref.changeDelay = 0.05;
|
||||
addPref(pref);
|
||||
createPrefItemNumber('FPS', 'The framerate that the game is running on', function(value:Float) {
|
||||
Preferences.framerate = Std.int(value);
|
||||
}, Preferences.framerate, 60, 360, 1, 0);
|
||||
#end
|
||||
|
||||
var pref:CheckboxPreferenceItem = new CheckboxPreferenceItem('Naughtyness', 'Toggle displaying raunchy content', Preferences.naughtyness,
|
||||
function(value:Bool):Void {
|
||||
Preferences.naughtyness = value;
|
||||
});
|
||||
addPref(pref);
|
||||
|
||||
var pref:CheckboxPreferenceItem = new CheckboxPreferenceItem('Downscroll', 'Enable to make notes move downwards', Preferences.downscroll,
|
||||
function(value:Bool):Void {
|
||||
Preferences.downscroll = value;
|
||||
});
|
||||
addPref(pref);
|
||||
|
||||
var pref:CheckboxPreferenceItem = new CheckboxPreferenceItem('Flashing Lights', 'Disable to dampen flashing effects', Preferences.flashingLights,
|
||||
function(value:Bool):Void {
|
||||
Preferences.flashingLights = value;
|
||||
});
|
||||
addPref(pref);
|
||||
|
||||
var pref:CheckboxPreferenceItem = new CheckboxPreferenceItem('Camera Zooming on Beat', 'Disable to stop the camera bouncing to the song',
|
||||
Preferences.zoomCamera, function(value:Bool):Void {
|
||||
Preferences.zoomCamera = value;
|
||||
});
|
||||
addPref(pref);
|
||||
|
||||
var pref:CheckboxPreferenceItem = new CheckboxPreferenceItem('Debug Display', 'Enable to show FPS and other debug stats', Preferences.debugDisplay,
|
||||
function(value:Bool):Void {
|
||||
Preferences.debugDisplay = value;
|
||||
});
|
||||
addPref(pref);
|
||||
|
||||
var pref:CheckboxPreferenceItem = new CheckboxPreferenceItem('Auto Pause', 'Automatically pause the game when it loses focus', Preferences.autoPause,
|
||||
function(value:Bool):Void {
|
||||
Preferences.autoPause = value;
|
||||
});
|
||||
addPref(pref);
|
||||
}
|
||||
|
||||
function changeSelection(change:Int):Void
|
||||
{
|
||||
curSelected += change;
|
||||
if (curSelected < 0)
|
||||
{
|
||||
curSelected = prefs.length - 1;
|
||||
}
|
||||
else if (curSelected >= prefs.length)
|
||||
{
|
||||
curSelected = 0;
|
||||
}
|
||||
|
||||
for (pref in prefs)
|
||||
{
|
||||
if (pref.ID == curSelected)
|
||||
{
|
||||
pref.onSelect(true);
|
||||
camFollow.y = pref.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
pref.onSelect(false);
|
||||
}
|
||||
}
|
||||
createPrefItemCheckbox('Naughtyness', 'Toggle displaying raunchy content', function(value:Bool):Void {
|
||||
Preferences.naughtyness = value;
|
||||
}, Preferences.naughtyness);
|
||||
createPrefItemCheckbox('Downscroll', 'Enable to make notes move downwards', function(value:Bool):Void {
|
||||
Preferences.downscroll = value;
|
||||
}, Preferences.downscroll);
|
||||
createPrefItemCheckbox('Flashing Lights', 'Disable to dampen flashing effects', function(value:Bool):Void {
|
||||
Preferences.flashingLights = value;
|
||||
}, Preferences.flashingLights);
|
||||
createPrefItemCheckbox('Camera Zooming on Beat', 'Disable to stop the camera bouncing to the song', function(value:Bool):Void {
|
||||
Preferences.zoomCamera = value;
|
||||
}, Preferences.zoomCamera);
|
||||
createPrefItemCheckbox('Debug Display', 'Enable to show FPS and other debug stats', function(value:Bool):Void {
|
||||
Preferences.debugDisplay = value;
|
||||
}, Preferences.debugDisplay);
|
||||
createPrefItemCheckbox('Auto Pause', 'Automatically pause the game when it loses focus', function(value:Bool):Void {
|
||||
Preferences.autoPause = value;
|
||||
}, Preferences.autoPause);
|
||||
}
|
||||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
if (controls.UI_DOWN_P && allowScrolling)
|
||||
{
|
||||
FunkinSound.playOnce(Paths.sound('scrollMenu'));
|
||||
changeSelection(1);
|
||||
}
|
||||
else if (controls.UI_UP_P && allowScrolling)
|
||||
{
|
||||
FunkinSound.playOnce(Paths.sound('scrollMenu'));
|
||||
changeSelection(-1);
|
||||
}
|
||||
// Indent the selected item.
|
||||
// TODO: Only do this on menu change?
|
||||
items.forEach(function(daItem:TextMenuItem) {
|
||||
var thyOffset:Int = 0;
|
||||
if (Std.isOfType(daItem, NumberPreferenceItem)) thyOffset = cast(daItem, NumberPreferenceItem).lefthandText.getWidth();
|
||||
|
||||
var selectedPref:PreferenceItem = prefs.members[curSelected];
|
||||
selectedPref?.handleInput(elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
class PreferenceItem extends FlxTypedSpriteGroup<FlxSprite>
|
||||
{
|
||||
public var name:String = "";
|
||||
public var description:String = "";
|
||||
|
||||
public function handleInput(elapsed:Float):Void {}
|
||||
|
||||
public function onSelect(isSelected:Bool):Void {}
|
||||
}
|
||||
|
||||
class NumberedPreferenceItem extends PreferenceItem
|
||||
{
|
||||
public var onChange:Float->Void;
|
||||
public var changeRate:Float = 1.0;
|
||||
public var changeDelay:Float = 0.1;
|
||||
|
||||
public var minValue(default, set):Null<Float>;
|
||||
|
||||
function set_minValue(value:Float):Float
|
||||
{
|
||||
minValue = value;
|
||||
currentValue = currentValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
public var maxValue(default, set):Null<Float>;
|
||||
|
||||
function set_maxValue(value:Float):Float
|
||||
{
|
||||
maxValue = value;
|
||||
currentValue = currentValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
public var currentValue(default, set):Float;
|
||||
|
||||
function set_currentValue(value:Float):Float
|
||||
{
|
||||
currentValue = FlxMath.bound(value, minValue, maxValue);
|
||||
onChange(currentValue);
|
||||
updateText();
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
var valueText:AtlasText;
|
||||
var preferenceText:AtlasText;
|
||||
|
||||
public function new(name:String, description:String, defaultValue:Float, onChange:Float->Void)
|
||||
{
|
||||
super();
|
||||
|
||||
this.valueText = new AtlasText(20, 30, '$defaultValue', AtlasFont.DEFAULT);
|
||||
add(this.valueText);
|
||||
|
||||
this.preferenceText = new AtlasText(this.valueText.x + this.valueText.width + 30, 30, '$name', AtlasFont.BOLD);
|
||||
add(this.preferenceText);
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.onChange = onChange;
|
||||
this.currentValue = defaultValue;
|
||||
}
|
||||
|
||||
var timeToWait:Float = 0;
|
||||
|
||||
public override function handleInput(elapsed:Float):Void
|
||||
{
|
||||
timeToWait -= elapsed;
|
||||
|
||||
if (timeToWait > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerSettings.player1.controls.UI_RIGHT)
|
||||
{
|
||||
currentValue += changeRate;
|
||||
timeToWait = changeDelay;
|
||||
// FunkinSound.playOnce(Paths.sound('scrollMenu'));
|
||||
}
|
||||
else if (PlayerSettings.player1.controls.UI_LEFT)
|
||||
{
|
||||
currentValue -= changeRate;
|
||||
timeToWait = changeDelay;
|
||||
// FunkinSound.playOnce(Paths.sound('scrollMenu'));
|
||||
}
|
||||
}
|
||||
|
||||
var isSelected:Bool = false;
|
||||
|
||||
public override function onSelect(isSelected:Bool):Void
|
||||
{
|
||||
this.isSelected = isSelected;
|
||||
if (isSelected)
|
||||
{
|
||||
preferenceText.x = valueText.x + valueText.width + 60;
|
||||
preferenceText.alpha = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
preferenceText.x = valueText.x + valueText.width + 30;
|
||||
preferenceText.alpha = 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
function updateText():Void
|
||||
{
|
||||
valueText.text = '$currentValue';
|
||||
preferenceText.x = valueText.x + valueText.width + (isSelected ? 60 : 30);
|
||||
}
|
||||
}
|
||||
|
||||
class CheckboxPreferenceItem extends PreferenceItem
|
||||
{
|
||||
public var onChange:Bool->Void;
|
||||
|
||||
public var currentValue(default, set):Bool;
|
||||
|
||||
function set_currentValue(value:Bool):Bool
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
checkBox.animation.play('checked', true);
|
||||
checkBox.offset.set(17, 70);
|
||||
}
|
||||
else
|
||||
{
|
||||
checkBox.animation.play('static');
|
||||
checkBox.offset.set();
|
||||
}
|
||||
currentValue = value;
|
||||
onChange(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
var checkBox:FlxSprite;
|
||||
var preferenceText:AtlasText;
|
||||
|
||||
public function new(name:String, description:String, defaultValue:Bool, onChange:Bool->Void)
|
||||
{
|
||||
super();
|
||||
|
||||
this.checkBox = new FlxSprite();
|
||||
this.checkBox.frames = Paths.getSparrowAtlas('checkboxThingie');
|
||||
this.checkBox.animation.addByPrefix('static', 'Check Box unselected', 24, false);
|
||||
this.checkBox.animation.addByPrefix('checked', 'Check Box selecting animation', 24, false);
|
||||
this.checkBox.setGraphicSize(Std.int(this.checkBox.width * 0.7));
|
||||
this.checkBox.updateHitbox();
|
||||
add(this.checkBox);
|
||||
|
||||
this.preferenceText = new AtlasText(120, 30, '$name', AtlasFont.BOLD);
|
||||
add(this.preferenceText);
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.onChange = onChange;
|
||||
this.currentValue = defaultValue;
|
||||
}
|
||||
|
||||
var isAccepting:Bool = false;
|
||||
|
||||
public override function handleInput(elapsed:Float):Void
|
||||
{
|
||||
if (PlayerSettings.player1.controls.ACCEPT && !isAccepting)
|
||||
{
|
||||
isAccepting = true;
|
||||
PreferencesMenu.allowScrolling = false;
|
||||
FunkinSound.playOnce(Paths.sound('confirmMenu'));
|
||||
FlxFlicker.flicker(preferenceText, 1, 0.06, true, false, function(_) {
|
||||
isAccepting = false;
|
||||
PreferencesMenu.allowScrolling = true;
|
||||
currentValue = !currentValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override function onSelect(isSelected:Bool):Void
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
preferenceText.x = 150;
|
||||
preferenceText.alpha = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
preferenceText.alpha = 0.6;
|
||||
preferenceText.x = 120;
|
||||
}
|
||||
// Very messy but it works
|
||||
if (thyOffset == 0)
|
||||
{
|
||||
if (items.selectedItem == daItem) thyOffset += 150;
|
||||
else
|
||||
thyOffset += 120;
|
||||
}
|
||||
else if (items.selectedItem == daItem)
|
||||
{
|
||||
thyOffset += 70;
|
||||
}
|
||||
else
|
||||
{
|
||||
thyOffset += 25;
|
||||
}
|
||||
|
||||
daItem.x = thyOffset;
|
||||
});
|
||||
}
|
||||
|
||||
function createPrefItemCheckbox(prefName:String, prefDesc:String, onChange:Bool->Void, defaultValue:Bool):Void
|
||||
{
|
||||
var checkbox:CheckboxPreferenceItem = new CheckboxPreferenceItem(0, 120 * (items.length - 1 + 1), defaultValue);
|
||||
|
||||
items.createItem(120, (120 * items.length) + 30, prefName, AtlasFont.BOLD, function() {
|
||||
var value = !checkbox.currentValue;
|
||||
onChange(value);
|
||||
checkbox.currentValue = value;
|
||||
});
|
||||
|
||||
preferenceItems.add(checkbox);
|
||||
}
|
||||
|
||||
function createPrefItemNumber(prefName:String, prefDesc:String, onChange:Float->Void, defaultValue:Float, min:Float, max:Float, step:Float,
|
||||
precision:Int):Void
|
||||
{
|
||||
var item = new NumberPreferenceItem(145, (120 * items.length) + 30, prefName, defaultValue, min, max, step, precision, onChange);
|
||||
items.addItem(prefName, item);
|
||||
preferenceItems.add(item.lefthandText);
|
||||
}
|
||||
}
|
||||
|
|
49
source/funkin/ui/options/items/CheckboxPreferenceItem.hx
Normal file
49
source/funkin/ui/options/items/CheckboxPreferenceItem.hx
Normal file
|
@ -0,0 +1,49 @@
|
|||
package funkin.ui.options.items;
|
||||
|
||||
import flixel.FlxSprite.FlxSprite;
|
||||
|
||||
class CheckboxPreferenceItem extends FlxSprite
|
||||
{
|
||||
public var currentValue(default, set):Bool;
|
||||
|
||||
public function new(x:Float, y:Float, defaultValue:Bool = false)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
frames = Paths.getSparrowAtlas('checkboxThingie');
|
||||
animation.addByPrefix('static', 'Check Box unselected', 24, false);
|
||||
animation.addByPrefix('checked', 'Check Box selecting animation', 24, false);
|
||||
|
||||
setGraphicSize(Std.int(width * 0.7));
|
||||
updateHitbox();
|
||||
|
||||
this.currentValue = defaultValue;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
switch (animation.curAnim.name)
|
||||
{
|
||||
case 'static':
|
||||
offset.set();
|
||||
case 'checked':
|
||||
offset.set(17, 70);
|
||||
}
|
||||
}
|
||||
|
||||
function set_currentValue(value:Bool):Bool
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
animation.play('checked', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
animation.play('static');
|
||||
}
|
||||
|
||||
return currentValue = value;
|
||||
}
|
||||
}
|
107
source/funkin/ui/options/items/NumberPreferenceItem.hx
Normal file
107
source/funkin/ui/options/items/NumberPreferenceItem.hx
Normal file
|
@ -0,0 +1,107 @@
|
|||
package funkin.ui.options.items;
|
||||
|
||||
import funkin.ui.TextMenuList;
|
||||
import funkin.ui.AtlasText;
|
||||
import funkin.input.Controls;
|
||||
|
||||
/**
|
||||
* Preference item that allows the player to pick a value between min and max
|
||||
*/
|
||||
class NumberPreferenceItem extends TextMenuItem
|
||||
{
|
||||
function controls():Controls
|
||||
{
|
||||
return PlayerSettings.player1.controls;
|
||||
}
|
||||
|
||||
public var lefthandText:AtlasText;
|
||||
|
||||
public var currentValue:Float;
|
||||
public var min:Float;
|
||||
public var max:Float;
|
||||
public var step:Float;
|
||||
public var precision:Int;
|
||||
public var onChangeCallback:Null<Float->Void>;
|
||||
|
||||
public function new(x:Float, y:Float, name:String, defaultValue:Float, min:Float, max:Float, step:Float, precision:Int, ?callback:Float->Void):Void
|
||||
{
|
||||
super(x, y, name, function() {
|
||||
callback(this.currentValue);
|
||||
});
|
||||
lefthandText = new AtlasText(20, y, formatted(defaultValue), AtlasFont.DEFAULT);
|
||||
|
||||
updateHitbox();
|
||||
|
||||
this.currentValue = defaultValue;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.step = step;
|
||||
this.precision = precision;
|
||||
this.onChangeCallback = callback;
|
||||
}
|
||||
|
||||
static final HOLD_DELAY:Float = 0.5; // seconds
|
||||
static final CHANGE_RATE:Float = 0.02; // seconds
|
||||
|
||||
var holdDelayTimer:Float = HOLD_DELAY; // seconds
|
||||
var changeRateTimer:Float = 0.0; // seconds
|
||||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
// var fancyTextFancyColor:Color;
|
||||
if (selected)
|
||||
{
|
||||
holdDelayTimer -= elapsed;
|
||||
if (holdDelayTimer <= 0.0)
|
||||
{
|
||||
changeRateTimer -= elapsed;
|
||||
}
|
||||
|
||||
var jpLeft:Bool = controls().UI_LEFT_P;
|
||||
var jpRight:Bool = controls().UI_RIGHT_P;
|
||||
|
||||
if (jpLeft || jpRight)
|
||||
{
|
||||
holdDelayTimer = HOLD_DELAY;
|
||||
changeRateTimer = 0.0;
|
||||
}
|
||||
|
||||
var shouldDecrease:Bool = jpLeft;
|
||||
var shouldIncrease:Bool = jpRight;
|
||||
|
||||
if (controls().UI_LEFT && holdDelayTimer <= 0.0 && changeRateTimer <= 0.0)
|
||||
{
|
||||
shouldDecrease = true;
|
||||
changeRateTimer = CHANGE_RATE;
|
||||
}
|
||||
else if (controls().UI_RIGHT && holdDelayTimer <= 0.0 && changeRateTimer <= 0.0)
|
||||
{
|
||||
shouldIncrease = true;
|
||||
changeRateTimer = CHANGE_RATE;
|
||||
}
|
||||
|
||||
if (shouldDecrease) currentValue -= step;
|
||||
else if (shouldIncrease) currentValue += step;
|
||||
currentValue = currentValue.clamp(min, max);
|
||||
if (onChangeCallback != null && (shouldIncrease || shouldDecrease))
|
||||
{
|
||||
onChangeCallback(currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
lefthandText.text = formatted(currentValue);
|
||||
}
|
||||
|
||||
function formatted(value:Float):String
|
||||
{
|
||||
return '${toFixed(value)}';
|
||||
}
|
||||
|
||||
function toFixed(value:Float):Float
|
||||
{
|
||||
var multiplier:Float = Math.pow(10, precision);
|
||||
return Math.floor(value * multiplier) / multiplier;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue