mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-11-09 00:04:42 +00:00
commit
dd14af7499
60
Project.xml
60
Project.xml
|
@ -75,26 +75,26 @@
|
|||
<library name="week7" preload="false" />
|
||||
</section>
|
||||
|
||||
<assets path="assets/songs" library="songs" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/songs" library="songs" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/shared" library="shared" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/shared" library="shared" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/tutorial" library="tutorial" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/tutorial" library="tutorial" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/week1" library="week1" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/week1" library="week1" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/week2" library="week2" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/week2" library="week2" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/week3" library="week3" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/week3" library="week3" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/week4" library="week4" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/week4" library="week4" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/week5" library="week5" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/week5" library="week5" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/week6" library="week6" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/week6" library="week6" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/week7" library="week7" exclude="*.ogg" if="web"/>
|
||||
<assets path="assets/week7" library="week7" exclude="*.mp3" unless="web"/>
|
||||
<assets path="assets/songs" library="songs" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/songs" library="songs" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/shared" library="shared" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/shared" library="shared" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/tutorial" library="tutorial" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/tutorial" library="tutorial" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/week1" library="week1" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/week1" library="week1" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/week2" library="week2" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/week2" library="week2" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/week3" library="week3" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/week3" library="week3" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/week4" library="week4" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/week4" library="week4" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/week5" library="week5" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/week5" library="week5" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/week6" library="week6" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/week6" library="week6" exclude="*.fla|*.mp3" unless="web"/>
|
||||
<assets path="assets/week7" library="week7" exclude="*.fla|*.ogg" if="web"/>
|
||||
<assets path="assets/week7" library="week7" exclude="*.fla|*.mp3" unless="web"/>
|
||||
|
||||
<!-- <assets path='example_mods' rename='mods' embed='false'/> -->
|
||||
|
||||
|
@ -122,9 +122,10 @@
|
|||
|
||||
<!--In case you want to use the ui package-->
|
||||
<haxelib name="flixel-ui" />
|
||||
<haxelib name="newgrounds"/>
|
||||
<haxelib name="newgrounds" unless="switch"/>
|
||||
<haxelib name="faxe" if='switch'/>
|
||||
<haxelib name="polymod"/>
|
||||
<haxelib name="hxcpp-debug-server" if="desktop debug"/>
|
||||
<haxelib name="discord_rpc" if="desktop"/>
|
||||
<!-- <haxelib name="hxcpp-debug-server" if="desktop"/> -->
|
||||
|
||||
|
@ -177,6 +178,21 @@
|
|||
|
||||
|
||||
<!-- <haxedef name="SKIP_TO_PLAYSTATE" if="debug" /> -->
|
||||
<haxedef name="NG_LOGIN" if="newgrounds" />
|
||||
|
||||
<haxedef name="CAN_OPEN_LINKS" unless="switch"/>
|
||||
<haxedef name="CAN_CHEAT" if="switch debug"/>
|
||||
|
||||
<!-- <haxedef name="CLEAR_INPUT_SAVE"/> -->
|
||||
|
||||
<section if="newgrounds">
|
||||
<!-- Enables Ng.core.verbose -->
|
||||
<!-- <haxedef name="NG_VERBOSE" /> -->
|
||||
|
||||
<!-- Enables a NG debug session, so medals don't permently unlock -->
|
||||
<!-- <haxedef name="NG_DEBUG" /> -->
|
||||
|
||||
<!-- pretends that the saved session Id was expired, forcing the reconnect prompt -->
|
||||
<!-- <haxedef name="NG_FORCE_EXPIRED_SESSION" if="debug" /> -->
|
||||
</section>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -62,8 +62,9 @@ package;
|
|||
|
||||
class APIStuff
|
||||
{
|
||||
public static var API:String = "";
|
||||
public static var EncKey:String = "";
|
||||
inline public static var API:String = "51348:TtzK0rZ8";
|
||||
inline public static var EncKey:String = "5NqKsSVSNKHbF9fPgZPqPg==";
|
||||
inline public static var SESSION:String = null;
|
||||
}
|
||||
|
||||
```
|
||||
|
|
|
@ -40,7 +40,7 @@ class Alphabet extends FlxSpriteGroup
|
|||
|
||||
var isBold:Bool = false;
|
||||
|
||||
public function new(x:Float, y:Float, text:String = "", ?bold:Bool = false, typed:Bool = false)
|
||||
public function new(x:Float = 0.0, y:Float = 0.0, text:String = "", ?bold:Bool = false, typed:Bool = false)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
|
|
|
@ -11,57 +11,6 @@ import flixel.input.gamepad.FlxGamepadButton;
|
|||
import flixel.input.gamepad.FlxGamepadInputID;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
enum abstract Action(String) to String from String
|
||||
{
|
||||
var UP = "up";
|
||||
var LEFT = "left";
|
||||
var RIGHT = "right";
|
||||
var DOWN = "down";
|
||||
var UP_P = "up-press";
|
||||
var LEFT_P = "left-press";
|
||||
var RIGHT_P = "right-press";
|
||||
var DOWN_P = "down-press";
|
||||
var UP_R = "up-release";
|
||||
var LEFT_R = "left-release";
|
||||
var RIGHT_R = "right-release";
|
||||
var DOWN_R = "down-release";
|
||||
var ACCEPT = "accept";
|
||||
var BACK = "back";
|
||||
var PAUSE = "pause";
|
||||
var RESET = "reset";
|
||||
var CHEAT = "cheat";
|
||||
}
|
||||
#else
|
||||
@:enum
|
||||
abstract Action(String) to String from String
|
||||
{
|
||||
var UP = "up";
|
||||
var LEFT = "left";
|
||||
var RIGHT = "right";
|
||||
var DOWN = "down";
|
||||
var UP_P = "up-press";
|
||||
var LEFT_P = "left-press";
|
||||
var RIGHT_P = "right-press";
|
||||
var DOWN_P = "down-press";
|
||||
var UP_R = "up-release";
|
||||
var LEFT_R = "left-release";
|
||||
var RIGHT_R = "right-release";
|
||||
var DOWN_R = "down-release";
|
||||
var ACCEPT = "accept";
|
||||
var BACK = "back";
|
||||
var PAUSE = "pause";
|
||||
var RESET = "reset";
|
||||
var CHEAT = "cheat";
|
||||
}
|
||||
#end
|
||||
|
||||
enum Device
|
||||
{
|
||||
Keys;
|
||||
Gamepad(id:Int);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since, in many cases multiple actions should use similar keys, we don't want the
|
||||
* rebinding UI to list every action. ActionBinders are what the user percieves as
|
||||
|
@ -69,15 +18,64 @@ enum Device
|
|||
*/
|
||||
enum Control
|
||||
{
|
||||
UP;
|
||||
LEFT;
|
||||
RIGHT;
|
||||
DOWN;
|
||||
// List notes in order from left to right on gameplay screen.
|
||||
NOTE_LEFT;
|
||||
NOTE_DOWN;
|
||||
NOTE_UP;
|
||||
NOTE_RIGHT;
|
||||
UI_UP;
|
||||
UI_LEFT;
|
||||
UI_RIGHT;
|
||||
UI_DOWN;
|
||||
RESET;
|
||||
ACCEPT;
|
||||
BACK;
|
||||
PAUSE;
|
||||
#if CAN_CHEAT
|
||||
CHEAT;
|
||||
#end
|
||||
}
|
||||
|
||||
@:enum
|
||||
abstract Action(String) to String from String
|
||||
{
|
||||
var UI_UP = "ui_up";
|
||||
var UI_LEFT = "ui_left";
|
||||
var UI_RIGHT = "ui_right";
|
||||
var UI_DOWN = "ui_down";
|
||||
var UI_UP_P = "ui_up-press";
|
||||
var UI_LEFT_P = "ui_left-press";
|
||||
var UI_RIGHT_P = "ui_right-press";
|
||||
var UI_DOWN_P = "ui_down-press";
|
||||
var UI_UP_R = "ui_up-release";
|
||||
var UI_LEFT_R = "ui_left-release";
|
||||
var UI_RIGHT_R = "ui_right-release";
|
||||
var UI_DOWN_R = "ui_down-release";
|
||||
var NOTE_UP = "note_up";
|
||||
var NOTE_LEFT = "note_left";
|
||||
var NOTE_RIGHT = "note_right";
|
||||
var NOTE_DOWN = "note_down";
|
||||
var NOTE_UP_P = "note_up-press";
|
||||
var NOTE_LEFT_P = "note_left-press";
|
||||
var NOTE_RIGHT_P = "note_right-press";
|
||||
var NOTE_DOWN_P = "note_down-press";
|
||||
var NOTE_UP_R = "note_up-release";
|
||||
var NOTE_LEFT_R = "note_left-release";
|
||||
var NOTE_RIGHT_R = "note_right-release";
|
||||
var NOTE_DOWN_R = "note_down-release";
|
||||
var ACCEPT = "accept";
|
||||
var BACK = "back";
|
||||
var PAUSE = "pause";
|
||||
var RESET = "reset";
|
||||
#if CAN_CHEAT
|
||||
var CHEAT = "cheat";
|
||||
#end
|
||||
}
|
||||
|
||||
enum Device
|
||||
{
|
||||
Keys;
|
||||
Gamepad(id:Int);
|
||||
}
|
||||
|
||||
enum KeyboardScheme
|
||||
|
@ -94,177 +92,125 @@ enum KeyboardScheme
|
|||
*/
|
||||
class Controls extends FlxActionSet
|
||||
{
|
||||
var _up = new FlxActionDigital(Action.UP);
|
||||
var _left = new FlxActionDigital(Action.LEFT);
|
||||
var _right = new FlxActionDigital(Action.RIGHT);
|
||||
var _down = new FlxActionDigital(Action.DOWN);
|
||||
var _upP = new FlxActionDigital(Action.UP_P);
|
||||
var _leftP = new FlxActionDigital(Action.LEFT_P);
|
||||
var _rightP = new FlxActionDigital(Action.RIGHT_P);
|
||||
var _downP = new FlxActionDigital(Action.DOWN_P);
|
||||
var _upR = new FlxActionDigital(Action.UP_R);
|
||||
var _leftR = new FlxActionDigital(Action.LEFT_R);
|
||||
var _rightR = new FlxActionDigital(Action.RIGHT_R);
|
||||
var _downR = new FlxActionDigital(Action.DOWN_R);
|
||||
var _ui_up = new FlxActionDigital(Action.UI_UP);
|
||||
var _ui_left = new FlxActionDigital(Action.UI_LEFT);
|
||||
var _ui_right = new FlxActionDigital(Action.UI_RIGHT);
|
||||
var _ui_down = new FlxActionDigital(Action.UI_DOWN);
|
||||
var _ui_upP = new FlxActionDigital(Action.UI_UP_P);
|
||||
var _ui_leftP = new FlxActionDigital(Action.UI_LEFT_P);
|
||||
var _ui_rightP = new FlxActionDigital(Action.UI_RIGHT_P);
|
||||
var _ui_downP = new FlxActionDigital(Action.UI_DOWN_P);
|
||||
var _ui_upR = new FlxActionDigital(Action.UI_UP_R);
|
||||
var _ui_leftR = new FlxActionDigital(Action.UI_LEFT_R);
|
||||
var _ui_rightR = new FlxActionDigital(Action.UI_RIGHT_R);
|
||||
var _ui_downR = new FlxActionDigital(Action.UI_DOWN_R);
|
||||
var _note_up = new FlxActionDigital(Action.NOTE_UP);
|
||||
var _note_left = new FlxActionDigital(Action.NOTE_LEFT);
|
||||
var _note_right = new FlxActionDigital(Action.NOTE_RIGHT);
|
||||
var _note_down = new FlxActionDigital(Action.NOTE_DOWN);
|
||||
var _note_upP = new FlxActionDigital(Action.NOTE_UP_P);
|
||||
var _note_leftP = new FlxActionDigital(Action.NOTE_LEFT_P);
|
||||
var _note_rightP = new FlxActionDigital(Action.NOTE_RIGHT_P);
|
||||
var _note_downP = new FlxActionDigital(Action.NOTE_DOWN_P);
|
||||
var _note_upR = new FlxActionDigital(Action.NOTE_UP_R);
|
||||
var _note_leftR = new FlxActionDigital(Action.NOTE_LEFT_R);
|
||||
var _note_rightR = new FlxActionDigital(Action.NOTE_RIGHT_R);
|
||||
var _note_downR = new FlxActionDigital(Action.NOTE_DOWN_R);
|
||||
var _accept = new FlxActionDigital(Action.ACCEPT);
|
||||
var _back = new FlxActionDigital(Action.BACK);
|
||||
var _pause = new FlxActionDigital(Action.PAUSE);
|
||||
var _reset = new FlxActionDigital(Action.RESET);
|
||||
#if CAN_CHEAT
|
||||
var _cheat = new FlxActionDigital(Action.CHEAT);
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
var byName:Map<String, FlxActionDigital> = [];
|
||||
#else
|
||||
var byName:Map<String, FlxActionDigital> = new Map<String, FlxActionDigital>();
|
||||
#end
|
||||
|
||||
var byName:Map<String, FlxActionDigital> = new Map<String, FlxActionDigital>();
|
||||
|
||||
public var gamepadsAdded:Array<Int> = [];
|
||||
public var keyboardScheme = KeyboardScheme.None;
|
||||
|
||||
public var UP(get, never):Bool;
|
||||
public var UI_UP (get, never):Bool; inline function get_UI_UP () return _ui_up .check();
|
||||
public var UI_LEFT (get, never):Bool; inline function get_UI_LEFT () return _ui_left .check();
|
||||
public var UI_RIGHT(get, never):Bool; inline function get_UI_RIGHT() return _ui_right.check();
|
||||
public var UI_DOWN (get, never):Bool; inline function get_UI_DOWN () return _ui_down .check();
|
||||
|
||||
inline function get_UP()
|
||||
return _up.check();
|
||||
public var UI_UP_P (get, never):Bool; inline function get_UI_UP_P () return _ui_upP .check();
|
||||
public var UI_LEFT_P (get, never):Bool; inline function get_UI_LEFT_P () return _ui_leftP .check();
|
||||
public var UI_RIGHT_P(get, never):Bool; inline function get_UI_RIGHT_P() return _ui_rightP.check();
|
||||
public var UI_DOWN_P (get, never):Bool; inline function get_UI_DOWN_P () return _ui_downP .check();
|
||||
|
||||
public var LEFT(get, never):Bool;
|
||||
public var UI_UP_R (get, never):Bool; inline function get_UI_UP_R () return _ui_upR .check();
|
||||
public var UI_LEFT_R (get, never):Bool; inline function get_UI_LEFT_R () return _ui_leftR .check();
|
||||
public var UI_RIGHT_R(get, never):Bool; inline function get_UI_RIGHT_R() return _ui_rightR.check();
|
||||
public var UI_DOWN_R (get, never):Bool; inline function get_UI_DOWN_R () return _ui_downR .check();
|
||||
|
||||
public var NOTE_UP (get, never):Bool; inline function get_NOTE_UP () return _note_up .check();
|
||||
public var NOTE_LEFT (get, never):Bool; inline function get_NOTE_LEFT () return _note_left .check();
|
||||
public var NOTE_RIGHT(get, never):Bool; inline function get_NOTE_RIGHT() return _note_right.check();
|
||||
public var NOTE_DOWN (get, never):Bool; inline function get_NOTE_DOWN () return _note_down .check();
|
||||
|
||||
inline function get_LEFT()
|
||||
return _left.check();
|
||||
public var NOTE_UP_P (get, never):Bool; inline function get_NOTE_UP_P () return _note_upP .check();
|
||||
public var NOTE_LEFT_P (get, never):Bool; inline function get_NOTE_LEFT_P () return _note_leftP .check();
|
||||
public var NOTE_RIGHT_P(get, never):Bool; inline function get_NOTE_RIGHT_P() return _note_rightP.check();
|
||||
public var NOTE_DOWN_P (get, never):Bool; inline function get_NOTE_DOWN_P () return _note_downP .check();
|
||||
|
||||
public var RIGHT(get, never):Bool;
|
||||
public var NOTE_UP_R (get, never):Bool; inline function get_NOTE_UP_R () return _note_upR .check();
|
||||
public var NOTE_LEFT_R (get, never):Bool; inline function get_NOTE_LEFT_R () return _note_leftR .check();
|
||||
public var NOTE_RIGHT_R(get, never):Bool; inline function get_NOTE_RIGHT_R() return _note_rightR.check();
|
||||
public var NOTE_DOWN_R (get, never):Bool; inline function get_NOTE_DOWN_R () return _note_downR .check();
|
||||
|
||||
inline function get_RIGHT()
|
||||
return _right.check();
|
||||
|
||||
public var DOWN(get, never):Bool;
|
||||
|
||||
inline function get_DOWN()
|
||||
return _down.check();
|
||||
|
||||
public var UP_P(get, never):Bool;
|
||||
|
||||
inline function get_UP_P()
|
||||
return _upP.check();
|
||||
|
||||
public var LEFT_P(get, never):Bool;
|
||||
|
||||
inline function get_LEFT_P()
|
||||
return _leftP.check();
|
||||
|
||||
public var RIGHT_P(get, never):Bool;
|
||||
|
||||
inline function get_RIGHT_P()
|
||||
return _rightP.check();
|
||||
|
||||
public var DOWN_P(get, never):Bool;
|
||||
|
||||
inline function get_DOWN_P()
|
||||
return _downP.check();
|
||||
|
||||
public var UP_R(get, never):Bool;
|
||||
|
||||
inline function get_UP_R()
|
||||
return _upR.check();
|
||||
|
||||
public var LEFT_R(get, never):Bool;
|
||||
|
||||
inline function get_LEFT_R()
|
||||
return _leftR.check();
|
||||
|
||||
public var RIGHT_R(get, never):Bool;
|
||||
|
||||
inline function get_RIGHT_R()
|
||||
return _rightR.check();
|
||||
|
||||
public var DOWN_R(get, never):Bool;
|
||||
|
||||
inline function get_DOWN_R()
|
||||
return _downR.check();
|
||||
|
||||
public var ACCEPT(get, never):Bool;
|
||||
|
||||
inline function get_ACCEPT()
|
||||
return _accept.check();
|
||||
|
||||
public var BACK(get, never):Bool;
|
||||
|
||||
inline function get_BACK()
|
||||
return _back.check();
|
||||
|
||||
public var PAUSE(get, never):Bool;
|
||||
|
||||
inline function get_PAUSE()
|
||||
return _pause.check();
|
||||
|
||||
public var RESET(get, never):Bool;
|
||||
|
||||
inline function get_RESET()
|
||||
return _reset.check();
|
||||
|
||||
public var CHEAT(get, never):Bool;
|
||||
|
||||
inline function get_CHEAT()
|
||||
return _cheat.check();
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
public function new(name, scheme = None)
|
||||
{
|
||||
super(name);
|
||||
|
||||
add(_up);
|
||||
add(_left);
|
||||
add(_right);
|
||||
add(_down);
|
||||
add(_upP);
|
||||
add(_leftP);
|
||||
add(_rightP);
|
||||
add(_downP);
|
||||
add(_upR);
|
||||
add(_leftR);
|
||||
add(_rightR);
|
||||
add(_downR);
|
||||
add(_accept);
|
||||
add(_back);
|
||||
add(_pause);
|
||||
add(_reset);
|
||||
add(_cheat);
|
||||
|
||||
for (action in digitalActions)
|
||||
byName[action.name] = action;
|
||||
|
||||
setKeyboardScheme(scheme, false);
|
||||
}
|
||||
#else
|
||||
public var ACCEPT(get, never):Bool; inline function get_ACCEPT() return _accept.check();
|
||||
public var BACK (get, never):Bool; inline function get_BACK () return _back .check();
|
||||
public var PAUSE (get, never):Bool; inline function get_PAUSE () return _pause .check();
|
||||
public var RESET (get, never):Bool; inline function get_RESET () return _reset .check();
|
||||
#if CAN_CHEAT
|
||||
public var CHEAT (get, never):Bool; inline function get_CHEAT () return _cheat.check ();
|
||||
#end
|
||||
|
||||
public function new(name, scheme:KeyboardScheme = null)
|
||||
{
|
||||
super(name);
|
||||
|
||||
add(_up);
|
||||
add(_left);
|
||||
add(_right);
|
||||
add(_down);
|
||||
add(_upP);
|
||||
add(_leftP);
|
||||
add(_rightP);
|
||||
add(_downP);
|
||||
add(_upR);
|
||||
add(_leftR);
|
||||
add(_rightR);
|
||||
add(_downR);
|
||||
add(_ui_up);
|
||||
add(_ui_left);
|
||||
add(_ui_right);
|
||||
add(_ui_down);
|
||||
add(_ui_upP);
|
||||
add(_ui_leftP);
|
||||
add(_ui_rightP);
|
||||
add(_ui_downP);
|
||||
add(_ui_upR);
|
||||
add(_ui_leftR);
|
||||
add(_ui_rightR);
|
||||
add(_ui_downR);
|
||||
add(_note_up);
|
||||
add(_note_left);
|
||||
add(_note_right);
|
||||
add(_note_down);
|
||||
add(_note_upP);
|
||||
add(_note_leftP);
|
||||
add(_note_rightP);
|
||||
add(_note_downP);
|
||||
add(_note_upR);
|
||||
add(_note_leftR);
|
||||
add(_note_rightR);
|
||||
add(_note_downR);
|
||||
add(_accept);
|
||||
add(_back);
|
||||
add(_pause);
|
||||
add(_reset);
|
||||
#if CAN_CHEAT
|
||||
add(_cheat);
|
||||
#end
|
||||
|
||||
for (action in digitalActions)
|
||||
byName[action.name] = action;
|
||||
|
||||
|
||||
if (scheme == null)
|
||||
scheme = None;
|
||||
|
||||
setKeyboardScheme(scheme, false);
|
||||
}
|
||||
#end
|
||||
|
||||
override function update()
|
||||
{
|
||||
|
@ -301,15 +247,21 @@ class Controls extends FlxActionSet
|
|||
{
|
||||
return switch (control)
|
||||
{
|
||||
case UP: _up;
|
||||
case DOWN: _down;
|
||||
case LEFT: _left;
|
||||
case RIGHT: _right;
|
||||
case UI_UP: _ui_up;
|
||||
case UI_DOWN: _ui_down;
|
||||
case UI_LEFT: _ui_left;
|
||||
case UI_RIGHT: _ui_right;
|
||||
case NOTE_UP: _note_up;
|
||||
case NOTE_DOWN: _note_down;
|
||||
case NOTE_LEFT: _note_left;
|
||||
case NOTE_RIGHT: _note_right;
|
||||
case ACCEPT: _accept;
|
||||
case BACK: _back;
|
||||
case PAUSE: _pause;
|
||||
case RESET: _reset;
|
||||
#if CAN_CHEAT
|
||||
case CHEAT: _cheat;
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,22 +281,38 @@ class Controls extends FlxActionSet
|
|||
{
|
||||
switch (control)
|
||||
{
|
||||
case UP:
|
||||
func(_up, PRESSED);
|
||||
func(_upP, JUST_PRESSED);
|
||||
func(_upR, JUST_RELEASED);
|
||||
case LEFT:
|
||||
func(_left, PRESSED);
|
||||
func(_leftP, JUST_PRESSED);
|
||||
func(_leftR, JUST_RELEASED);
|
||||
case RIGHT:
|
||||
func(_right, PRESSED);
|
||||
func(_rightP, JUST_PRESSED);
|
||||
func(_rightR, JUST_RELEASED);
|
||||
case DOWN:
|
||||
func(_down, PRESSED);
|
||||
func(_downP, JUST_PRESSED);
|
||||
func(_downR, JUST_RELEASED);
|
||||
case UI_UP:
|
||||
func(_ui_up, PRESSED);
|
||||
func(_ui_upP, JUST_PRESSED);
|
||||
func(_ui_upR, JUST_RELEASED);
|
||||
case UI_LEFT:
|
||||
func(_ui_left, PRESSED);
|
||||
func(_ui_leftP, JUST_PRESSED);
|
||||
func(_ui_leftR, JUST_RELEASED);
|
||||
case UI_RIGHT:
|
||||
func(_ui_right, PRESSED);
|
||||
func(_ui_rightP, JUST_PRESSED);
|
||||
func(_ui_rightR, JUST_RELEASED);
|
||||
case UI_DOWN:
|
||||
func(_ui_down, PRESSED);
|
||||
func(_ui_downP, JUST_PRESSED);
|
||||
func(_ui_downR, JUST_RELEASED);
|
||||
case NOTE_UP:
|
||||
func(_note_up, PRESSED);
|
||||
func(_note_upP, JUST_PRESSED);
|
||||
func(_note_upR, JUST_RELEASED);
|
||||
case NOTE_LEFT:
|
||||
func(_note_left, PRESSED);
|
||||
func(_note_leftP, JUST_PRESSED);
|
||||
func(_note_leftR, JUST_RELEASED);
|
||||
case NOTE_RIGHT:
|
||||
func(_note_right, PRESSED);
|
||||
func(_note_rightP, JUST_PRESSED);
|
||||
func(_note_rightR, JUST_RELEASED);
|
||||
case NOTE_DOWN:
|
||||
func(_note_down, PRESSED);
|
||||
func(_note_downP, JUST_PRESSED);
|
||||
func(_note_downR, JUST_RELEASED);
|
||||
case ACCEPT:
|
||||
func(_accept, JUST_PRESSED);
|
||||
case BACK:
|
||||
|
@ -353,12 +321,14 @@ class Controls extends FlxActionSet
|
|||
func(_pause, JUST_PRESSED);
|
||||
case RESET:
|
||||
func(_reset, JUST_PRESSED);
|
||||
#if CAN_CHEAT
|
||||
case CHEAT:
|
||||
func(_cheat, JUST_PRESSED);
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
public function replaceBinding(control:Control, device:Device, ?toAdd:Int, ?toRemove:Int)
|
||||
public function replaceBinding(control:Control, device:Device, toAdd:Int, toRemove:Int)
|
||||
{
|
||||
if (toAdd == toRemove)
|
||||
return;
|
||||
|
@ -366,31 +336,41 @@ class Controls extends FlxActionSet
|
|||
switch (device)
|
||||
{
|
||||
case Keys:
|
||||
if (toRemove != null)
|
||||
unbindKeys(control, [toRemove]);
|
||||
if (toAdd != null)
|
||||
bindKeys(control, [toAdd]);
|
||||
forEachBound(control, function(action, _) replaceKey(action, toAdd, toRemove));
|
||||
|
||||
case Gamepad(id):
|
||||
if (toRemove != null)
|
||||
unbindButtons(control, id, [toRemove]);
|
||||
if (toAdd != null)
|
||||
bindButtons(control, id, [toAdd]);
|
||||
forEachBound(control, function(action, _) replaceButton(action, id, toAdd, toRemove));
|
||||
}
|
||||
}
|
||||
|
||||
function replaceKey(action:FlxActionDigital, toAdd:Int, toRemove:Int)
|
||||
{
|
||||
for (i in 0...action.inputs.length)
|
||||
{
|
||||
var input = action.inputs[i];
|
||||
if (input.device == KEYBOARD && input.inputID == toRemove)
|
||||
{
|
||||
@:privateAccess
|
||||
action.inputs[i].inputID = toAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function replaceButton(action:FlxActionDigital, deviceID:Int, toAdd:Int, toRemove:Int)
|
||||
{
|
||||
for (i in 0...action.inputs.length)
|
||||
{
|
||||
var input = action.inputs[i];
|
||||
if (isGamepad(input, deviceID) && input.inputID == toRemove)
|
||||
{
|
||||
@:privateAccess
|
||||
action.inputs[i].inputID = toAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function copyFrom(controls:Controls, ?device:Device)
|
||||
{
|
||||
#if (haxe >= "4.0.0")
|
||||
for (name => action in controls.byName)
|
||||
{
|
||||
for (input in action.inputs)
|
||||
{
|
||||
if (device == null || isDevice(input, device))
|
||||
byName[name].add(cast input);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (name in controls.byName.keys())
|
||||
{
|
||||
var action = controls.byName[name];
|
||||
|
@ -400,21 +380,14 @@ class Controls extends FlxActionSet
|
|||
byName[name].add(cast input);
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
switch (device)
|
||||
{
|
||||
case null:
|
||||
// add all
|
||||
#if (haxe >= "4.0.0")
|
||||
for (gamepad in controls.gamepadsAdded)
|
||||
if (!gamepadsAdded.contains(gamepad))
|
||||
gamepadsAdded.push(gamepad);
|
||||
#else
|
||||
for (gamepad in controls.gamepadsAdded)
|
||||
if (gamepadsAdded.indexOf(gamepad) == -1)
|
||||
gamepadsAdded.push(gamepad);
|
||||
#end
|
||||
|
||||
mergeKeyboardScheme(controls.keyboardScheme);
|
||||
|
||||
|
@ -450,11 +423,7 @@ class Controls extends FlxActionSet
|
|||
*/
|
||||
public function bindKeys(control:Control, keys:Array<FlxKey>)
|
||||
{
|
||||
#if (haxe >= "4.0.0")
|
||||
inline forEachBound(control, (action, state) -> addKeys(action, keys, state));
|
||||
#else
|
||||
forEachBound(control, function(action, state) addKeys(action, keys, state));
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -463,11 +432,7 @@ class Controls extends FlxActionSet
|
|||
*/
|
||||
public function unbindKeys(control:Control, keys:Array<FlxKey>)
|
||||
{
|
||||
#if (haxe >= "4.0.0")
|
||||
inline forEachBound(control, (action, _) -> removeKeys(action, keys));
|
||||
#else
|
||||
forEachBound(control, function(action, _) removeKeys(action, keys));
|
||||
#end
|
||||
}
|
||||
|
||||
inline static function addKeys(action:FlxActionDigital, keys:Array<FlxKey>, state:FlxInputState)
|
||||
|
@ -494,65 +459,43 @@ class Controls extends FlxActionSet
|
|||
|
||||
keyboardScheme = scheme;
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
switch (scheme)
|
||||
{
|
||||
case Solo:
|
||||
inline bindKeys(Control.UP, [W, FlxKey.UP]);
|
||||
inline bindKeys(Control.DOWN, [S, FlxKey.DOWN]);
|
||||
inline bindKeys(Control.LEFT, [A, FlxKey.LEFT]);
|
||||
inline bindKeys(Control.RIGHT, [D, FlxKey.RIGHT]);
|
||||
inline bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]);
|
||||
inline bindKeys(Control.BACK, [BACKSPACE, ESCAPE]);
|
||||
inline bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]);
|
||||
inline bindKeys(Control.RESET, [R]);
|
||||
case Duo(true):
|
||||
inline bindKeys(Control.UP, [W]);
|
||||
inline bindKeys(Control.DOWN, [S]);
|
||||
inline bindKeys(Control.LEFT, [A]);
|
||||
inline bindKeys(Control.RIGHT, [D]);
|
||||
inline bindKeys(Control.ACCEPT, [G, Z]);
|
||||
inline bindKeys(Control.BACK, [H, X]);
|
||||
inline bindKeys(Control.PAUSE, [ONE]);
|
||||
inline bindKeys(Control.RESET, [R]);
|
||||
case Duo(false):
|
||||
inline bindKeys(Control.UP, [FlxKey.UP]);
|
||||
inline bindKeys(Control.DOWN, [FlxKey.DOWN]);
|
||||
inline bindKeys(Control.LEFT, [FlxKey.LEFT]);
|
||||
inline bindKeys(Control.RIGHT, [FlxKey.RIGHT]);
|
||||
inline bindKeys(Control.ACCEPT, [O]);
|
||||
inline bindKeys(Control.BACK, [P]);
|
||||
inline bindKeys(Control.PAUSE, [ENTER]);
|
||||
inline bindKeys(Control.RESET, [BACKSPACE]);
|
||||
case None: // nothing
|
||||
case Custom: // nothing
|
||||
}
|
||||
#else
|
||||
switch (scheme)
|
||||
{
|
||||
case Solo:
|
||||
bindKeys(Control.UP, [W, FlxKey.UP]);
|
||||
bindKeys(Control.DOWN, [S, FlxKey.DOWN]);
|
||||
bindKeys(Control.LEFT, [A, FlxKey.LEFT]);
|
||||
bindKeys(Control.RIGHT, [D, FlxKey.RIGHT]);
|
||||
bindKeys(Control.UI_UP, [W, FlxKey.UP]);
|
||||
bindKeys(Control.UI_DOWN, [S, FlxKey.DOWN]);
|
||||
bindKeys(Control.UI_LEFT, [A, FlxKey.LEFT]);
|
||||
bindKeys(Control.UI_RIGHT, [D, FlxKey.RIGHT]);
|
||||
bindKeys(Control.NOTE_UP, [W, FlxKey.UP]);
|
||||
bindKeys(Control.NOTE_DOWN, [S, FlxKey.DOWN]);
|
||||
bindKeys(Control.NOTE_LEFT, [A, FlxKey.LEFT]);
|
||||
bindKeys(Control.NOTE_RIGHT, [D, FlxKey.RIGHT]);
|
||||
bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]);
|
||||
bindKeys(Control.BACK, [BACKSPACE, ESCAPE]);
|
||||
bindKeys(Control.BACK, [X, BACKSPACE, ESCAPE]);
|
||||
bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]);
|
||||
bindKeys(Control.RESET, [R]);
|
||||
case Duo(true):
|
||||
bindKeys(Control.UP, [W]);
|
||||
bindKeys(Control.DOWN, [S]);
|
||||
bindKeys(Control.LEFT, [A]);
|
||||
bindKeys(Control.RIGHT, [D]);
|
||||
bindKeys(Control.UI_UP, [W]);
|
||||
bindKeys(Control.UI_DOWN, [S]);
|
||||
bindKeys(Control.UI_LEFT, [A]);
|
||||
bindKeys(Control.UI_RIGHT, [D]);
|
||||
bindKeys(Control.NOTE_UP, [W]);
|
||||
bindKeys(Control.NOTE_DOWN, [S]);
|
||||
bindKeys(Control.NOTE_LEFT, [A]);
|
||||
bindKeys(Control.NOTE_RIGHT, [D]);
|
||||
bindKeys(Control.ACCEPT, [G, Z]);
|
||||
bindKeys(Control.BACK, [H, X]);
|
||||
bindKeys(Control.PAUSE, [ONE]);
|
||||
bindKeys(Control.RESET, [R]);
|
||||
case Duo(false):
|
||||
bindKeys(Control.UP, [FlxKey.UP]);
|
||||
bindKeys(Control.DOWN, [FlxKey.DOWN]);
|
||||
bindKeys(Control.LEFT, [FlxKey.LEFT]);
|
||||
bindKeys(Control.RIGHT, [FlxKey.RIGHT]);
|
||||
bindKeys(Control.UI_UP, [FlxKey.UP]);
|
||||
bindKeys(Control.UI_DOWN, [FlxKey.DOWN]);
|
||||
bindKeys(Control.UI_LEFT, [FlxKey.LEFT]);
|
||||
bindKeys(Control.UI_RIGHT, [FlxKey.RIGHT]);
|
||||
bindKeys(Control.NOTE_UP, [FlxKey.UP]);
|
||||
bindKeys(Control.NOTE_DOWN, [FlxKey.DOWN]);
|
||||
bindKeys(Control.NOTE_LEFT, [FlxKey.LEFT]);
|
||||
bindKeys(Control.NOTE_RIGHT, [FlxKey.RIGHT]);
|
||||
bindKeys(Control.ACCEPT, [O]);
|
||||
bindKeys(Control.BACK, [P]);
|
||||
bindKeys(Control.PAUSE, [ENTER]);
|
||||
|
@ -560,7 +503,6 @@ class Controls extends FlxActionSet
|
|||
case None: // nothing
|
||||
case Custom: // nothing
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
function removeKeyboard()
|
||||
|
@ -577,30 +519,19 @@ class Controls extends FlxActionSet
|
|||
}
|
||||
}
|
||||
|
||||
public function addGamepad(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
|
||||
public function addGamepadWithSaveData(id:Int, ?padData:Dynamic):Void
|
||||
{
|
||||
gamepadsAdded.push(id);
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
for (control => buttons in buttonMap)
|
||||
inline bindButtons(control, id, buttons);
|
||||
#else
|
||||
for (control in buttonMap.keys())
|
||||
bindButtons(control, id, buttonMap[control]);
|
||||
#end
|
||||
fromSaveData(padData, Gamepad(id));
|
||||
}
|
||||
|
||||
inline function addGamepadLiteral(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
|
||||
{
|
||||
gamepadsAdded.push(id);
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
for (control => buttons in buttonMap)
|
||||
inline bindButtons(control, id, buttons);
|
||||
#else
|
||||
for (control in buttonMap.keys())
|
||||
bindButtons(control, id, buttonMap[control]);
|
||||
#end
|
||||
}
|
||||
|
||||
public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void
|
||||
|
@ -611,7 +542,7 @@ class Controls extends FlxActionSet
|
|||
while (i-- > 0)
|
||||
{
|
||||
var input = action.inputs[i];
|
||||
if (input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID))
|
||||
if (isGamepad(input, deviceID))
|
||||
action.remove(input);
|
||||
}
|
||||
}
|
||||
|
@ -621,32 +552,25 @@ class Controls extends FlxActionSet
|
|||
|
||||
public function addDefaultGamepad(id):Void
|
||||
{
|
||||
#if !switch
|
||||
addGamepadLiteral(id, [
|
||||
Control.ACCEPT => [A],
|
||||
Control.BACK => [B],
|
||||
Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP],
|
||||
Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN],
|
||||
Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT],
|
||||
Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT],
|
||||
|
||||
Control.ACCEPT => [#if switch B #else A #end],
|
||||
Control.BACK => [#if switch A #else B #end, FlxGamepadInputID.BACK],
|
||||
Control.UI_UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP],
|
||||
Control.UI_DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN],
|
||||
Control.UI_LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT],
|
||||
Control.UI_RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT],
|
||||
// don't swap A/B or X/Y for switch on these. A is always the bottom face button
|
||||
Control.NOTE_UP => [DPAD_UP, Y, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP],
|
||||
Control.NOTE_DOWN => [DPAD_DOWN, A, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN],
|
||||
Control.NOTE_LEFT => [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT],
|
||||
Control.NOTE_RIGHT => [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT],
|
||||
Control.PAUSE => [START],
|
||||
Control.RESET => [Y]
|
||||
#if CAN_CHEAT
|
||||
,Control.CHEAT => [X]
|
||||
#end
|
||||
]);
|
||||
#else
|
||||
addGamepadLiteral(id, [
|
||||
//Swap A and B for switch
|
||||
Control.ACCEPT => [B],
|
||||
Control.BACK => [A],
|
||||
Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP],
|
||||
Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN],
|
||||
Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT],
|
||||
Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT],
|
||||
Control.PAUSE => [START],
|
||||
//Swap Y and X for switch
|
||||
Control.RESET => [Y],
|
||||
Control.CHEAT => [X]
|
||||
]);
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -655,11 +579,7 @@ class Controls extends FlxActionSet
|
|||
*/
|
||||
public function bindButtons(control:Control, id, buttons)
|
||||
{
|
||||
#if (haxe >= "4.0.0")
|
||||
inline forEachBound(control, (action, state) -> addButtons(action, buttons, state, id));
|
||||
#else
|
||||
forEachBound(control, function(action, state) addButtons(action, buttons, state, id));
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -668,11 +588,7 @@ class Controls extends FlxActionSet
|
|||
*/
|
||||
public function unbindButtons(control:Control, gamepadID:Int, buttons)
|
||||
{
|
||||
#if (haxe >= "4.0.0")
|
||||
inline forEachBound(control, (action, _) -> removeButtons(action, gamepadID, buttons));
|
||||
#else
|
||||
forEachBound(control, function(action, _) removeButtons(action, gamepadID, buttons));
|
||||
#end
|
||||
}
|
||||
|
||||
inline static function addButtons(action:FlxActionDigital, buttons:Array<FlxGamepadInputID>, state, id)
|
||||
|
@ -708,7 +624,7 @@ class Controls extends FlxActionSet
|
|||
case Gamepad(id):
|
||||
for (input in getActionFromControl(control).inputs)
|
||||
{
|
||||
if (input.deviceID == id)
|
||||
if (isGamepad(input, id))
|
||||
list.push(input.inputID);
|
||||
}
|
||||
}
|
||||
|
@ -726,6 +642,37 @@ class Controls extends FlxActionSet
|
|||
}
|
||||
}
|
||||
|
||||
public function fromSaveData(data:Dynamic, device:Device)
|
||||
{
|
||||
for (control in Control.createAll())
|
||||
{
|
||||
var inputs:Array<Int> = Reflect.field(data, control.getName());
|
||||
if (inputs != null)
|
||||
{
|
||||
switch(device)
|
||||
{
|
||||
case Keys: bindKeys(control, inputs.copy());
|
||||
case Gamepad(id): bindButtons(control, id, inputs.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function createSaveData(device:Device):Dynamic
|
||||
{
|
||||
var isEmpty = true;
|
||||
var data = {};
|
||||
for (control in Control.createAll())
|
||||
{
|
||||
var inputs = getInputsFor(control, device);
|
||||
isEmpty = isEmpty && inputs.length == 0;
|
||||
|
||||
Reflect.setField(data, control.getName(), inputs);
|
||||
}
|
||||
|
||||
return isEmpty ? null : data;
|
||||
}
|
||||
|
||||
static function isDevice(input:FlxActionInput, device:Device)
|
||||
{
|
||||
return switch device
|
||||
|
@ -740,3 +687,6 @@ class Controls extends FlxActionSet
|
|||
return input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef SaveInputLists = {?keys:Array<Int>, ?pad:Array<Int>};
|
|
@ -201,8 +201,8 @@ class FreeplayState extends MusicBeatState
|
|||
|
||||
scoreText.text = "PERSONAL BEST:" + lerpScore;
|
||||
|
||||
var upP = controls.UP_P;
|
||||
var downP = controls.DOWN_P;
|
||||
var upP = controls.UI_UP_P;
|
||||
var downP = controls.UI_DOWN_P;
|
||||
var accepted = controls.ACCEPT;
|
||||
|
||||
if (upP)
|
||||
|
@ -214,9 +214,9 @@ class FreeplayState extends MusicBeatState
|
|||
changeSelection(1);
|
||||
}
|
||||
|
||||
if (controls.LEFT_P)
|
||||
if (controls.UI_LEFT_P)
|
||||
changeDiff(-1);
|
||||
if (controls.RIGHT_P)
|
||||
if (controls.UI_RIGHT_P)
|
||||
changeDiff(1);
|
||||
|
||||
if (controls.BACK)
|
||||
|
@ -246,9 +246,7 @@ class FreeplayState extends MusicBeatState
|
|||
if (curDifficulty > 2)
|
||||
curDifficulty = 0;
|
||||
|
||||
#if !switch
|
||||
intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty);
|
||||
#end
|
||||
|
||||
PlayState.storyDifficulty = curDifficulty;
|
||||
|
||||
|
@ -259,9 +257,7 @@ class FreeplayState extends MusicBeatState
|
|||
|
||||
function changeSelection(change:Int = 0)
|
||||
{
|
||||
#if !switch
|
||||
NGio.logEvent('Fresh');
|
||||
#end
|
||||
|
||||
// NGio.logEvent('Fresh');
|
||||
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
|
||||
|
@ -275,10 +271,8 @@ class FreeplayState extends MusicBeatState
|
|||
|
||||
// selector.y = (70 * curSelected) + 30;
|
||||
|
||||
#if !switch
|
||||
intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty);
|
||||
// lerpScore = 0;
|
||||
#end
|
||||
|
||||
#if PRELOAD_ALL
|
||||
FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName), 0);
|
||||
|
|
|
@ -52,7 +52,7 @@ class GitarooPause extends MusicBeatState
|
|||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
if (controls.LEFT_P || controls.RIGHT_P)
|
||||
if (controls.UI_LEFT_P || controls.UI_RIGHT_P)
|
||||
changeThing();
|
||||
|
||||
if (controls.ACCEPT)
|
||||
|
|
|
@ -13,51 +13,55 @@ class Highscore
|
|||
|
||||
public static function saveScore(song:String, score:Int = 0, ?diff:Int = 0):Void
|
||||
{
|
||||
var daSong:String = formatSong(song, diff);
|
||||
var formattedSong:String = formatSong(song, diff);
|
||||
|
||||
|
||||
#if !switch
|
||||
#if newgrounds
|
||||
NGio.postScore(score, song);
|
||||
#end
|
||||
|
||||
|
||||
if (songScores.exists(daSong))
|
||||
if (songScores.exists(formattedSong))
|
||||
{
|
||||
if (songScores.get(daSong) < score)
|
||||
setScore(daSong, score);
|
||||
if (songScores.get(formattedSong) < score)
|
||||
setScore(formattedSong, score);
|
||||
}
|
||||
else
|
||||
setScore(daSong, score);
|
||||
setScore(formattedSong, score);
|
||||
}
|
||||
|
||||
public static function saveWeekScore(week:Int = 1, score:Int = 0, ?diff:Int = 0):Void
|
||||
{
|
||||
|
||||
#if !switch
|
||||
#if newgrounds
|
||||
NGio.postScore(score, "Week " + week);
|
||||
#end
|
||||
|
||||
var formattedSong:String = formatSong('week' + week, diff);
|
||||
|
||||
var daWeek:String = formatSong('week' + week, diff);
|
||||
|
||||
if (songScores.exists(daWeek))
|
||||
if (songScores.exists(formattedSong))
|
||||
{
|
||||
if (songScores.get(daWeek) < score)
|
||||
setScore(daWeek, score);
|
||||
if (songScores.get(formattedSong) < score)
|
||||
setScore(formattedSong, score);
|
||||
}
|
||||
else
|
||||
setScore(daWeek, score);
|
||||
setScore(formattedSong, score);
|
||||
}
|
||||
|
||||
/**
|
||||
* YOU SHOULD FORMAT SONG WITH formatSong() BEFORE TOSSING IN SONG VARIABLE
|
||||
*/
|
||||
static function setScore(song:String, score:Int):Void
|
||||
static function setScore(formattedSong:String, score:Int):Void
|
||||
{
|
||||
/** GeoKureli
|
||||
* References to Highscore were wrapped in `#if !switch` blocks. I wasn't sure if this
|
||||
* is because switch doesn't use NGio, or because switch has a different saving method.
|
||||
* I moved the compiler flag here, rather than using it everywhere else.
|
||||
*/
|
||||
#if !switch
|
||||
|
||||
// Reminder that I don't need to format this song, it should come formatted!
|
||||
songScores.set(song, score);
|
||||
songScores.set(formattedSong, score);
|
||||
FlxG.save.data.songScores = songScores;
|
||||
FlxG.save.flush();
|
||||
#end
|
||||
}
|
||||
|
||||
public static function formatSong(song:String, diff:Int):String
|
||||
|
|
220
source/InputFormatter.hx
Normal file
220
source/InputFormatter.hx
Normal file
|
@ -0,0 +1,220 @@
|
|||
package ;
|
||||
|
||||
import Controls;
|
||||
|
||||
import flixel.FlxG;
|
||||
import flixel.input.gamepad.FlxGamepad;
|
||||
import flixel.input.gamepad.FlxGamepadInputID;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
|
||||
using flixel.util.FlxStringUtil;
|
||||
|
||||
class InputFormatter
|
||||
{
|
||||
static public function format(id:Int, device:Device):String
|
||||
{
|
||||
return switch (device)
|
||||
{
|
||||
case Keys: getKeyName(id);
|
||||
case Gamepad(gamepadID): getButtonName(id, FlxG.gamepads.getByID(gamepadID));
|
||||
}
|
||||
}
|
||||
|
||||
static public function getKeyName(id:Int):String
|
||||
{
|
||||
return switch(id)
|
||||
{
|
||||
case ZERO : "0";
|
||||
case ONE : "1";
|
||||
case TWO : "2";
|
||||
case THREE : "3";
|
||||
case FOUR : "4";
|
||||
case FIVE : "5";
|
||||
case SIX : "6";
|
||||
case SEVEN : "7";
|
||||
case EIGHT : "8";
|
||||
case NINE : "9";
|
||||
case PAGEUP : "PgUp";
|
||||
case PAGEDOWN : "PgDown";
|
||||
// case HOME : "Hm";
|
||||
// case END : "End";
|
||||
// case INSERT : "Ins";
|
||||
// case ESCAPE : "Esc";
|
||||
// case MINUS : "-";
|
||||
// case PLUS : "+";
|
||||
// case DELETE : "Del";
|
||||
case BACKSPACE : "BckSpc";
|
||||
case LBRACKET : "[";
|
||||
case RBRACKET : "]";
|
||||
case BACKSLASH : "\\";
|
||||
case CAPSLOCK : "Caps";
|
||||
case SEMICOLON : ";";
|
||||
case QUOTE : "'";
|
||||
// case ENTER : "Ent";
|
||||
// case SHIFT : "Shf";
|
||||
case COMMA : ",";
|
||||
case PERIOD : ".";
|
||||
case SLASH : "/";
|
||||
case GRAVEACCENT : "`";
|
||||
case CONTROL : "Ctrl";
|
||||
case ALT : "Alt";
|
||||
// case SPACE : "Spc";
|
||||
// case UP : "Up";
|
||||
// case DOWN : "Dn";
|
||||
// case LEFT : "Lf";
|
||||
// case RIGHT : "Rt";
|
||||
// case TAB : "Tab";
|
||||
case PRINTSCREEN : "PrtScrn";
|
||||
case NUMPADZERO : "#0";
|
||||
case NUMPADONE : "#1";
|
||||
case NUMPADTWO : "#2";
|
||||
case NUMPADTHREE : "#3";
|
||||
case NUMPADFOUR : "#4";
|
||||
case NUMPADFIVE : "#5";
|
||||
case NUMPADSIX : "#6";
|
||||
case NUMPADSEVEN : "#7";
|
||||
case NUMPADEIGHT : "#8";
|
||||
case NUMPADNINE : "#9";
|
||||
case NUMPADMINUS : "#-";
|
||||
case NUMPADPLUS : "#+";
|
||||
case NUMPADPERIOD : "#.";
|
||||
case NUMPADMULTIPLY: "#*";
|
||||
default: titleCase(FlxKey.toStringMap[id]);
|
||||
}
|
||||
}
|
||||
|
||||
static var dirReg = ~/^(l|r).?-(left|right|down|up)$/;
|
||||
inline static public function getButtonName(id:Int, gamepad:FlxGamepad):String
|
||||
{
|
||||
return switch(gamepad.getInputLabel(id))
|
||||
{
|
||||
// case null | "": shortenButtonName(FlxGamepadInputID.toStringMap[id]);
|
||||
case label: shortenButtonName(label);
|
||||
}
|
||||
}
|
||||
|
||||
static function shortenButtonName(name:String)
|
||||
{
|
||||
return switch (name == null ? "" : name.toLowerCase())
|
||||
{
|
||||
case "": "[?]";
|
||||
// case "square" : "[]";
|
||||
// case "circle" : "()";
|
||||
// case "triangle": "/\\";
|
||||
// case "plus" : "+";
|
||||
// case "minus" : "-";
|
||||
// case "home" : "Hm";
|
||||
// case "guide" : "Gd";
|
||||
// case "back" : "Bk";
|
||||
// case "select" : "Bk";
|
||||
// case "start" : "St";
|
||||
// case "left" : "Lf";
|
||||
// case "right" : "Rt";
|
||||
// case "down" : "Dn";
|
||||
// case "up" : "Up";
|
||||
case dir if (dirReg.match(dir)):
|
||||
dirReg.matched(1).toUpperCase() + " " + titleCase(dirReg.matched(2));
|
||||
case label: titleCase(label);
|
||||
}
|
||||
}
|
||||
|
||||
inline static function titleCaseTrim(str:String, length = 8)
|
||||
{
|
||||
return str.charAt(0).toUpperCase() + str.substr(1, length - 1).toLowerCase();
|
||||
}
|
||||
|
||||
inline static function titleCase(str:String)
|
||||
{
|
||||
return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
|
||||
}
|
||||
|
||||
inline static public function parsePadName(name:String):ControllerName
|
||||
{
|
||||
return ControllerName.parseName(name);
|
||||
}
|
||||
|
||||
inline static public function getPadName(gamepad:FlxGamepad):ControllerName
|
||||
{
|
||||
return ControllerName.getName(gamepad);
|
||||
}
|
||||
|
||||
inline static public function getPadNameById(id:Int):ControllerName
|
||||
{
|
||||
return ControllerName.getNameById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@:forward
|
||||
@:enum abstract ControllerName(String) from String to String
|
||||
{
|
||||
var OUYA = "Ouya" ;
|
||||
var PS4 = "PS4" ;
|
||||
var LOGI = "Logi" ;
|
||||
var XBOX = "XBox" ;
|
||||
var XINPUT = "XInput" ;
|
||||
var WII = "Wii" ;
|
||||
var PRO_CON = "Pro_Con" ;
|
||||
var JOYCONS = "Joycons" ;
|
||||
var JOYCON_L = "Joycon_L";
|
||||
var JOYCON_R = "Joycon_R";
|
||||
var MFI = "MFI" ;
|
||||
var PAD = "Pad" ;
|
||||
|
||||
static public function getAssetByDevice(device:Device):String
|
||||
{
|
||||
return switch (device)
|
||||
{
|
||||
case Keys: getAsset(null);
|
||||
case Gamepad(id): getAsset(FlxG.gamepads.getByID(id));
|
||||
}
|
||||
}
|
||||
|
||||
static public function getAsset(gamepad:FlxGamepad):String
|
||||
{
|
||||
if (gamepad == null)
|
||||
return 'assets/images/ui/devices/Keys.png';
|
||||
|
||||
final name = parseName(gamepad.name);
|
||||
var path = 'assets/images/ui/devices/$name.png';
|
||||
if (openfl.utils.Assets.exists(path))
|
||||
return path;
|
||||
|
||||
return 'assets/images/ui/devices/Pad.png';
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline static public function getNameById(id:Int):ControllerName return getName(FlxG.gamepads.getByID(id));
|
||||
inline static public function getName(gamepad:FlxGamepad):ControllerName return parseName(gamepad.name);
|
||||
static public function parseName(name:String):ControllerName
|
||||
{
|
||||
name = name.toLowerCase().remove("-").remove("_");
|
||||
return
|
||||
if (name.contains("ouya"))
|
||||
OUYA;
|
||||
else if (name.contains("wireless controller") || name.contains("ps4"))
|
||||
PS4;
|
||||
else if (name.contains("logitech"))
|
||||
LOGI;
|
||||
else if (name.contains("xbox"))
|
||||
XBOX
|
||||
else if (name.contains("xinput"))
|
||||
XINPUT;
|
||||
else if (name.contains("nintendo rvlcnt01tr") || name.contains("nintendo rvlcnt01"))
|
||||
WII;
|
||||
else if (name.contains("mayflash wiimote pc adapter"))
|
||||
WII;
|
||||
else if (name.contains("pro controller"))
|
||||
PRO_CON;
|
||||
else if (name.contains("joycon l+r"))
|
||||
JOYCONS;
|
||||
else if (name.contains("joycon (l)"))
|
||||
JOYCON_L;
|
||||
else if (name.contains("joycon (r)"))
|
||||
JOYCON_R;
|
||||
else if (name.contains("mfi"))
|
||||
MFI;
|
||||
else
|
||||
PAD;
|
||||
}
|
||||
}
|
|
@ -75,7 +75,7 @@ class LoadingState extends MusicBeatState
|
|||
if (!Assets.cache.hasSound(path))
|
||||
{
|
||||
var library = Assets.getLibrary("songs");
|
||||
final symbolPath = path.split(":").pop();
|
||||
var symbolPath = path.split(":").pop();
|
||||
// @:privateAccess
|
||||
// library.types.set(symbolPath, SOUND);
|
||||
// @:privateAccess
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package;
|
||||
|
||||
#if desktop
|
||||
import Discord.DiscordClient;
|
||||
#end
|
||||
import NGio;
|
||||
|
||||
import flixel.ui.FlxButton;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxObject;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.FlxState;
|
||||
import flixel.addons.transition.FlxTransitionableState;
|
||||
import flixel.effects.FlxFlicker;
|
||||
import flixel.graphics.frames.FlxAtlasFrames;
|
||||
|
@ -14,22 +15,28 @@ import flixel.text.FlxText;
|
|||
import flixel.tweens.FlxEase;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.util.FlxColor;
|
||||
import io.newgrounds.NG;
|
||||
import flixel.util.FlxTimer;
|
||||
import lime.app.Application;
|
||||
|
||||
#if desktop
|
||||
import Discord.DiscordClient;
|
||||
#end
|
||||
|
||||
#if newgrounds
|
||||
import io.newgrounds.NG;
|
||||
import ui.NgPrompt;
|
||||
#end
|
||||
|
||||
import ui.AtlasMenuList;
|
||||
import ui.MenuList;
|
||||
import ui.OptionsState;
|
||||
import ui.Prompt;
|
||||
|
||||
using StringTools;
|
||||
|
||||
class MainMenuState extends MusicBeatState
|
||||
{
|
||||
var curSelected:Int = 0;
|
||||
|
||||
var menuItems:FlxTypedGroup<FlxSprite>;
|
||||
|
||||
#if !switch
|
||||
var optionShit:Array<String> = ['story mode', 'freeplay', 'donate', 'options'];
|
||||
#else
|
||||
var optionShit:Array<String> = ['story mode', 'freeplay'];
|
||||
#end
|
||||
var menuItems:MainMenuList;
|
||||
|
||||
var magenta:FlxSprite;
|
||||
var camFollow:FlxObject;
|
||||
|
@ -51,10 +58,10 @@ class MainMenuState extends MusicBeatState
|
|||
|
||||
persistentUpdate = persistentDraw = true;
|
||||
|
||||
var bg:FlxSprite = new FlxSprite(-80).loadGraphic(Paths.image('menuBG'));
|
||||
var bg:FlxSprite = new FlxSprite(Paths.image('menuBG'));
|
||||
bg.scrollFactor.x = 0;
|
||||
bg.scrollFactor.y = 0.17;
|
||||
bg.setGraphicSize(Std.int(bg.width * 1.1));
|
||||
bg.setGraphicSize(Std.int(bg.width * 1.2));
|
||||
bg.updateHitbox();
|
||||
bg.screenCenter();
|
||||
bg.antialiasing = true;
|
||||
|
@ -63,38 +70,57 @@ class MainMenuState extends MusicBeatState
|
|||
camFollow = new FlxObject(0, 0, 1, 1);
|
||||
add(camFollow);
|
||||
|
||||
magenta = new FlxSprite(-80).loadGraphic(Paths.image('menuDesat'));
|
||||
magenta.scrollFactor.x = 0;
|
||||
magenta.scrollFactor.y = 0.17;
|
||||
magenta.setGraphicSize(Std.int(magenta.width * 1.1));
|
||||
magenta = new FlxSprite(Paths.image('menuDesat'));
|
||||
magenta.scrollFactor.x = bg.scrollFactor.x;
|
||||
magenta.scrollFactor.y = bg.scrollFactor.y;
|
||||
magenta.setGraphicSize(Std.int(bg.width));
|
||||
magenta.updateHitbox();
|
||||
magenta.screenCenter();
|
||||
magenta.x = bg.x;
|
||||
magenta.y = bg.y;
|
||||
magenta.visible = false;
|
||||
magenta.antialiasing = true;
|
||||
magenta.color = 0xFFfd719b;
|
||||
add(magenta);
|
||||
// magenta.scrollFactor.set();
|
||||
|
||||
menuItems = new FlxTypedGroup<FlxSprite>();
|
||||
menuItems = new MainMenuList();
|
||||
add(menuItems);
|
||||
|
||||
var tex = Paths.getSparrowAtlas('FNF_main_menu_assets');
|
||||
|
||||
for (i in 0...optionShit.length)
|
||||
menuItems.onChange.add(onMenuItemChange);
|
||||
menuItems.onAcceptPress.add(function(_)
|
||||
{
|
||||
var menuItem:FlxSprite = new FlxSprite(0, 60 + (i * 160));
|
||||
menuItem.frames = tex;
|
||||
menuItem.animation.addByPrefix('idle', optionShit[i] + " basic", 24);
|
||||
menuItem.animation.addByPrefix('selected', optionShit[i] + " white", 24);
|
||||
menuItem.animation.play('idle');
|
||||
menuItem.ID = i;
|
||||
menuItem.screenCenter(X);
|
||||
menuItems.add(menuItem);
|
||||
menuItem.scrollFactor.set();
|
||||
menuItem.antialiasing = true;
|
||||
FlxFlicker.flicker(magenta, 1.1, 0.15, false, true);
|
||||
});
|
||||
|
||||
|
||||
|
||||
menuItems.enabled = false;// disable for intro
|
||||
menuItems.createItem('story mode', function () startExitState(new StoryMenuState()));
|
||||
menuItems.createItem('freeplay', function () startExitState(new FreeplayState()));
|
||||
// addMenuItem('options', function () startExitState(new OptionMenu()));
|
||||
#if CAN_OPEN_LINKS
|
||||
var hasPopupBlocker = #if web true #else false #end;
|
||||
menuItems.createItem('donate', selectDonate, hasPopupBlocker);
|
||||
#end
|
||||
menuItems.createItem('options', function () startExitState(new OptionsState()));
|
||||
// #if newgrounds
|
||||
// if (NGio.isLoggedIn)
|
||||
// menuItems.createItem("logout", selectLogout);
|
||||
// else
|
||||
// menuItems.createItem("login", selectLogin);
|
||||
// #end
|
||||
|
||||
// center vertically
|
||||
var spacing = 160;
|
||||
var top = (FlxG.height - (spacing * (menuItems.length - 1))) / 2;
|
||||
for (i in 0...menuItems.length)
|
||||
{
|
||||
var menuItem = menuItems.members[i];
|
||||
menuItem.x = FlxG.width / 2;
|
||||
menuItem.y = top + spacing * i;
|
||||
}
|
||||
|
||||
FlxG.camera.follow(camFollow, null, 0.06);
|
||||
// FlxG.camera.setScrollBounds(bg.x, bg.x + bg.width, bg.y, bg.y + bg.height * 1.2);
|
||||
|
||||
var versionShit:FlxText = new FlxText(5, FlxG.height - 18, 0, "v" + Application.current.meta.get('version'), 12);
|
||||
versionShit.scrollFactor.set();
|
||||
|
@ -103,12 +129,113 @@ class MainMenuState extends MusicBeatState
|
|||
|
||||
// NG.core.calls.event.logEvent('swag').send();
|
||||
|
||||
changeItem();
|
||||
|
||||
super.create();
|
||||
}
|
||||
|
||||
var selectedSomethin:Bool = false;
|
||||
|
||||
override function finishTransIn()
|
||||
{
|
||||
super.finishTransIn();
|
||||
|
||||
menuItems.enabled = true;
|
||||
|
||||
// #if newgrounds
|
||||
// if (NGio.savedSessionFailed)
|
||||
// showSavedSessionFailed();
|
||||
// #end
|
||||
}
|
||||
|
||||
function onMenuItemChange(selected:MenuItem)
|
||||
{
|
||||
camFollow.setPosition(selected.getGraphicMidpoint().x, selected.getGraphicMidpoint().y);
|
||||
}
|
||||
|
||||
#if CAN_OPEN_LINKS
|
||||
function selectDonate()
|
||||
{
|
||||
#if linux
|
||||
Sys.command('/usr/bin/xdg-open', ["https://ninja-muffin24.itch.io/funkin", "&"]);
|
||||
#else
|
||||
FlxG.openURL('https://ninja-muffin24.itch.io/funkin');
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if newgrounds
|
||||
function selectLogin()
|
||||
{
|
||||
openNgPrompt(NgPrompt.showLogin());
|
||||
}
|
||||
|
||||
function selectLogout()
|
||||
{
|
||||
openNgPrompt(NgPrompt.showLogout());
|
||||
}
|
||||
|
||||
function showSavedSessionFailed()
|
||||
{
|
||||
openNgPrompt(NgPrompt.showSavedSessionFailed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls openPrompt and redraws the login/logout button
|
||||
* @param prompt
|
||||
* @param onClose
|
||||
*/
|
||||
public function openNgPrompt(prompt:Prompt, ?onClose:Void->Void)
|
||||
{
|
||||
var onPromptClose = checkLoginStatus;
|
||||
if (onClose != null)
|
||||
{
|
||||
onPromptClose = function ()
|
||||
{
|
||||
checkLoginStatus();
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
openPrompt(prompt, onPromptClose);
|
||||
}
|
||||
|
||||
function checkLoginStatus()
|
||||
{
|
||||
var prevLoggedIn = menuItems.has("logout");
|
||||
if (prevLoggedIn && !NGio.isLoggedIn)
|
||||
menuItems.resetItem("login", "logout", selectLogout);
|
||||
else if (!prevLoggedIn && NGio.isLoggedIn)
|
||||
menuItems.resetItem("logout", "login", selectLogin);
|
||||
}
|
||||
#end
|
||||
|
||||
public function openPrompt(prompt:Prompt, onClose:Void->Void)
|
||||
{
|
||||
menuItems.enabled = false;
|
||||
prompt.closeCallback = function ()
|
||||
{
|
||||
menuItems.enabled = true;
|
||||
if (onClose != null)
|
||||
onClose();
|
||||
}
|
||||
|
||||
openSubState(prompt);
|
||||
}
|
||||
|
||||
function startExitState(state:FlxState)
|
||||
{
|
||||
var duration = 0.4;
|
||||
menuItems.forEach(function(item)
|
||||
{
|
||||
if (menuItems.selectedIndex != item.ID)
|
||||
{
|
||||
FlxTween.tween(item, {alpha: 0}, duration, { ease: FlxEase.quadOut });
|
||||
}
|
||||
else
|
||||
{
|
||||
item.visible = false;
|
||||
}
|
||||
});
|
||||
|
||||
new FlxTimer().start(duration, function(_) FlxG.switchState(state));
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
|
@ -117,124 +244,52 @@ class MainMenuState extends MusicBeatState
|
|||
FlxG.sound.music.volume += 0.5 * FlxG.elapsed;
|
||||
}
|
||||
|
||||
if (!selectedSomethin)
|
||||
{
|
||||
if (controls.UP_P)
|
||||
{
|
||||
FlxG.sound.play(Paths.sound('scrollMenu'));
|
||||
changeItem(-1);
|
||||
}
|
||||
|
||||
if (controls.DOWN_P)
|
||||
{
|
||||
FlxG.sound.play(Paths.sound('scrollMenu'));
|
||||
changeItem(1);
|
||||
}
|
||||
|
||||
if (controls.BACK)
|
||||
{
|
||||
FlxG.switchState(new TitleState());
|
||||
}
|
||||
|
||||
if (controls.ACCEPT)
|
||||
{
|
||||
if (optionShit[curSelected] == 'donate')
|
||||
{
|
||||
#if linux
|
||||
Sys.command('/usr/bin/xdg-open', ["https://ninja-muffin24.itch.io/funkin", "&"]);
|
||||
#else
|
||||
FlxG.openURL('https://ninja-muffin24.itch.io/funkin');
|
||||
#end
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedSomethin = true;
|
||||
FlxG.sound.play(Paths.sound('confirmMenu'));
|
||||
|
||||
FlxFlicker.flicker(magenta, 1.1, 0.15, false);
|
||||
|
||||
menuItems.forEach(function(spr:FlxSprite)
|
||||
{
|
||||
if (curSelected != spr.ID)
|
||||
{
|
||||
FlxTween.tween(spr, {alpha: 0}, 0.4, {
|
||||
ease: FlxEase.quadOut,
|
||||
onComplete: function(twn:FlxTween)
|
||||
{
|
||||
spr.kill();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
FlxFlicker.flicker(spr, 1, 0.06, false, false, function(flick:FlxFlicker)
|
||||
{
|
||||
var daChoice:String = optionShit[curSelected];
|
||||
|
||||
switch (daChoice)
|
||||
{
|
||||
case 'story mode':
|
||||
FlxG.switchState(new StoryMenuState());
|
||||
trace("Story Menu Selected");
|
||||
case 'freeplay':
|
||||
FlxG.switchState(new FreeplayState());
|
||||
|
||||
trace("Freeplay Menu Selected");
|
||||
|
||||
case 'options':
|
||||
FlxTransitionableState.skipNextTransIn = true;
|
||||
FlxTransitionableState.skipNextTransOut = true;
|
||||
FlxG.switchState(new OptionsMenu());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (menuItems.enabled && controls.BACK)
|
||||
FlxG.switchState(new TitleState());
|
||||
|
||||
super.update(elapsed);
|
||||
|
||||
menuItems.forEach(function(spr:FlxSprite)
|
||||
{
|
||||
spr.screenCenter(X);
|
||||
});
|
||||
}
|
||||
|
||||
function changeItem(huh:Int = 0)
|
||||
{
|
||||
curSelected += huh;
|
||||
|
||||
if (curSelected >= menuItems.length)
|
||||
curSelected = 0;
|
||||
if (curSelected < 0)
|
||||
curSelected = menuItems.length - 1;
|
||||
|
||||
menuItems.forEach(function(spr:FlxSprite)
|
||||
{
|
||||
spr.animation.play('idle');
|
||||
|
||||
if (spr.ID == curSelected)
|
||||
{
|
||||
camFollow.setPosition(spr.getGraphicMidpoint().x, spr.getGraphicMidpoint().y);
|
||||
spr.animation.play('selected');
|
||||
}
|
||||
|
||||
spr.updateHitbox();
|
||||
if(spr.animation.curAnim.name == 'selected')
|
||||
{
|
||||
switch(optionShit[curSelected])
|
||||
{
|
||||
case 'story mode':
|
||||
spr.offset.y += 26;
|
||||
case 'freeplay':
|
||||
spr.offset.y += 28;
|
||||
case 'donate':
|
||||
spr.offset.y += 21;
|
||||
case 'options':
|
||||
spr.offset.y += 26;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class MainMenuList extends MenuTypedList<MainMenuItem>
|
||||
{
|
||||
public var atlas:FlxAtlasFrames;
|
||||
|
||||
public function new ()
|
||||
{
|
||||
atlas = Paths.getSparrowAtlas('main_menu');
|
||||
super(Vertical);
|
||||
|
||||
}
|
||||
|
||||
public function createItem(x = 0.0, y = 0.0, name:String, callback, fireInstantly = false)
|
||||
{
|
||||
var item = new MainMenuItem(x, y, name, atlas, callback);
|
||||
item.fireInstantly = fireInstantly;
|
||||
item.ID = length;
|
||||
|
||||
return addItem(name, item);
|
||||
}
|
||||
|
||||
override function destroy()
|
||||
{
|
||||
super.destroy();
|
||||
atlas = null;
|
||||
}
|
||||
}
|
||||
private class MainMenuItem extends AtlasMenuItem
|
||||
{
|
||||
public function new(x = 0.0, y = 0.0, name, atlas, callback)
|
||||
{
|
||||
super(x, y, name, atlas, callback);
|
||||
scrollFactor.set();
|
||||
}
|
||||
|
||||
override function changeAnim(anim:String)
|
||||
{
|
||||
super.changeAnim(anim);
|
||||
// position by center
|
||||
centerOrigin();
|
||||
offset.copyFrom(origin);
|
||||
}
|
||||
}
|
229
source/NGio.hx
229
source/NGio.hx
|
@ -1,10 +1,13 @@
|
|||
package;
|
||||
#if newgrounds
|
||||
|
||||
import flixel.FlxG;
|
||||
import flixel.util.FlxSignal;
|
||||
import flixel.util.FlxTimer;
|
||||
import io.newgrounds.NG;
|
||||
import io.newgrounds.NGLite;
|
||||
import io.newgrounds.components.ScoreBoardComponent.Period;
|
||||
import io.newgrounds.objects.Error;
|
||||
import io.newgrounds.objects.Medal;
|
||||
import io.newgrounds.objects.Score;
|
||||
import io.newgrounds.objects.ScoreBoard;
|
||||
|
@ -15,14 +18,24 @@ import lime.app.Application;
|
|||
import openfl.display.Stage;
|
||||
|
||||
using StringTools;
|
||||
|
||||
#end
|
||||
/**
|
||||
* MADE BY GEOKURELI THE LEGENED GOD HERO MVP
|
||||
*/
|
||||
class NGio
|
||||
{
|
||||
public static var isLoggedIn:Bool = false;
|
||||
#if newgrounds
|
||||
/**
|
||||
* True, if the saved sessionId was used in the initial login, and failed to connect.
|
||||
* Used in MainMenuState to show a popup to establish a new connection
|
||||
*/
|
||||
public static var savedSessionFailed(default, null):Bool = false;
|
||||
public static var scoreboardsLoaded:Bool = false;
|
||||
public static var isLoggedIn(get, never):Bool;
|
||||
inline static function get_isLoggedIn()
|
||||
{
|
||||
return NG.core != null && NG.core.loggedIn;
|
||||
}
|
||||
|
||||
public static var scoreboardArray:Array<Score> = [];
|
||||
|
||||
|
@ -30,45 +43,67 @@ class NGio
|
|||
public static var ngScoresLoaded(default, null):FlxSignal = new FlxSignal();
|
||||
|
||||
public static var GAME_VER:String = "";
|
||||
public static var GAME_VER_NUMS:String = '';
|
||||
public static var gotOnlineVer:Bool = false;
|
||||
|
||||
public static function noLogin(api:String)
|
||||
|
||||
static public function checkVersion(callback:String->Void)
|
||||
{
|
||||
trace('INIT NOLOGIN');
|
||||
trace('checking NG.io version');
|
||||
GAME_VER = "v" + Application.current.meta.get('version');
|
||||
|
||||
if (api.length != 0)
|
||||
{
|
||||
NG.create(api);
|
||||
|
||||
new FlxTimer().start(2, function(tmr:FlxTimer)
|
||||
NG.core.calls.app.getCurrentVersion(GAME_VER)
|
||||
.addDataHandler(function(response)
|
||||
{
|
||||
var call = NG.core.calls.app.getCurrentVersion(GAME_VER).addDataHandler(function(response:Response<GetCurrentVersionResult>)
|
||||
{
|
||||
GAME_VER = response.result.data.currentVersion;
|
||||
GAME_VER_NUMS = GAME_VER.split(" ")[0].trim();
|
||||
trace('CURRENT NG VERSION: ' + GAME_VER);
|
||||
trace('CURRENT NG VERSION: ' + GAME_VER_NUMS);
|
||||
gotOnlineVer = true;
|
||||
});
|
||||
|
||||
call.send();
|
||||
});
|
||||
}
|
||||
GAME_VER = response.result.data.currentVersion;
|
||||
trace('CURRENT NG VERSION: ' + GAME_VER);
|
||||
callback(GAME_VER);
|
||||
})
|
||||
.send();
|
||||
}
|
||||
|
||||
public function new(api:String, encKey:String, ?sessionId:String)
|
||||
static public function init()
|
||||
{
|
||||
var api = APIStuff.API;
|
||||
if (api == null || api.length == 0)
|
||||
{
|
||||
trace("Missing Newgrounds API key, aborting connection");
|
||||
return;
|
||||
}
|
||||
trace("connecting to newgrounds");
|
||||
|
||||
NG.createAndCheckSession(api, sessionId);
|
||||
|
||||
NG.core.verbose = true;
|
||||
|
||||
#if NG_FORCE_EXPIRED_SESSION
|
||||
var sessionId:String = "fake_session_id";
|
||||
function onSessionFail(error:Error)
|
||||
{
|
||||
trace("Forcing an expired saved session. "
|
||||
+ "To disable, comment out NG_FORCE_EXPIRED_SESSION in Project.xml");
|
||||
savedSessionFailed = true;
|
||||
}
|
||||
#else
|
||||
var sessionId:String = NGLite.getSessionId();
|
||||
if (sessionId != null)
|
||||
trace("found web session id");
|
||||
|
||||
#if (debug)
|
||||
if (sessionId == null && APIStuff.SESSION != null)
|
||||
{
|
||||
trace("using debug session id");
|
||||
sessionId = APIStuff.SESSION;
|
||||
}
|
||||
#end
|
||||
|
||||
var onSessionFail:Error->Void = null;
|
||||
if (sessionId == null && FlxG.save.data.sessionId != null)
|
||||
{
|
||||
trace("using stored session id");
|
||||
sessionId = FlxG.save.data.sessionId;
|
||||
onSessionFail = function (error) savedSessionFailed = true;
|
||||
}
|
||||
#end
|
||||
|
||||
NG.create(api, sessionId, #if NG_DEBUG true #else false #end, onSessionFail);
|
||||
|
||||
#if NG_VERBOSE NG.core.verbose = true; #end
|
||||
// Set the encryption cipher/format to RC4/Base64. AES128 and Hex are not implemented yet
|
||||
NG.core.initEncryption(encKey); // Found in you NG project view
|
||||
|
||||
trace(NG.core.attemptingLogin);
|
||||
NG.core.initEncryption(APIStuff.EncKey); // Found in you NG project view
|
||||
|
||||
if (NG.core.attemptingLogin)
|
||||
{
|
||||
|
@ -78,21 +113,58 @@ class NGio
|
|||
trace("attempting login");
|
||||
NG.core.onLogin.add(onNGLogin);
|
||||
}
|
||||
else
|
||||
//GK: taking out auto login, adding a login button to the main menu
|
||||
// else
|
||||
// {
|
||||
// /* They are NOT playing on newgrounds.com, no session id was found. We must start one manually, if we want to.
|
||||
// * Note: This will cause a new browser window to pop up where they can log in to newgrounds
|
||||
// */
|
||||
// NG.core.requestLogin(onNGLogin);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to log in to newgrounds by requesting a new session ID, only call if no session ID was found automatically
|
||||
* @param popupLauncher The function to call to open the login url, must be inside
|
||||
* a user input event or the popup blocker will block it.
|
||||
* @param onComplete A callback with the result of the connection.
|
||||
*/
|
||||
static public function login(?popupLauncher:(Void->Void)->Void, onComplete:ConnectionResult->Void)
|
||||
{
|
||||
trace("Logging in manually");
|
||||
var onPending:Void->Void = null;
|
||||
if (popupLauncher != null)
|
||||
{
|
||||
/* They are NOT playing on newgrounds.com, no session id was found. We must start one manually, if we want to.
|
||||
* Note: This will cause a new browser window to pop up where they can log in to newgrounds
|
||||
*/
|
||||
NG.core.requestLogin(onNGLogin);
|
||||
onPending = function () popupLauncher(NG.core.openPassportUrl);
|
||||
}
|
||||
|
||||
var onSuccess:Void->Void = onNGLogin;
|
||||
var onFail:Error->Void = null;
|
||||
var onCancel:Void->Void = null;
|
||||
if (onComplete != null)
|
||||
{
|
||||
onSuccess = function ()
|
||||
{
|
||||
onNGLogin();
|
||||
onComplete(Success);
|
||||
}
|
||||
onFail = function (e) onComplete(Fail(e.message));
|
||||
onCancel = function() onComplete(Cancelled);
|
||||
}
|
||||
|
||||
NG.core.requestLogin(onSuccess, onPending, onFail, onCancel);
|
||||
}
|
||||
|
||||
inline static public function cancelLogin():Void
|
||||
{
|
||||
NG.core.cancelLoginRequest();
|
||||
}
|
||||
|
||||
function onNGLogin():Void
|
||||
static function onNGLogin():Void
|
||||
{
|
||||
trace('logged in! user:${NG.core.user.name}');
|
||||
isLoggedIn = true;
|
||||
FlxG.save.data.sessionId = NG.core.sessionId;
|
||||
// FlxG.save.flush();
|
||||
FlxG.save.flush();
|
||||
// Load medals then call onNGMedalFetch()
|
||||
NG.core.requestMedals(onNGMedalFetch);
|
||||
|
||||
|
@ -101,9 +173,17 @@ class NGio
|
|||
|
||||
ngDataLoaded.dispatch();
|
||||
}
|
||||
|
||||
static public function logout()
|
||||
{
|
||||
NG.core.logOut();
|
||||
|
||||
FlxG.save.data.sessionId = null;
|
||||
FlxG.save.flush();
|
||||
}
|
||||
|
||||
// --- MEDALS
|
||||
function onNGMedalFetch():Void
|
||||
static function onNGMedalFetch():Void
|
||||
{
|
||||
/*
|
||||
// Reading medal info
|
||||
|
@ -121,7 +201,7 @@ class NGio
|
|||
}
|
||||
|
||||
// --- SCOREBOARDS
|
||||
function onNGBoardsFetch():Void
|
||||
static function onNGBoardsFetch():Void
|
||||
{
|
||||
/*
|
||||
// Reading medal info
|
||||
|
@ -145,25 +225,7 @@ class NGio
|
|||
// more info on scores --- http://www.newgrounds.io/help/components/#scoreboard-getscores
|
||||
}
|
||||
|
||||
inline static public function postScore(score:Int = 0, song:String)
|
||||
{
|
||||
if (isLoggedIn)
|
||||
{
|
||||
for (id in NG.core.scoreBoards.keys())
|
||||
{
|
||||
var board = NG.core.scoreBoards.get(id);
|
||||
|
||||
if (song == board.name)
|
||||
{
|
||||
board.postScore(score, "Uhh meow?");
|
||||
}
|
||||
|
||||
// trace('loaded scoreboard id:$id, name:${board.name}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onNGScoresFetch():Void
|
||||
static function onNGScoresFetch():Void
|
||||
{
|
||||
scoreboardsLoaded = true;
|
||||
|
||||
|
@ -181,20 +243,61 @@ class NGio
|
|||
|
||||
// NGio.scoreboardArray = NG.core.scoreBoards.get(8004).scores;
|
||||
}
|
||||
#end
|
||||
|
||||
inline static public function logEvent(event:String)
|
||||
static public function logEvent(event:String)
|
||||
{
|
||||
#if newgrounds
|
||||
NG.core.calls.event.logEvent(event).send();
|
||||
trace('should have logged: ' + event);
|
||||
#else
|
||||
#if debug trace('event:$event - not logged, missing NG.io lib'); #end
|
||||
#end
|
||||
}
|
||||
|
||||
inline static public function unlockMedal(id:Int)
|
||||
static public function unlockMedal(id:Int)
|
||||
{
|
||||
#if newgrounds
|
||||
if (isLoggedIn)
|
||||
{
|
||||
var medal = NG.core.medals.get(id);
|
||||
if (!medal.unlocked)
|
||||
medal.sendUnlock();
|
||||
}
|
||||
#else
|
||||
#if debug trace('medal:$id - not unlocked, missing NG.io lib'); #end
|
||||
#end
|
||||
}
|
||||
|
||||
static public function postScore(score:Int = 0, song:String)
|
||||
{
|
||||
#if newgrounds
|
||||
if (isLoggedIn)
|
||||
{
|
||||
for (id in NG.core.scoreBoards.keys())
|
||||
{
|
||||
var board = NG.core.scoreBoards.get(id);
|
||||
|
||||
if (song == board.name)
|
||||
{
|
||||
board.postScore(score, "Uhh meow?");
|
||||
}
|
||||
|
||||
// trace('loaded scoreboard id:$id, name:${board.name}');
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if debug trace('Song:$song, Score:$score - not posted, missing NG.io lib'); #end
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
enum ConnectionResult
|
||||
{
|
||||
/** Log in successful */
|
||||
Success;
|
||||
/** Could not login */
|
||||
Fail(msg:String);
|
||||
/** User cancelled the login */
|
||||
Cancelled;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import flixel.text.FlxText;
|
|||
import flixel.util.FlxColor;
|
||||
import lime.utils.Assets;
|
||||
|
||||
class OptionsMenu extends MusicBeatState
|
||||
class OptionsMenu_old extends MusicBeatState
|
||||
{
|
||||
var selector:FlxText;
|
||||
var curSelected:Int = 0;
|
||||
|
@ -82,7 +82,7 @@ class OptionsMenu extends MusicBeatState
|
|||
{
|
||||
if (FlxG.keys.getIsDown().length > 0)
|
||||
{
|
||||
PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxG.keys.getIsDown()[0].ID, null);
|
||||
// PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxG.keys.getIsDown()[0].ID, null);
|
||||
}
|
||||
// PlayerSettings.player1.controls.replaceBinding(Control)
|
||||
}
|
||||
|
@ -99,9 +99,7 @@ class OptionsMenu extends MusicBeatState
|
|||
|
||||
function changeSelection(change:Int = 0)
|
||||
{
|
||||
#if !switch
|
||||
NGio.logEvent('Fresh');
|
||||
#end
|
||||
|
||||
FlxG.sound.play(Paths.sound('scrollMenu'), 0.4);
|
||||
|
|
@ -97,7 +97,7 @@ class PauseSubState extends MusicBeatSubstate
|
|||
|
||||
regenMenu();
|
||||
|
||||
cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
|
||||
// cameras = [FlxG.cameras.list[FlxG.cameras.list.length - 1]];
|
||||
}
|
||||
|
||||
private function regenMenu():Void
|
||||
|
@ -126,8 +126,8 @@ class PauseSubState extends MusicBeatSubstate
|
|||
|
||||
super.update(elapsed);
|
||||
|
||||
var upP = controls.UP_P;
|
||||
var downP = controls.DOWN_P;
|
||||
var upP = controls.UI_UP_P;
|
||||
var downP = controls.UI_DOWN_P;
|
||||
var accepted = controls.ACCEPT;
|
||||
|
||||
if (upP)
|
||||
|
|
|
@ -153,9 +153,7 @@ class PlayState extends MusicBeatState
|
|||
camHUD.bgColor.alpha = 0;
|
||||
|
||||
FlxG.cameras.reset(camGame);
|
||||
FlxG.cameras.add(camHUD);
|
||||
|
||||
FlxCamera.defaultCameras = [camGame];
|
||||
FlxG.cameras.add(camHUD, false);
|
||||
|
||||
persistentUpdate = true;
|
||||
persistentDraw = true;
|
||||
|
@ -1462,7 +1460,13 @@ class PlayState extends MusicBeatState
|
|||
FlxG.switchState(new GitarooPause());
|
||||
}
|
||||
else
|
||||
openSubState(new PauseSubState(boyfriend.getScreenPosition().x, boyfriend.getScreenPosition().y));
|
||||
{
|
||||
var boyfriendPos = boyfriend.getScreenPosition();
|
||||
var pauseSubState = new PauseSubState(boyfriendPos.x, boyfriendPos.y);
|
||||
openSubState(pauseSubState);
|
||||
pauseSubState.camera = camHUD;
|
||||
boyfriendPos.put();
|
||||
}
|
||||
|
||||
#if desktop
|
||||
DiscordClient.changePresence(detailsPausedText, SONG.song + " (" + storyDifficultyText + ")", iconRPC);
|
||||
|
@ -1618,12 +1622,13 @@ class PlayState extends MusicBeatState
|
|||
trace("RESET = True");
|
||||
}
|
||||
|
||||
// CHEAT = brandon's a pussy
|
||||
#if CAN_CHEAT // brandon's a pussy
|
||||
if (controls.CHEAT)
|
||||
{
|
||||
health += 1;
|
||||
trace("User is cheating!");
|
||||
}
|
||||
#end
|
||||
|
||||
if (health <= 0 && !practiceMode)
|
||||
{
|
||||
|
@ -1762,9 +1767,7 @@ class PlayState extends MusicBeatState
|
|||
vocals.volume = 0;
|
||||
if (SONG.validScore)
|
||||
{
|
||||
#if !switch
|
||||
Highscore.saveScore(SONG.song, songScore, storyDifficulty);
|
||||
#end
|
||||
}
|
||||
|
||||
if (isStoryMode)
|
||||
|
@ -1994,20 +1997,20 @@ class PlayState extends MusicBeatState
|
|||
private function keyShit():Void
|
||||
{
|
||||
// HOLDING
|
||||
var up = controls.UP;
|
||||
var right = controls.RIGHT;
|
||||
var down = controls.DOWN;
|
||||
var left = controls.LEFT;
|
||||
var up = controls.NOTE_UP;
|
||||
var right = controls.NOTE_RIGHT;
|
||||
var down = controls.NOTE_DOWN;
|
||||
var left = controls.NOTE_LEFT;
|
||||
|
||||
var upP = controls.UP_P;
|
||||
var rightP = controls.RIGHT_P;
|
||||
var downP = controls.DOWN_P;
|
||||
var leftP = controls.LEFT_P;
|
||||
var upP = controls.NOTE_UP_P;
|
||||
var rightP = controls.NOTE_RIGHT_P;
|
||||
var downP = controls.NOTE_DOWN_P;
|
||||
var leftP = controls.NOTE_LEFT_P;
|
||||
|
||||
var upR = controls.UP_R;
|
||||
var rightR = controls.RIGHT_R;
|
||||
var downR = controls.DOWN_R;
|
||||
var leftR = controls.LEFT_R;
|
||||
var upR = controls.NOTE_UP_R;
|
||||
var rightR = controls.NOTE_RIGHT_R;
|
||||
var downR = controls.NOTE_DOWN_R;
|
||||
var leftR = controls.NOTE_LEFT_R;
|
||||
|
||||
var controlArray:Array<Bool> = [leftP, downP, upP, rightP];
|
||||
|
||||
|
@ -2231,10 +2234,10 @@ class PlayState extends MusicBeatState
|
|||
{
|
||||
// just double pasting this shit cuz fuk u
|
||||
// REDO THIS SYSTEM!
|
||||
var upP = controls.UP_P;
|
||||
var rightP = controls.RIGHT_P;
|
||||
var downP = controls.DOWN_P;
|
||||
var leftP = controls.LEFT_P;
|
||||
var upP = controls.NOTE_UP_P;
|
||||
var rightP = controls.NOTE_RIGHT_P;
|
||||
var downP = controls.NOTE_DOWN_P;
|
||||
var leftP = controls.NOTE_LEFT_P;
|
||||
|
||||
if (leftP)
|
||||
noteMiss(0);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package;
|
||||
|
||||
import Controls;
|
||||
|
||||
import flixel.FlxCamera;
|
||||
import flixel.FlxG;
|
||||
import flixel.input.actions.FlxActionInput;
|
||||
import flixel.input.gamepad.FlxGamepad;
|
||||
import flixel.util.FlxSignal;
|
||||
|
||||
// import ui.DeviceManager;
|
||||
|
@ -14,143 +17,233 @@ class PlayerSettings
|
|||
static public var player1(default, null):PlayerSettings;
|
||||
static public var player2(default, null):PlayerSettings;
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
static public final onAvatarAdd = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
static public final onAvatarRemove = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
#else
|
||||
static public var onAvatarAdd = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
static public var onAvatarRemove = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
#end
|
||||
static public var onAvatarAdd(default, null) = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
static public var onAvatarRemove(default, null) = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
|
||||
public var id(default, null):Int;
|
||||
|
||||
#if (haxe >= "4.0.0")
|
||||
public final controls:Controls;
|
||||
#else
|
||||
public var controls:Controls;
|
||||
#end
|
||||
public var controls(default, null):Controls;
|
||||
|
||||
// public var avatar:Player;
|
||||
// public var camera(get, never):PlayCamera;
|
||||
|
||||
function new(id, scheme)
|
||||
function new(id)
|
||||
{
|
||||
this.id = id;
|
||||
this.controls = new Controls('player$id', scheme);
|
||||
this.controls = new Controls('player$id', None);
|
||||
|
||||
#if CLEAR_INPUT_SAVE
|
||||
FlxG.save.data.controls = null;
|
||||
FlxG.save.flush();
|
||||
#end
|
||||
|
||||
var useDefault = true;
|
||||
var controlData = FlxG.save.data.controls;
|
||||
if (controlData != null)
|
||||
{
|
||||
var keyData:Dynamic = null;
|
||||
if (id == 0 && controlData.p1 != null && controlData.p1.keys != null)
|
||||
keyData = controlData.p1.keys;
|
||||
else if (id == 1 && controlData.p2 != null && controlData.p2.keys != null)
|
||||
keyData = controlData.p2.keys;
|
||||
|
||||
if (keyData != null)
|
||||
{
|
||||
useDefault = false;
|
||||
trace("loaded key data: " + haxe.Json.stringify(keyData));
|
||||
controls.fromSaveData(keyData, Keys);
|
||||
}
|
||||
}
|
||||
|
||||
if (useDefault)
|
||||
controls.setKeyboardScheme(Solo);
|
||||
}
|
||||
|
||||
function addGamepad(gamepad:FlxGamepad)
|
||||
{
|
||||
var useDefault = true;
|
||||
var controlData = FlxG.save.data.controls;
|
||||
if (controlData != null)
|
||||
{
|
||||
var padData:Dynamic = null;
|
||||
if (id == 0 && controlData.p1 != null && controlData.p1.pad != null)
|
||||
padData = controlData.p1.pad;
|
||||
else if (id == 1 && controlData.p2 != null && controlData.p2.pad != null)
|
||||
padData = controlData.p2.pad;
|
||||
|
||||
if (padData != null)
|
||||
{
|
||||
useDefault = false;
|
||||
trace("loaded pad data: " + haxe.Json.stringify(padData));
|
||||
controls.addGamepadWithSaveData(gamepad.id, padData);
|
||||
}
|
||||
}
|
||||
|
||||
if (useDefault)
|
||||
controls.addDefaultGamepad(gamepad.id);
|
||||
}
|
||||
|
||||
public function saveControls()
|
||||
{
|
||||
if (FlxG.save.data.controls == null)
|
||||
FlxG.save.data.controls = {};
|
||||
|
||||
var playerData:{ ?keys:Dynamic, ?pad:Dynamic }
|
||||
if (id == 0)
|
||||
{
|
||||
if (FlxG.save.data.controls.p1 == null)
|
||||
FlxG.save.data.controls.p1 = {};
|
||||
playerData = FlxG.save.data.controls.p1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FlxG.save.data.controls.p2 == null)
|
||||
FlxG.save.data.controls.p2 = {};
|
||||
playerData = FlxG.save.data.controls.p2;
|
||||
}
|
||||
|
||||
var keyData = controls.createSaveData(Keys);
|
||||
if (keyData != null)
|
||||
{
|
||||
playerData.keys = keyData;
|
||||
trace("saving key data: " + haxe.Json.stringify(keyData));
|
||||
}
|
||||
|
||||
if (controls.gamepadsAdded.length > 0)
|
||||
{
|
||||
var padData = controls.createSaveData(Gamepad(controls.gamepadsAdded[0]));
|
||||
if (padData != null)
|
||||
{
|
||||
trace("saving pad data: " + haxe.Json.stringify(padData));
|
||||
playerData.pad = padData;
|
||||
}
|
||||
}
|
||||
|
||||
FlxG.save.flush();
|
||||
}
|
||||
|
||||
static public function init():Void
|
||||
{
|
||||
if (player1 == null)
|
||||
{
|
||||
player1 = new PlayerSettings(0);
|
||||
++numPlayers;
|
||||
}
|
||||
|
||||
FlxG.gamepads.deviceConnected.add(onGamepadAdded);
|
||||
|
||||
var numGamepads = FlxG.gamepads.numActiveGamepads;
|
||||
for (i in 0...numGamepads)
|
||||
{
|
||||
var gamepad = FlxG.gamepads.getByID(i);
|
||||
if (gamepad != null)
|
||||
onGamepadAdded(gamepad);
|
||||
}
|
||||
|
||||
// player1.controls.addDefaultGamepad(0);
|
||||
// }
|
||||
|
||||
// if (numGamepads > 1)
|
||||
// {
|
||||
// if (player2 == null)
|
||||
// {
|
||||
// player2 = new PlayerSettings(1, None);
|
||||
// ++numPlayers;
|
||||
// }
|
||||
|
||||
// var gamepad = FlxG.gamepads.getByID(1);
|
||||
// if (gamepad == null)
|
||||
// throw 'Unexpected null gamepad. id:0';
|
||||
|
||||
// player2.controls.addDefaultGamepad(1);
|
||||
// }
|
||||
|
||||
// DeviceManager.init();
|
||||
}
|
||||
|
||||
static function onGamepadAdded(gamepad:FlxGamepad)
|
||||
{
|
||||
player1.addGamepad(gamepad);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public function setKeyboardScheme(scheme)
|
||||
{
|
||||
controls.setKeyboardScheme(scheme);
|
||||
}
|
||||
|
||||
/*
|
||||
static public function addAvatar(avatar:Player):PlayerSettings
|
||||
{
|
||||
var settings:PlayerSettings;
|
||||
|
||||
if (player1 == null)
|
||||
{
|
||||
player1 = new PlayerSettings(0, Solo);
|
||||
++numPlayers;
|
||||
}
|
||||
|
||||
if (player1.avatar == null)
|
||||
settings = player1;
|
||||
else
|
||||
{
|
||||
if (player2 == null)
|
||||
{
|
||||
if (player1.controls.keyboardScheme.match(Duo(true)))
|
||||
player2 = new PlayerSettings(1, Duo(false));
|
||||
else
|
||||
player2 = new PlayerSettings(1, None);
|
||||
++numPlayers;
|
||||
}
|
||||
|
||||
if (player2.avatar == null)
|
||||
settings = player2;
|
||||
else
|
||||
throw throw 'Invalid number of players: ${numPlayers + 1}';
|
||||
}
|
||||
++numAvatars;
|
||||
settings.avatar = avatar;
|
||||
avatar.settings = settings;
|
||||
|
||||
splitCameras();
|
||||
|
||||
onAvatarAdd.dispatch(settings);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
static public function removeAvatar(avatar:Player):Void
|
||||
{
|
||||
var settings:PlayerSettings;
|
||||
|
||||
if (player1 != null && player1.avatar == avatar)
|
||||
settings = player1;
|
||||
else if (player2 != null && player2.avatar == avatar)
|
||||
{
|
||||
settings = player2;
|
||||
if (player1.controls.keyboardScheme.match(Duo(_)))
|
||||
player1.setKeyboardScheme(Solo);
|
||||
}
|
||||
else
|
||||
throw "Cannot remove avatar that is not for a player";
|
||||
|
||||
settings.avatar = null;
|
||||
while (settings.controls.gamepadsAdded.length > 0)
|
||||
{
|
||||
final id = settings.controls.gamepadsAdded.shift();
|
||||
settings.controls.removeGamepad(id);
|
||||
DeviceManager.releaseGamepad(FlxG.gamepads.getByID(id));
|
||||
}
|
||||
|
||||
--numAvatars;
|
||||
|
||||
splitCameras();
|
||||
|
||||
onAvatarRemove.dispatch(avatar.settings);
|
||||
}
|
||||
|
||||
*/
|
||||
static public function init():Void
|
||||
static public function addAvatar(avatar:Player):PlayerSettings
|
||||
{
|
||||
var settings:PlayerSettings;
|
||||
|
||||
if (player1 == null)
|
||||
{
|
||||
player1 = new PlayerSettings(0, Solo);
|
||||
++numPlayers;
|
||||
}
|
||||
|
||||
var numGamepads = FlxG.gamepads.numActiveGamepads;
|
||||
if (numGamepads > 0)
|
||||
{
|
||||
var gamepad = FlxG.gamepads.getByID(0);
|
||||
if (gamepad == null)
|
||||
throw 'Unexpected null gamepad. id:0';
|
||||
|
||||
player1.controls.addDefaultGamepad(0);
|
||||
}
|
||||
|
||||
if (numGamepads > 1)
|
||||
if (player1.avatar == null)
|
||||
settings = player1;
|
||||
else
|
||||
{
|
||||
if (player2 == null)
|
||||
{
|
||||
player2 = new PlayerSettings(1, None);
|
||||
if (player1.controls.keyboardScheme.match(Duo(true)))
|
||||
player2 = new PlayerSettings(1, Duo(false));
|
||||
else
|
||||
player2 = new PlayerSettings(1, None);
|
||||
++numPlayers;
|
||||
}
|
||||
|
||||
var gamepad = FlxG.gamepads.getByID(1);
|
||||
if (gamepad == null)
|
||||
throw 'Unexpected null gamepad. id:0';
|
||||
if (player2.avatar == null)
|
||||
settings = player2;
|
||||
else
|
||||
throw throw 'Invalid number of players: ${numPlayers + 1}';
|
||||
}
|
||||
++numAvatars;
|
||||
settings.avatar = avatar;
|
||||
avatar.settings = settings;
|
||||
|
||||
player2.controls.addDefaultGamepad(1);
|
||||
splitCameras();
|
||||
|
||||
onAvatarAdd.dispatch(settings);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
static public function removeAvatar(avatar:Player):Void
|
||||
{
|
||||
var settings:PlayerSettings;
|
||||
|
||||
if (player1 != null && player1.avatar == avatar)
|
||||
settings = player1;
|
||||
else if (player2 != null && player2.avatar == avatar)
|
||||
{
|
||||
settings = player2;
|
||||
if (player1.controls.keyboardScheme.match(Duo(_)))
|
||||
player1.setKeyboardScheme(Solo);
|
||||
}
|
||||
else
|
||||
throw "Cannot remove avatar that is not for a player";
|
||||
|
||||
settings.avatar = null;
|
||||
while (settings.controls.gamepadsAdded.length > 0)
|
||||
{
|
||||
final id = settings.controls.gamepadsAdded.shift();
|
||||
settings.controls.removeGamepad(id);
|
||||
DeviceManager.releaseGamepad(FlxG.gamepads.getByID(id));
|
||||
}
|
||||
|
||||
// DeviceManager.init();
|
||||
--numAvatars;
|
||||
|
||||
splitCameras();
|
||||
|
||||
onAvatarRemove.dispatch(avatar.settings);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
static public function reset()
|
||||
{
|
||||
player1 = null;
|
||||
|
|
|
@ -245,29 +245,29 @@ class StoryMenuState extends MusicBeatState
|
|||
{
|
||||
if (!selectedWeek)
|
||||
{
|
||||
if (controls.UP_P)
|
||||
if (controls.UI_UP_P)
|
||||
{
|
||||
changeWeek(-1);
|
||||
}
|
||||
|
||||
if (controls.DOWN_P)
|
||||
if (controls.UI_DOWN_P)
|
||||
{
|
||||
changeWeek(1);
|
||||
}
|
||||
|
||||
if (controls.RIGHT)
|
||||
if (controls.UI_RIGHT)
|
||||
rightArrow.animation.play('press')
|
||||
else
|
||||
rightArrow.animation.play('idle');
|
||||
|
||||
if (controls.LEFT)
|
||||
if (controls.UI_LEFT)
|
||||
leftArrow.animation.play('press');
|
||||
else
|
||||
leftArrow.animation.play('idle');
|
||||
|
||||
if (controls.RIGHT_P)
|
||||
if (controls.UI_RIGHT_P)
|
||||
changeDifficulty(1);
|
||||
if (controls.LEFT_P)
|
||||
if (controls.UI_LEFT_P)
|
||||
changeDifficulty(-1);
|
||||
}
|
||||
|
||||
|
@ -360,10 +360,6 @@ class StoryMenuState extends MusicBeatState
|
|||
sprDifficulty.y = leftArrow.y - 15;
|
||||
intendedScore = Highscore.getWeekScore(curWeek, curDifficulty);
|
||||
|
||||
#if !switch
|
||||
intendedScore = Highscore.getWeekScore(curWeek, curDifficulty);
|
||||
#end
|
||||
|
||||
FlxTween.tween(sprDifficulty, {y: leftArrow.y + 15, alpha: 1}, 0.07);
|
||||
}
|
||||
|
||||
|
@ -439,8 +435,6 @@ class StoryMenuState extends MusicBeatState
|
|||
txtTracklist.screenCenter(X);
|
||||
txtTracklist.x -= FlxG.width * 0.35;
|
||||
|
||||
#if !switch
|
||||
intendedScore = Highscore.getWeekScore(curWeek, curDifficulty);
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import flixel.tweens.FlxEase;
|
|||
import flixel.tweens.FlxTween;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.FlxTimer;
|
||||
import io.newgrounds.NG;
|
||||
import lime.app.Application;
|
||||
import openfl.Assets;
|
||||
import shaderslmfao.ColorSwap;
|
||||
|
@ -54,25 +53,20 @@ class TitleState extends MusicBeatState
|
|||
|
||||
FlxG.sound.muteKeys = [ZERO];
|
||||
|
||||
PlayerSettings.init();
|
||||
|
||||
curWacky = FlxG.random.getObject(getIntroTextShit());
|
||||
|
||||
// DEBUG BULLSHIT
|
||||
|
||||
super.create();
|
||||
|
||||
NGio.noLogin(APIStuff.API);
|
||||
|
||||
#if ng
|
||||
var ng:NGio = new NGio(APIStuff.API, APIStuff.EncKey);
|
||||
trace('NEWGROUNDS LOL');
|
||||
#end
|
||||
|
||||
FlxG.save.bind('funkin', 'ninjamuffin99');
|
||||
|
||||
PlayerSettings.init();
|
||||
Highscore.load();
|
||||
|
||||
|
||||
#if newgrounds
|
||||
NGio.init();
|
||||
#end
|
||||
|
||||
if (FlxG.save.data.weekUnlocked != null)
|
||||
{
|
||||
// FIX LATER!!!
|
||||
|
@ -289,13 +283,11 @@ class TitleState extends MusicBeatState
|
|||
|
||||
if (pressedEnter && !transitioning && skippedIntro)
|
||||
{
|
||||
#if !switch
|
||||
NGio.unlockMedal(60960);
|
||||
|
||||
// If it's Friday according to da clock
|
||||
if (Date.now().getDay() == 5)
|
||||
NGio.unlockMedal(61034);
|
||||
#end
|
||||
|
||||
titleText.animation.play('press');
|
||||
|
||||
|
@ -305,26 +297,30 @@ class TitleState extends MusicBeatState
|
|||
transitioning = true;
|
||||
// FlxG.sound.music.stop();
|
||||
|
||||
new FlxTimer().start(2, function(tmr:FlxTimer)
|
||||
#if newgrounds
|
||||
if (!OutdatedSubState.leftState)
|
||||
{
|
||||
// Check if version is outdated
|
||||
|
||||
var version:String = "v" + Application.current.meta.get('version');
|
||||
|
||||
if (version.trim() != NGio.GAME_VER_NUMS.trim() && !OutdatedSubState.leftState)
|
||||
NGio.checkVersion(function(version)
|
||||
{
|
||||
FlxG.switchState(new OutdatedSubState());
|
||||
trace('OLD VERSION!');
|
||||
trace('old ver');
|
||||
trace(version.trim());
|
||||
trace('cur ver');
|
||||
trace(NGio.GAME_VER_NUMS.trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
FlxG.switchState(new MainMenuState());
|
||||
}
|
||||
});
|
||||
// Check if version is outdated
|
||||
|
||||
var localVersion:String = "v" + Application.current.meta.get('version');
|
||||
var onlineVersion = version.split(" ")[0].trim();
|
||||
|
||||
if (version.trim() != onlineVersion)
|
||||
{
|
||||
trace('OLD VERSION!');
|
||||
FlxG.switchState(new OutdatedSubState());
|
||||
}
|
||||
else
|
||||
{
|
||||
FlxG.switchState(new MainMenuState());
|
||||
}
|
||||
});
|
||||
}
|
||||
#else
|
||||
FlxG.switchState(new MainMenuState());
|
||||
#end
|
||||
// FlxG.sound.play(Paths.music('titleShoot'), 0.7);
|
||||
}
|
||||
|
||||
|
@ -333,12 +329,12 @@ class TitleState extends MusicBeatState
|
|||
skipIntro();
|
||||
}
|
||||
|
||||
if (controls.LEFT)
|
||||
if (controls.UI_LEFT)
|
||||
{
|
||||
swagShader.update(-elapsed * 0.1);
|
||||
}
|
||||
|
||||
if (controls.RIGHT)
|
||||
if (controls.UI_RIGHT)
|
||||
{
|
||||
swagShader.update(elapsed * 0.1);
|
||||
}
|
||||
|
|
81
source/ui/AtlasMenuList.hx
Normal file
81
source/ui/AtlasMenuList.hx
Normal file
|
@ -0,0 +1,81 @@
|
|||
package ui;
|
||||
|
||||
import ui.MenuList;
|
||||
|
||||
import flixel.graphics.frames.FlxAtlasFrames;
|
||||
|
||||
typedef AtlasAsset = flixel.util.typeLimit.OneOfTwo<String, FlxAtlasFrames>;
|
||||
|
||||
class AtlasMenuList extends MenuTypedList<AtlasMenuItem>
|
||||
{
|
||||
public var atlas:FlxAtlasFrames;
|
||||
|
||||
public function new (atlas, navControls:NavControls = Vertical, ?wrapMode)
|
||||
{
|
||||
super(navControls, wrapMode);
|
||||
|
||||
if (Std.is(atlas, String))
|
||||
this.atlas = Paths.getSparrowAtlas(cast atlas);
|
||||
else
|
||||
this.atlas = cast atlas;
|
||||
}
|
||||
|
||||
public function createItem(x = 0.0, y = 0.0, name, callback, fireInstantly = false)
|
||||
{
|
||||
var item = new AtlasMenuItem(x, y, name, atlas, callback);
|
||||
item.fireInstantly = fireInstantly;
|
||||
return addItem(name, item);
|
||||
}
|
||||
|
||||
override function destroy()
|
||||
{
|
||||
super.destroy();
|
||||
atlas = null;
|
||||
}
|
||||
}
|
||||
|
||||
class AtlasMenuItem extends MenuItem
|
||||
{
|
||||
var atlas:FlxAtlasFrames;
|
||||
public function new (x = 0.0, y = 0.0, name:String, atlas:FlxAtlasFrames, callback)
|
||||
{
|
||||
this.atlas = atlas;
|
||||
super(x, y, name, callback);
|
||||
}
|
||||
|
||||
override function setData(name:String, ?callback:Void->Void)
|
||||
{
|
||||
frames = atlas;
|
||||
animation.addByPrefix('idle', '$name idle', 24);
|
||||
animation.addByPrefix('selected', '$name selected', 24);
|
||||
|
||||
super.setData(name, callback);
|
||||
}
|
||||
|
||||
function changeAnim(animName:String)
|
||||
{
|
||||
animation.play(animName);
|
||||
updateHitbox();
|
||||
}
|
||||
|
||||
override function idle()
|
||||
{
|
||||
changeAnim('idle');
|
||||
}
|
||||
|
||||
override function select()
|
||||
{
|
||||
changeAnim('selected');
|
||||
}
|
||||
|
||||
override function get_selected()
|
||||
{
|
||||
return animation.curAnim != null && animation.curAnim.name == "selected";
|
||||
}
|
||||
|
||||
override function destroy()
|
||||
{
|
||||
super.destroy();
|
||||
atlas = null;
|
||||
}
|
||||
}
|
262
source/ui/AtlasText.hx
Normal file
262
source/ui/AtlasText.hx
Normal file
|
@ -0,0 +1,262 @@
|
|||
package ui;
|
||||
|
||||
import flixel.FlxSprite;
|
||||
import flixel.group.FlxSpriteGroup;
|
||||
import flixel.graphics.frames.FlxAtlasFrames;
|
||||
import flixel.util.FlxStringUtil;
|
||||
|
||||
@:forward
|
||||
abstract BoldText(AtlasText) from AtlasText to AtlasText
|
||||
{
|
||||
inline public function new (x = 0.0, y = 0.0, text:String)
|
||||
{
|
||||
this = new AtlasText(x, y, text, Bold);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alphabet.hx has a ton of bugs and does a bunch of stuff I don't need, fuck that class
|
||||
*/
|
||||
class AtlasText extends FlxTypedSpriteGroup<AtlasChar>
|
||||
{
|
||||
static var fonts = new Map<AtlasFont, AtlasFontData>();
|
||||
static var casesAllowed = new Map<AtlasFont, Case>();
|
||||
public var text(default, set):String = "";
|
||||
|
||||
var font:AtlasFontData;
|
||||
|
||||
public var atlas(get, never):FlxAtlasFrames;
|
||||
inline function get_atlas() return font.atlas;
|
||||
public var caseAllowed(get, never):Case;
|
||||
inline function get_caseAllowed() return font.caseAllowed;
|
||||
public var maxHeight(get, never):Float;
|
||||
inline function get_maxHeight() return font.maxHeight;
|
||||
|
||||
public function new (x = 0.0, y = 0.0, text:String, fontName:AtlasFont = Default)
|
||||
{
|
||||
if (!fonts.exists(fontName))
|
||||
fonts[fontName] = new AtlasFontData(fontName);
|
||||
font = fonts[fontName];
|
||||
|
||||
super(x, y);
|
||||
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
function set_text(value:String)
|
||||
{
|
||||
if (value == null)
|
||||
value = "";
|
||||
|
||||
var caseValue = restrictCase(value);
|
||||
var caseText = restrictCase(this.text);
|
||||
|
||||
this.text = value;
|
||||
if (caseText == caseValue)
|
||||
return value; // cancel redraw
|
||||
|
||||
if (caseValue.indexOf(caseText) == 0)
|
||||
{
|
||||
// new text is just old text with additions at the end, append the difference
|
||||
appendTextCased(caseValue.substr(caseText.length));
|
||||
return this.text;
|
||||
}
|
||||
|
||||
value = caseValue;
|
||||
|
||||
group.kill();
|
||||
|
||||
if (value == "")
|
||||
return this.text;
|
||||
|
||||
appendTextCased(caseValue);
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new characters, without needing to redraw the previous characters
|
||||
* @param text The text to add.
|
||||
* @throws String if `text` is null.
|
||||
*/
|
||||
public function appendText(text:String)
|
||||
{
|
||||
if (text == null)
|
||||
throw "cannot append null";
|
||||
|
||||
if (text == "")
|
||||
return;
|
||||
|
||||
this.text = this.text + text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all characters to fit the font's `allowedCase`.
|
||||
* @param text
|
||||
*/
|
||||
function restrictCase(text:String)
|
||||
{
|
||||
return switch(caseAllowed)
|
||||
{
|
||||
case Both: text;
|
||||
case Upper: text.toUpperCase();
|
||||
case Lower: text.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new text on top of the existing text. Helper for other methods; DOESN'T CHANGE `this.text`.
|
||||
* @param text The text to add, assumed to match the font's `caseAllowed`.
|
||||
*/
|
||||
function appendTextCased(text:String)
|
||||
{
|
||||
var charCount = group.countLiving();
|
||||
var xPos:Float = 0;
|
||||
var yPos:Float = 0;
|
||||
// `countLiving` returns -1 if group is empty
|
||||
if (charCount == -1)
|
||||
charCount = 0;
|
||||
else if (charCount > 0)
|
||||
{
|
||||
var lastChar = group.members[charCount - 1];
|
||||
xPos = lastChar.x + lastChar.width - x;
|
||||
yPos = lastChar.y + lastChar.height - maxHeight - y;
|
||||
}
|
||||
|
||||
var splitValues = text.split("");
|
||||
for (i in 0...splitValues.length)
|
||||
{
|
||||
switch(splitValues[i])
|
||||
{
|
||||
case " ":
|
||||
{
|
||||
xPos += 40;
|
||||
}
|
||||
case "\n":
|
||||
{
|
||||
xPos = 0;
|
||||
yPos += maxHeight;
|
||||
}
|
||||
case char:
|
||||
{
|
||||
var charSprite:AtlasChar;
|
||||
if (group.members.length <= charCount)
|
||||
charSprite = new AtlasChar(atlas, char);
|
||||
else
|
||||
{
|
||||
charSprite = group.members[charCount];
|
||||
charSprite.revive();
|
||||
charSprite.char = char;
|
||||
charSprite.alpha = 1;//gets multiplied when added
|
||||
}
|
||||
charSprite.x = xPos;
|
||||
charSprite.y = yPos + maxHeight - charSprite.height;
|
||||
add(charSprite);
|
||||
|
||||
xPos += charSprite.width;
|
||||
charCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override function toString()
|
||||
{
|
||||
return "InputItem, " + FlxStringUtil.getDebugString(
|
||||
[ LabelValuePair.weak("x", x)
|
||||
, LabelValuePair.weak("y", y)
|
||||
, LabelValuePair.weak("text", text)
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AtlasChar extends FlxSprite
|
||||
{
|
||||
public var char(default, set):String;
|
||||
public function new(x = 0.0, y = 0.0, atlas:FlxAtlasFrames, char:String)
|
||||
{
|
||||
super(x, y);
|
||||
frames = atlas;
|
||||
this.char = char;
|
||||
antialiasing = true;
|
||||
}
|
||||
|
||||
function set_char(value:String)
|
||||
{
|
||||
if (this.char != value)
|
||||
{
|
||||
var prefix = getAnimPrefix(value);
|
||||
animation.addByPrefix("anim", prefix, 24);
|
||||
animation.play("anim");
|
||||
updateHitbox();
|
||||
}
|
||||
|
||||
return this.char = value;
|
||||
}
|
||||
|
||||
function getAnimPrefix(char:String)
|
||||
{
|
||||
return switch (char)
|
||||
{
|
||||
case '-': '-dash-';
|
||||
case '.': '-period-';
|
||||
case ",": '-comma-';
|
||||
case "'": '-apostraphie-';
|
||||
case "?": '-question mark-';
|
||||
case "!": '-exclamation point-';
|
||||
case "\\": '-back slash-';
|
||||
case "/": '-forward slash-';
|
||||
case "*": '-multiply x-';
|
||||
case "“": '-start quote-';
|
||||
case "”": '-end quote-';
|
||||
default: char;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class AtlasFontData
|
||||
{
|
||||
static public var upperChar = ~/^[A-Z]\d+$/;
|
||||
static public var lowerChar = ~/^[a-z]\d+$/;
|
||||
|
||||
public var atlas:FlxAtlasFrames;
|
||||
public var maxHeight:Float = 0.0;
|
||||
public var caseAllowed:Case = Both;
|
||||
|
||||
public function new (name:AtlasFont)
|
||||
{
|
||||
atlas = Paths.getSparrowAtlas("fonts/" + name.getName().toLowerCase());
|
||||
atlas.parent.destroyOnNoUse = false;
|
||||
atlas.parent.persist = true;
|
||||
|
||||
var containsUpper = false;
|
||||
var containsLower = false;
|
||||
|
||||
for (frame in atlas.frames)
|
||||
{
|
||||
maxHeight = Math.max(maxHeight, frame.frame.height);
|
||||
|
||||
if (!containsUpper)
|
||||
containsUpper = upperChar.match(frame.name);
|
||||
|
||||
if (!containsLower)
|
||||
containsLower = lowerChar.match(frame.name);
|
||||
}
|
||||
|
||||
if (containsUpper != containsLower)
|
||||
caseAllowed = containsUpper ? Upper : Lower;
|
||||
}
|
||||
}
|
||||
|
||||
enum Case
|
||||
{
|
||||
Both;
|
||||
Upper;
|
||||
Lower;
|
||||
}
|
||||
|
||||
enum AtlasFont
|
||||
{
|
||||
Default;
|
||||
Bold;
|
||||
}
|
356
source/ui/ControlsMenu.hx
Normal file
356
source/ui/ControlsMenu.hx
Normal file
|
@ -0,0 +1,356 @@
|
|||
package ui;
|
||||
|
||||
import flixel.input.actions.FlxActionInput;
|
||||
import flixel.input.gamepad.FlxGamepadInputID;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxCamera;
|
||||
import flixel.FlxObject;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
|
||||
import Controls;
|
||||
import ui.AtlasText;
|
||||
import ui.MenuList;
|
||||
import ui.TextMenuList;
|
||||
|
||||
class ControlsMenu extends ui.OptionsState.Page
|
||||
{
|
||||
inline static public var COLUMNS = 2;
|
||||
static var controlList = Control.createAll();
|
||||
/*
|
||||
* Defines groups of controls that cannot share inputs, like left and right. Say, if ACCEPT is Z, Back is X,
|
||||
* if the player sets Back to Z it also set ACCEPT to X. This prevents the player from setting the controls in
|
||||
* a way the prevents them from changing more controls or exiting the menu.
|
||||
*/
|
||||
static var controlGroups:Array<Array<Control>> =
|
||||
[ [ NOTE_UP, NOTE_DOWN, NOTE_LEFT, NOTE_RIGHT ]
|
||||
, [ UI_UP, UI_DOWN, UI_LEFT, UI_RIGHT, ACCEPT, BACK ]
|
||||
];
|
||||
|
||||
var itemGroups:Array<Array<InputItem>> = [for (i in 0...controlGroups.length) []];
|
||||
|
||||
var controlGrid:MenuTypedList<InputItem>;
|
||||
var deviceList:TextMenuList;
|
||||
var menuCamera:FlxCamera;
|
||||
var prompt:Prompt;
|
||||
var camFollow:FlxObject;
|
||||
var labels:FlxTypedGroup<AtlasText>;
|
||||
|
||||
var currentDevice:Device = Keys;
|
||||
var deviceListSelected = false;
|
||||
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
|
||||
menuCamera = new FlxCamera();
|
||||
FlxG.cameras.add(menuCamera, false);
|
||||
menuCamera.bgColor = 0x0;
|
||||
camera = menuCamera;
|
||||
|
||||
labels = new FlxTypedGroup<AtlasText>();
|
||||
var headers = new FlxTypedGroup<AtlasText>();
|
||||
controlGrid = new MenuTypedList(Columns(COLUMNS), Vertical);
|
||||
|
||||
add(labels);
|
||||
add(headers);
|
||||
add(controlGrid);
|
||||
|
||||
if (FlxG.gamepads.numActiveGamepads > 0)
|
||||
{
|
||||
var devicesBg = new FlxSprite();
|
||||
devicesBg.makeGraphic(FlxG.width, 100, 0xFFfafd6d);
|
||||
add(devicesBg);
|
||||
deviceList = new TextMenuList(Horizontal, None);
|
||||
add(deviceList);
|
||||
deviceListSelected = true;
|
||||
|
||||
var item;
|
||||
|
||||
item = deviceList.createItem("Keyboard", Bold, selectDevice.bind(Keys));
|
||||
item.x = FlxG.width / 2 - item.width - 30;
|
||||
item.y = (devicesBg.height - item.height) / 2;
|
||||
|
||||
item = deviceList.createItem("Gamepad", Bold, selectDevice.bind(Gamepad(FlxG.gamepads.firstActive.id)));
|
||||
item.x = FlxG.width / 2 + 30;
|
||||
item.y = (devicesBg.height - item.height) / 2;
|
||||
}
|
||||
|
||||
// FlxG.debugger.drawDebug = true;
|
||||
var y = deviceList == null ? 30 : 120;
|
||||
var spacer = 70;
|
||||
var currentHeader:String = null;
|
||||
// list order is determined by enum order
|
||||
for (i in 0...controlList.length)
|
||||
{
|
||||
var control = controlList[i];
|
||||
var name = control.getName();
|
||||
if (currentHeader != "UI_" && name.indexOf("UI_") == 0)
|
||||
{
|
||||
currentHeader = "UI_";
|
||||
headers.add(new BoldText(0, y, "UI")).screenCenter(X);
|
||||
y += spacer;
|
||||
}
|
||||
else if (currentHeader != "NOTE_" && name.indexOf("NOTE_") == 0)
|
||||
{
|
||||
currentHeader = "NOTE_";
|
||||
headers.add(new BoldText(0, y, "NOTES")).screenCenter(X);
|
||||
y += spacer;
|
||||
}
|
||||
|
||||
if (currentHeader != null && name.indexOf(currentHeader) == 0)
|
||||
name = name.substr(currentHeader.length);
|
||||
|
||||
var label = labels.add(new BoldText(150, y, name));
|
||||
label.alpha = 0.6;
|
||||
for (i in 0...COLUMNS)
|
||||
createItem(label.x + 400 + i * 300, y, control, i);
|
||||
|
||||
y += spacer;
|
||||
}
|
||||
|
||||
camFollow = new FlxObject(FlxG.width / 2, 0, 70, 70);
|
||||
if (deviceList != null)
|
||||
{
|
||||
camFollow.y = deviceList.selectedItem.y;
|
||||
controlGrid.selectedItem.idle();
|
||||
controlGrid.enabled = false;
|
||||
}
|
||||
else
|
||||
camFollow.y = controlGrid.selectedItem.y;
|
||||
|
||||
menuCamera.follow(camFollow, null, 0.06);
|
||||
var margin = 100;
|
||||
menuCamera.deadzone.set(0, margin, menuCamera.width, menuCamera.height - margin * 2);
|
||||
menuCamera.minScrollY = 0;
|
||||
controlGrid.onChange.add(function (selected)
|
||||
{
|
||||
camFollow.y = selected.y;
|
||||
|
||||
labels.forEach((label)->label.alpha = 0.6);
|
||||
labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0;
|
||||
});
|
||||
|
||||
prompt = new Prompt("\nPress any key to rebind\n\n\n\n Escape to cancel", None);
|
||||
prompt.create();
|
||||
prompt.createBgFromMargin(100, 0xFFfafd6d);
|
||||
prompt.back.scrollFactor.set(0, 0);
|
||||
prompt.exists = false;
|
||||
add(prompt);
|
||||
}
|
||||
|
||||
function createItem(x = 0.0, y = 0.0, control:Control, index:Int)
|
||||
{
|
||||
var item = new InputItem(x, y, currentDevice, control, index, onSelect);
|
||||
for (i in 0...controlGroups.length)
|
||||
{
|
||||
if (controlGroups[i].contains(control))
|
||||
itemGroups[i].push(item);
|
||||
}
|
||||
|
||||
return controlGrid.addItem(item.name, item);
|
||||
}
|
||||
|
||||
function onSelect():Void
|
||||
{
|
||||
controlGrid.enabled = false;
|
||||
canExit = false;
|
||||
prompt.exists = true;
|
||||
}
|
||||
|
||||
function goToDeviceList()
|
||||
{
|
||||
controlGrid.selectedItem.idle();
|
||||
labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 0.6;
|
||||
controlGrid.enabled = false;
|
||||
deviceList.enabled = true;
|
||||
canExit = true;
|
||||
camFollow.y = deviceList.selectedItem.y;
|
||||
deviceListSelected = true;
|
||||
}
|
||||
|
||||
function selectDevice(device:Device)
|
||||
{
|
||||
currentDevice = device;
|
||||
|
||||
for (item in controlGrid.members)
|
||||
item.updateDevice(currentDevice);
|
||||
|
||||
var inputName = device == Keys ? "key" : "button";
|
||||
var cancel = device == Keys ? "Escape" : "Back";
|
||||
//todo: alignment
|
||||
if (device == Keys)
|
||||
prompt.setText('\nPress any key to rebind\n\n\n\n $cancel to cancel');
|
||||
else
|
||||
prompt.setText('\nPress any button\n to rebind\n\n\n $cancel to cancel');
|
||||
|
||||
|
||||
controlGrid.selectedItem.select();
|
||||
labels.members[Std.int(controlGrid.selectedIndex / COLUMNS)].alpha = 1.0;
|
||||
controlGrid.enabled = true;
|
||||
deviceList.enabled = false;
|
||||
deviceListSelected = false;
|
||||
canExit = false;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
var controls = PlayerSettings.player1.controls;
|
||||
if (controlGrid.enabled && deviceList != null && deviceListSelected == false && controls.BACK)
|
||||
goToDeviceList();
|
||||
|
||||
if (prompt.exists)
|
||||
{
|
||||
switch (currentDevice)
|
||||
{
|
||||
case Keys:
|
||||
{
|
||||
// check released otherwise bugs can happen when you change the BACK key
|
||||
var key = FlxG.keys.firstJustReleased();
|
||||
if (key != NONE)
|
||||
{
|
||||
if (key != ESCAPE)
|
||||
onInputSelect(key);
|
||||
closePrompt();
|
||||
}
|
||||
}
|
||||
case Gamepad(id):
|
||||
{
|
||||
var button = FlxG.gamepads.getByID(id).firstJustReleasedID();
|
||||
if (button != NONE)
|
||||
{
|
||||
if (button != BACK)
|
||||
onInputSelect(button);
|
||||
closePrompt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onInputSelect(input:Int)
|
||||
{
|
||||
var item = controlGrid.selectedItem;
|
||||
|
||||
// check if that key is already set for this
|
||||
var column0 = Math.floor(controlGrid.selectedIndex / 2) * 2;
|
||||
for (i in 0...COLUMNS)
|
||||
{
|
||||
if (controlGrid.members[column0 + i].input == input)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if items in the same group already have the new input
|
||||
for (group in itemGroups)
|
||||
{
|
||||
if (group.contains(item))
|
||||
{
|
||||
for (otherItem in group)
|
||||
{
|
||||
if (otherItem != item && otherItem.input == input)
|
||||
{
|
||||
// replace that input with this items old input.
|
||||
PlayerSettings.player1.controls.replaceBinding(otherItem.control, currentDevice, item.input, otherItem.input);
|
||||
// Don't use resetItem() since items share names/labels
|
||||
otherItem.input = item.input;
|
||||
otherItem.label.text = item.label.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayerSettings.player1.controls.replaceBinding(item.control, currentDevice, input, item.input);
|
||||
// Don't use resetItem() since items share names/labels
|
||||
item.input = input;
|
||||
item.label.text = item.getLabel(input);
|
||||
|
||||
PlayerSettings.player1.saveControls();
|
||||
}
|
||||
|
||||
function closePrompt()
|
||||
{
|
||||
prompt.exists = false;
|
||||
controlGrid.enabled = true;
|
||||
if (deviceList == null)
|
||||
canExit = true;
|
||||
}
|
||||
|
||||
override function destroy()
|
||||
{
|
||||
super.destroy();
|
||||
|
||||
itemGroups = null;
|
||||
|
||||
if (FlxG.cameras.list.contains(menuCamera))
|
||||
FlxG.cameras.remove(menuCamera);
|
||||
}
|
||||
|
||||
override function set_enabled(value:Bool)
|
||||
{
|
||||
if (value == false)
|
||||
{
|
||||
controlGrid.enabled = false;
|
||||
if (deviceList != null)
|
||||
deviceList.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
controlGrid.enabled = !deviceListSelected;
|
||||
if (deviceList != null)
|
||||
deviceList.enabled = deviceListSelected;
|
||||
}
|
||||
return super.set_enabled(value);
|
||||
}
|
||||
}
|
||||
|
||||
class InputItem extends TextMenuItem
|
||||
{
|
||||
public var device(default, null):Device = Keys;
|
||||
public var control:Control;
|
||||
public var input:Int = -1;
|
||||
public var index:Int = -1;
|
||||
|
||||
public function new (x = 0.0, y = 0.0, device, control, index, ?callback)
|
||||
{
|
||||
this.device = device;
|
||||
this.control = control;
|
||||
this.index = index;
|
||||
this.input = getInput();
|
||||
|
||||
super(x, y, getLabel(input), Default, callback);
|
||||
}
|
||||
|
||||
public function updateDevice(device:Device)
|
||||
{
|
||||
if (this.device != device)
|
||||
{
|
||||
this.device = device;
|
||||
input = getInput();
|
||||
label.text = getLabel(input);
|
||||
}
|
||||
}
|
||||
|
||||
function getInput()
|
||||
{
|
||||
var list = PlayerSettings.player1.controls.getInputsFor(control, device);
|
||||
if (list.length > index)
|
||||
{
|
||||
if (list[index] != FlxKey.ESCAPE || list[index] != FlxGamepadInputID.BACK)
|
||||
return list[index];
|
||||
|
||||
if (list.length > ControlsMenu.COLUMNS)
|
||||
// Escape isn't mappable, show a third option, instead.
|
||||
return list[ControlsMenu.COLUMNS];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getLabel(input:Int)
|
||||
{
|
||||
return input == -1 ? "---" : InputFormatter.format(input, device);
|
||||
}
|
||||
}
|
366
source/ui/MenuList.hx
Normal file
366
source/ui/MenuList.hx
Normal file
|
@ -0,0 +1,366 @@
|
|||
package ui;
|
||||
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.effects.FlxFlicker;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.util.FlxSignal;
|
||||
|
||||
class MenuTypedList<T:MenuItem> extends FlxTypedGroup<T>
|
||||
{
|
||||
public var selectedIndex(default, null) = 0;
|
||||
public var selectedItem(get, never):T;
|
||||
/** Called when a new item is highlighted */
|
||||
public var onChange(default, null) = new FlxTypedSignal<T->Void>();
|
||||
/** Called when an item is accepted */
|
||||
public var onAcceptPress(default, null) = new FlxTypedSignal<T->Void>();
|
||||
/** The navigation control scheme to use */
|
||||
public var navControls:NavControls;
|
||||
/** Set to false to disable nav control */
|
||||
public var enabled:Bool = true;
|
||||
/** */
|
||||
public var wrapMode:WrapMode = Both;
|
||||
|
||||
var byName = new Map<String, T>();
|
||||
/** Set to true, internally to disable controls, without affecting vars like `enabled` */
|
||||
var busy:Bool = false;
|
||||
|
||||
public function new (navControls:NavControls = Vertical, ?wrapMode:WrapMode)
|
||||
{
|
||||
this.navControls = navControls;
|
||||
|
||||
if (wrapMode != null)
|
||||
this.wrapMode = wrapMode;
|
||||
else
|
||||
this.wrapMode = switch (navControls)
|
||||
{
|
||||
case Horizontal: Horizontal;
|
||||
case Vertical: Vertical;
|
||||
default: Both;
|
||||
}
|
||||
super();
|
||||
}
|
||||
|
||||
public function addItem(name:String, item:T):T
|
||||
{
|
||||
if (length == selectedIndex)
|
||||
item.select();
|
||||
|
||||
byName[name] = item;
|
||||
return add(item);
|
||||
}
|
||||
|
||||
public function resetItem(oldName:String, newName:String, ?callback:Void->Void):T
|
||||
{
|
||||
if (!byName.exists(oldName))
|
||||
throw "No item named:" + oldName;
|
||||
|
||||
var item = byName[oldName];
|
||||
byName.remove(oldName);
|
||||
byName[newName] = item;
|
||||
item.setItem(newName, callback);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
if (enabled && !busy)
|
||||
updateControls();
|
||||
}
|
||||
|
||||
inline function updateControls()
|
||||
{
|
||||
var controls = PlayerSettings.player1.controls;
|
||||
|
||||
var wrapX = wrapMode.match(Horizontal | Both);
|
||||
var wrapY = wrapMode.match(Vertical | Both);
|
||||
var newIndex = switch(navControls)
|
||||
{
|
||||
case Vertical : navList(controls.UI_UP_P , controls.UI_DOWN_P, wrapY);
|
||||
case Horizontal : navList(controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX);
|
||||
case Both : navList(controls.UI_LEFT_P || controls.UI_UP_P, controls.UI_RIGHT_P || controls.UI_DOWN_P, !wrapMode.match(None));
|
||||
|
||||
case Columns(num): navGrid(num, controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX, controls.UI_UP_P , controls.UI_DOWN_P , wrapY);
|
||||
case Rows (num): navGrid(num, controls.UI_UP_P , controls.UI_DOWN_P , wrapY, controls.UI_LEFT_P, controls.UI_RIGHT_P, wrapX);
|
||||
}
|
||||
|
||||
if (newIndex != selectedIndex)
|
||||
{
|
||||
FlxG.sound.play(Paths.sound('scrollMenu'));
|
||||
selectItem(newIndex);
|
||||
}
|
||||
|
||||
//Todo: bypass popup blocker on firefox
|
||||
if (controls.ACCEPT)
|
||||
accept();
|
||||
}
|
||||
|
||||
function navAxis(index:Int, size:Int, prev:Bool, next:Bool, allowWrap:Bool):Int
|
||||
{
|
||||
if (prev == next)
|
||||
return index;
|
||||
|
||||
if (prev)
|
||||
{
|
||||
if (index > 0)
|
||||
index--;
|
||||
else if (allowWrap)
|
||||
index = size - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index < size - 1)
|
||||
index++;
|
||||
else if (allowWrap)
|
||||
index = 0;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls navigation on a linear list of items such as Vertical.
|
||||
* @param prev
|
||||
* @param next
|
||||
* @param allowWrap
|
||||
*/
|
||||
inline function navList(prev:Bool, next:Bool, allowWrap:Bool)
|
||||
{
|
||||
return navAxis(selectedIndex, length, prev, next, allowWrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls navigation on a grid
|
||||
* @param latSize The size of the fixed axis of the grid, or the "lateral axis"
|
||||
* @param latPrev Whether the 'prev' key is pressed along the fixed-lengthed axis. eg: "left" in Column mode
|
||||
* @param latNext Whether the 'next' key is pressed along the fixed-lengthed axis. eg: "right" in Column mode
|
||||
* @param prev Whether the 'prev' key is pressed along the variable-lengthed axis. eg: "up" in Column mode
|
||||
* @param next Whether the 'next' key is pressed along the variable-lengthed axis. eg: "down" in Column mode
|
||||
* @param allowWrap unused
|
||||
*/
|
||||
function navGrid(latSize:Int, latPrev:Bool, latNext:Bool, latAllowWrap:Bool, prev:Bool, next:Bool, allowWrap:Bool):Int
|
||||
{
|
||||
// The grid lenth along the variable-length axis
|
||||
var size = Math.ceil(length / latSize);
|
||||
// The selected position along the variable-length axis
|
||||
var index = Math.floor(selectedIndex / latSize);
|
||||
// The selected position along the fixed axis
|
||||
var latIndex = selectedIndex % latSize;
|
||||
|
||||
latIndex = navAxis(latIndex, latSize, latPrev, latNext, latAllowWrap);
|
||||
index = navAxis(index, size, prev, next, allowWrap);
|
||||
|
||||
return Std.int(Math.min(length - 1, index * latSize + latIndex));
|
||||
}
|
||||
|
||||
public function accept()
|
||||
{
|
||||
var selected = members[selectedIndex];
|
||||
onAcceptPress.dispatch(selected);
|
||||
|
||||
if (selected.fireInstantly)
|
||||
selected.callback();
|
||||
else
|
||||
{
|
||||
busy = true;
|
||||
FlxG.sound.play(Paths.sound('confirmMenu'));
|
||||
FlxFlicker.flicker(selected, 1, 0.06, true, false, function(_)
|
||||
{
|
||||
busy = false;
|
||||
selected.callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function selectItem(index:Int)
|
||||
{
|
||||
members[selectedIndex].idle();
|
||||
|
||||
selectedIndex = index;
|
||||
|
||||
var selected = members[selectedIndex];
|
||||
selected.select();
|
||||
onChange.dispatch(selected);
|
||||
}
|
||||
|
||||
public function has(name:String)
|
||||
{
|
||||
return byName.exists(name);
|
||||
}
|
||||
|
||||
public function getItem(name:String)
|
||||
{
|
||||
return byName[name];
|
||||
}
|
||||
|
||||
override function destroy()
|
||||
{
|
||||
super.destroy();
|
||||
byName.clear();
|
||||
onChange.removeAll();
|
||||
onAcceptPress.removeAll();
|
||||
}
|
||||
|
||||
inline function get_selectedItem():T
|
||||
{
|
||||
return members[selectedIndex];
|
||||
}
|
||||
}
|
||||
|
||||
class MenuItem extends FlxSprite
|
||||
{
|
||||
public var callback:Void->Void;
|
||||
public var name:String;
|
||||
/**
|
||||
* Set to true for things like opening URLs otherwise, it may it get blocked.
|
||||
*/
|
||||
public var fireInstantly = false;
|
||||
public var selected(get, never):Bool;
|
||||
function get_selected() return alpha == 1.0;
|
||||
|
||||
public function new (x = 0.0, y = 0.0, name:String, callback)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
antialiasing = true;
|
||||
setData(name, callback);
|
||||
idle();
|
||||
}
|
||||
|
||||
function setData(name:String, ?callback:Void->Void)
|
||||
{
|
||||
this.name = name;
|
||||
|
||||
if (callback != null)
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls setData and resets/redraws the state of the item
|
||||
* @param name the label.
|
||||
* @param callback Unchanged if null.
|
||||
*/
|
||||
public function setItem(name:String, ?callback:Void->Void)
|
||||
{
|
||||
setData(name, callback);
|
||||
|
||||
if (selected)
|
||||
select();
|
||||
else
|
||||
idle();
|
||||
}
|
||||
|
||||
public function idle()
|
||||
{
|
||||
alpha = 0.6;
|
||||
}
|
||||
|
||||
public function select()
|
||||
{
|
||||
alpha = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
class MenuTypedItem<T:FlxSprite> extends MenuItem
|
||||
{
|
||||
public var label(default, set):T;
|
||||
|
||||
public function new (x = 0.0, y = 0.0, label:T, name:String, callback)
|
||||
{
|
||||
super(x, y, name, callback);
|
||||
// set label after super otherwise setters fuck up
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this when you only want to show the label
|
||||
*/
|
||||
function setEmptyBackground()
|
||||
{
|
||||
var oldWidth = width;
|
||||
var oldHeight = height;
|
||||
makeGraphic(1, 1, 0x0);
|
||||
width = oldWidth;
|
||||
height = oldHeight;
|
||||
}
|
||||
|
||||
function set_label(value:T)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
value.x = x;
|
||||
value.y = y;
|
||||
value.alpha = alpha;
|
||||
}
|
||||
return this.label = value;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
if (label != null)
|
||||
label.update(elapsed);
|
||||
}
|
||||
|
||||
override function draw()
|
||||
{
|
||||
super.draw();
|
||||
if (label != null)
|
||||
{
|
||||
label.cameras = cameras;
|
||||
label.scrollFactor.copyFrom(scrollFactor);
|
||||
label.draw();
|
||||
}
|
||||
}
|
||||
|
||||
override function set_alpha(value:Float):Float
|
||||
{
|
||||
super.set_alpha(value);
|
||||
|
||||
if (label != null)
|
||||
label.alpha = alpha;
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
override function set_x(value:Float):Float
|
||||
{
|
||||
super.set_x(value);
|
||||
|
||||
if (label != null)
|
||||
label.x = x;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
override function set_y(Value:Float):Float
|
||||
{
|
||||
super.set_y(Value);
|
||||
|
||||
if (label != null)
|
||||
label.y = y;
|
||||
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
enum NavControls
|
||||
{
|
||||
Horizontal;
|
||||
Vertical;
|
||||
Both;
|
||||
Columns(num:Int);
|
||||
Rows(num:Int);
|
||||
}
|
||||
|
||||
enum WrapMode
|
||||
{
|
||||
Horizontal;
|
||||
Vertical;
|
||||
Both;
|
||||
None;
|
||||
}
|
107
source/ui/NgPrompt.hx
Normal file
107
source/ui/NgPrompt.hx
Normal file
|
@ -0,0 +1,107 @@
|
|||
package ui;
|
||||
|
||||
import NGio;
|
||||
import ui.Prompt;
|
||||
|
||||
class NgPrompt extends Prompt
|
||||
{
|
||||
public function new (text:String, style:ButtonStyle = Yes_No)
|
||||
{
|
||||
super(text, style);
|
||||
}
|
||||
|
||||
static public function showLogin()
|
||||
{
|
||||
return showLoginPrompt(true);
|
||||
}
|
||||
|
||||
static public function showSavedSessionFailed()
|
||||
{
|
||||
return showLoginPrompt(false);
|
||||
}
|
||||
|
||||
static function showLoginPrompt(fromUi:Bool)
|
||||
{
|
||||
var prompt = new NgPrompt("Talking to server...", None);
|
||||
prompt.openCallback = NGio.login.bind
|
||||
(
|
||||
function popupLauncher(openPassportUrl)
|
||||
{
|
||||
var choiceMsg = fromUi
|
||||
? #if web "Log in to Newgrounds?" #else null #end // User-input needed to allow popups
|
||||
: "Your session has expired.\n Please login again.";
|
||||
|
||||
if (choiceMsg != null)
|
||||
{
|
||||
prompt.setText(choiceMsg);
|
||||
prompt.setButtons(Yes_No);
|
||||
#if web
|
||||
prompt.buttons.getItem("yes").fireInstantly = true;
|
||||
#end
|
||||
prompt.onYes = function()
|
||||
{
|
||||
prompt.setText("Connecting..." #if web + "\n(check your popup blocker)" #end);
|
||||
prompt.setButtons(None);
|
||||
openPassportUrl();
|
||||
};
|
||||
prompt.onNo = function()
|
||||
{
|
||||
prompt.close();
|
||||
prompt = null;
|
||||
NGio.cancelLogin();
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
prompt.setText("Connecting...");
|
||||
openPassportUrl();
|
||||
}
|
||||
},
|
||||
function onLoginComplete(result:ConnectionResult)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case Success:
|
||||
{
|
||||
prompt.setText("Login Successful");
|
||||
prompt.setButtons(Ok);
|
||||
prompt.onYes = prompt.close;
|
||||
}
|
||||
case Fail(msg):
|
||||
{
|
||||
trace("Login Error:" + msg);
|
||||
prompt.setText("Login failed");
|
||||
prompt.setButtons(Ok);
|
||||
prompt.onYes = prompt.close;
|
||||
}
|
||||
case Cancelled:
|
||||
{
|
||||
if (prompt != null)
|
||||
{
|
||||
prompt.setText("Login cancelled by user");
|
||||
prompt.setButtons(Ok);
|
||||
prompt.onYes = prompt.close;
|
||||
}
|
||||
else
|
||||
trace("Login cancelled via prompt");
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return prompt;
|
||||
}
|
||||
|
||||
static public function showLogout()
|
||||
{
|
||||
var user = io.newgrounds.NG.core.user.name;
|
||||
var prompt = new NgPrompt('Log out of $user?', Yes_No);
|
||||
prompt.onYes = function()
|
||||
{
|
||||
NGio.logout();
|
||||
prompt.close();
|
||||
};
|
||||
prompt.onNo = prompt.close;
|
||||
return prompt;
|
||||
}
|
||||
}
|
260
source/ui/OptionsState.hx
Normal file
260
source/ui/OptionsState.hx
Normal file
|
@ -0,0 +1,260 @@
|
|||
package ui;
|
||||
|
||||
import flixel.FlxSubState;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.group.FlxGroup;
|
||||
import flixel.util.FlxSignal;
|
||||
|
||||
import flixel.addons.transition.FlxTransitionableState;
|
||||
|
||||
// typedef OptionsState = OptionsMenu_old;
|
||||
|
||||
// class OptionsState_new extends MusicBeatState
|
||||
class OptionsState extends MusicBeatState
|
||||
{
|
||||
var pages = new Map<PageName, Page>();
|
||||
var currentName:PageName = #if newgrounds Options #else Controls #end;
|
||||
var currentPage(get, never):Page;
|
||||
inline function get_currentPage() return pages[currentName];
|
||||
|
||||
override function create()
|
||||
{
|
||||
var menuBG = new FlxSprite().loadGraphic(Paths.image('menuDesat'));
|
||||
menuBG.color = 0xFFea71fd;
|
||||
menuBG.setGraphicSize(Std.int(menuBG.width * 1.1));
|
||||
menuBG.updateHitbox();
|
||||
menuBG.screenCenter();
|
||||
menuBG.scrollFactor.set(0, 0);
|
||||
add(menuBG);
|
||||
|
||||
var options = addPage(Options, new OptionsMenu(false));
|
||||
var controls = addPage(Controls, new ControlsMenu());
|
||||
|
||||
if (options.hasMultipleOptions())
|
||||
{
|
||||
options.onExit.add(exitToMainMenu);
|
||||
controls.onExit.add(switchPage.bind(Options));
|
||||
}
|
||||
else
|
||||
{
|
||||
// No need to show Options page
|
||||
controls.onExit.add(exitToMainMenu);
|
||||
setPage(Controls);
|
||||
}
|
||||
|
||||
// disable for intro transition
|
||||
currentPage.enabled = false;
|
||||
super.create();
|
||||
}
|
||||
|
||||
function addPage<T:Page>(name:PageName, page:T)
|
||||
{
|
||||
page.onSwitch.add(switchPage);
|
||||
pages[name] = page;
|
||||
add(page);
|
||||
page.exists = currentName == name;
|
||||
return page;
|
||||
}
|
||||
|
||||
function setPage(name:PageName)
|
||||
{
|
||||
if (pages.exists(currentName))
|
||||
currentPage.exists = false;
|
||||
|
||||
currentName = name;
|
||||
|
||||
if (pages.exists(currentName))
|
||||
currentPage.exists = true;
|
||||
}
|
||||
|
||||
override function finishTransIn()
|
||||
{
|
||||
super.finishTransIn();
|
||||
|
||||
currentPage.enabled = true;
|
||||
}
|
||||
|
||||
function switchPage(name:PageName)
|
||||
{
|
||||
//Todo animate?
|
||||
setPage(name);
|
||||
}
|
||||
|
||||
function exitToMainMenu()
|
||||
{
|
||||
currentPage.enabled = false;
|
||||
//Todo animate?
|
||||
FlxG.switchState(new MainMenuState());
|
||||
}
|
||||
}
|
||||
|
||||
class Page extends FlxGroup
|
||||
{
|
||||
public var onSwitch(default, null) = new FlxTypedSignal<PageName->Void>();
|
||||
public var onExit(default, null) = new FlxSignal();
|
||||
|
||||
public var enabled(default, set) = true;
|
||||
public var canExit = true;
|
||||
|
||||
var controls(get, never):Controls;
|
||||
inline function get_controls() return PlayerSettings.player1.controls;
|
||||
|
||||
var subState:FlxSubState;
|
||||
|
||||
inline function switchPage(name:PageName)
|
||||
{
|
||||
onSwitch.dispatch(name);
|
||||
}
|
||||
|
||||
inline function exit()
|
||||
{
|
||||
onExit.dispatch();
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
if (enabled)
|
||||
updateEnabled(elapsed);
|
||||
}
|
||||
|
||||
function updateEnabled(elapsed:Float)
|
||||
{
|
||||
if (canExit && controls.BACK)
|
||||
exit();
|
||||
}
|
||||
|
||||
function set_enabled(value:Bool)
|
||||
{
|
||||
return this.enabled = value;
|
||||
}
|
||||
|
||||
function openPrompt(prompt:Prompt, onClose:Void->Void)
|
||||
{
|
||||
enabled = false;
|
||||
prompt.closeCallback = function ()
|
||||
{
|
||||
enabled = true;
|
||||
if (onClose != null)
|
||||
onClose();
|
||||
}
|
||||
|
||||
FlxG.state.openSubState(prompt);
|
||||
}
|
||||
|
||||
override function destroy()
|
||||
{
|
||||
super.destroy();
|
||||
onSwitch.removeAll();
|
||||
}
|
||||
}
|
||||
|
||||
class OptionsMenu extends Page
|
||||
{
|
||||
var items:TextMenuList;
|
||||
|
||||
public function new (showDonate:Bool)
|
||||
{
|
||||
super();
|
||||
|
||||
add(items = new TextMenuList());
|
||||
createItem("controls", function() switchPage(Controls));
|
||||
#if CAN_OPEN_LINKS
|
||||
if (showDonate)
|
||||
{
|
||||
var hasPopupBlocker = #if web true #else false #end;
|
||||
createItem('donate', selectDonate, hasPopupBlocker);
|
||||
}
|
||||
#end
|
||||
#if newgrounds
|
||||
if (NGio.isLoggedIn)
|
||||
createItem("logout", selectLogout);
|
||||
else
|
||||
createItem("login", selectLogin);
|
||||
#end
|
||||
createItem("exit", exit);
|
||||
}
|
||||
|
||||
function createItem(name:String, callback:Void->Void, fireInstantly = false)
|
||||
{
|
||||
var item = items.createItem(0, 100 + items.length * 100, name, Bold, callback);
|
||||
item.fireInstantly = fireInstantly;
|
||||
item.screenCenter(X);
|
||||
return item;
|
||||
}
|
||||
|
||||
override function set_enabled(value:Bool)
|
||||
{
|
||||
items.enabled = value;
|
||||
return super.set_enabled(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this page has multiple options, ecluding the exit option.
|
||||
* If false, there's no reason to ever show this page.
|
||||
*/
|
||||
public function hasMultipleOptions():Bool
|
||||
{
|
||||
return items.length > 2;
|
||||
}
|
||||
|
||||
#if CAN_OPEN_LINKS
|
||||
function selectDonate()
|
||||
{
|
||||
#if linux
|
||||
Sys.command('/usr/bin/xdg-open', ["https://ninja-muffin24.itch.io/funkin", "&"]);
|
||||
#else
|
||||
FlxG.openURL('https://ninja-muffin24.itch.io/funkin');
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
#if newgrounds
|
||||
function selectLogin()
|
||||
{
|
||||
openNgPrompt(NgPrompt.showLogin());
|
||||
}
|
||||
|
||||
function selectLogout()
|
||||
{
|
||||
openNgPrompt(NgPrompt.showLogout());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls openPrompt and redraws the login/logout button
|
||||
* @param prompt
|
||||
* @param onClose
|
||||
*/
|
||||
public function openNgPrompt(prompt:Prompt, ?onClose:Void->Void)
|
||||
{
|
||||
var onPromptClose = checkLoginStatus;
|
||||
if (onClose != null)
|
||||
{
|
||||
onPromptClose = function ()
|
||||
{
|
||||
checkLoginStatus();
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
openPrompt(prompt, onPromptClose);
|
||||
}
|
||||
|
||||
function checkLoginStatus()
|
||||
{
|
||||
var prevLoggedIn = items.has("logout");
|
||||
if (prevLoggedIn && !NGio.isLoggedIn)
|
||||
items.resetItem("login", "logout", selectLogout);
|
||||
else if (!prevLoggedIn && NGio.isLoggedIn)
|
||||
items.resetItem("logout", "login", selectLogin);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
enum PageName
|
||||
{
|
||||
Options;
|
||||
Controls;
|
||||
}
|
121
source/ui/Prompt.hx
Normal file
121
source/ui/Prompt.hx
Normal file
|
@ -0,0 +1,121 @@
|
|||
package ui;
|
||||
|
||||
import ui.AtlasText;
|
||||
import ui.MenuList;
|
||||
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.graphics.frames.FlxAtlasFrames;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.util.FlxColor;
|
||||
|
||||
class Prompt extends flixel.FlxSubState
|
||||
{
|
||||
inline static var MARGIN = 100;
|
||||
|
||||
public var onYes:Void->Void;
|
||||
public var onNo:Void->Void;
|
||||
public var buttons:TextMenuList;
|
||||
public var field:AtlasText;
|
||||
public var back:FlxSprite;
|
||||
|
||||
var style:ButtonStyle;
|
||||
|
||||
public function new (text:String, style:ButtonStyle = Ok)
|
||||
{
|
||||
this.style = style;
|
||||
super(0x80000000);
|
||||
|
||||
buttons = new TextMenuList(Horizontal);
|
||||
|
||||
field = new BoldText(text);
|
||||
field.scrollFactor.set(0, 0);
|
||||
}
|
||||
|
||||
override function create()
|
||||
{
|
||||
super.create();
|
||||
|
||||
field.y = MARGIN;
|
||||
field.screenCenter(X);
|
||||
add(field);
|
||||
|
||||
createButtons();
|
||||
add(buttons);
|
||||
}
|
||||
|
||||
public function createBg(width:Int, height:Int, color = 0xFF808080)
|
||||
{
|
||||
back = new FlxSprite();
|
||||
back.makeGraphic(width, height, color, false, "prompt-bg");
|
||||
back.screenCenter(XY);
|
||||
add(back);
|
||||
members.unshift(members.pop());// bring to front
|
||||
}
|
||||
|
||||
|
||||
public function createBgFromMargin(margin = MARGIN, color = 0xFF808080)
|
||||
{
|
||||
createBg(Std.int(FlxG.width - margin * 2), Std.int(FlxG.height - margin * 2), color);
|
||||
}
|
||||
|
||||
public function setButtons(style:ButtonStyle)
|
||||
{
|
||||
if (this.style != style)
|
||||
{
|
||||
this.style = style;
|
||||
createButtons();
|
||||
}
|
||||
}
|
||||
|
||||
function createButtons()
|
||||
{
|
||||
// destroy previous buttons
|
||||
while(buttons.members.length > 0)
|
||||
{
|
||||
buttons.remove(buttons.members[0], true).destroy();
|
||||
}
|
||||
|
||||
switch(style)
|
||||
{
|
||||
case Yes_No : createButtonsHelper("yes", "no");
|
||||
case Ok : createButtonsHelper("ok");
|
||||
case Custom(yes, no): createButtonsHelper(yes, no);
|
||||
case None : buttons.exists = false;
|
||||
};
|
||||
}
|
||||
|
||||
function createButtonsHelper(yes:String, ?no:String)
|
||||
{
|
||||
buttons.exists = true;
|
||||
// pass anonymous functions rather than the current callbacks, in case they change later
|
||||
var yesButton = buttons.createItem(yes, function() onYes());
|
||||
yesButton.screenCenter(X);
|
||||
yesButton.y = FlxG.height - yesButton.height - MARGIN;
|
||||
yesButton.scrollFactor.set(0, 0);
|
||||
if (no != null)
|
||||
{
|
||||
// place right
|
||||
yesButton.x = FlxG.width - yesButton.width - MARGIN;
|
||||
|
||||
var noButton = buttons.createItem(no, function() onNo());
|
||||
noButton.x = MARGIN;
|
||||
noButton.y = FlxG.height - noButton.height - MARGIN;
|
||||
noButton.scrollFactor.set(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public function setText(text:String)
|
||||
{
|
||||
field.text = text;
|
||||
field.screenCenter(X);
|
||||
}
|
||||
}
|
||||
|
||||
enum ButtonStyle
|
||||
{
|
||||
Ok;
|
||||
Yes_No;
|
||||
Custom(yes:String, no:Null<String>);//Todo: more than 2
|
||||
None;
|
||||
}
|
56
source/ui/TextMenuList.hx
Normal file
56
source/ui/TextMenuList.hx
Normal file
|
@ -0,0 +1,56 @@
|
|||
package ui;
|
||||
|
||||
import ui.AtlasText;
|
||||
import ui.MenuList;
|
||||
|
||||
class TextMenuList extends MenuTypedList<TextMenuItem>
|
||||
{
|
||||
public function new (navControls:NavControls = Vertical, ?wrapMode)
|
||||
{
|
||||
super(navControls, wrapMode);
|
||||
}
|
||||
|
||||
public function createItem(x = 0.0, y = 0.0, name:String, font:AtlasFont = Bold, callback, fireInstantly = false)
|
||||
{
|
||||
var item = new TextMenuItem(x, y, name, font, callback);
|
||||
item.fireInstantly = fireInstantly;
|
||||
return addItem(name, item);
|
||||
}
|
||||
}
|
||||
|
||||
class TextMenuItem extends TextTypedMenuItem<AtlasText>
|
||||
{
|
||||
public function new (x = 0.0, y = 0.0, name:String, font:AtlasFont = Bold, callback)
|
||||
{
|
||||
super(x, y, new AtlasText(0, 0, name, font), name, callback);
|
||||
setEmptyBackground();
|
||||
}
|
||||
}
|
||||
|
||||
class TextTypedMenuItem<T:AtlasText> extends MenuTypedItem<T>
|
||||
{
|
||||
public function new (x = 0.0, y = 0.0, label:T, name:String, callback)
|
||||
{
|
||||
super(x, y, label, name, callback);
|
||||
}
|
||||
|
||||
override function setItem(name:String, ?callback:Void -> Void)
|
||||
{
|
||||
if (label != null)
|
||||
{
|
||||
label.text = name;
|
||||
label.alpha = alpha;
|
||||
width = label.width;
|
||||
height = label.height;
|
||||
}
|
||||
|
||||
super.setItem(name, callback);
|
||||
}
|
||||
|
||||
override function set_label(value:T):T
|
||||
{
|
||||
super.set_label(value);
|
||||
setItem(name, callback);
|
||||
return value;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue