From bea3ca7fd8da882e84b77bffccc776456bef0daf Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 21 Oct 2020 16:33:43 -0700 Subject: [PATCH] BULLSHIT CONTROLS --- assets/data/specialThanks.txt | 3 +- source/Controls.hx | 606 ++++++++++++++++++++++++++++++++++ source/ControlsSubState.hx | 11 + source/FreeplayState.hx | 6 + source/Main.hx | 2 +- source/PlayState.hx | 143 ++++---- source/PlayerSettings.hx | 151 +++++++++ 7 files changed, 853 insertions(+), 69 deletions(-) create mode 100644 source/Controls.hx create mode 100644 source/ControlsSubState.hx create mode 100644 source/PlayerSettings.hx diff --git a/assets/data/specialThanks.txt b/assets/data/specialThanks.txt index 4b77fe1ba..a8397c8c4 100644 --- a/assets/data/specialThanks.txt +++ b/assets/data/specialThanks.txt @@ -7,4 +7,5 @@ Tom Fulp StuffedWombat mmatt_ugh Squidly -Luis \ No newline at end of file +Luis +GeoKureli \ No newline at end of file diff --git a/source/Controls.hx b/source/Controls.hx new file mode 100644 index 000000000..a60a49da4 --- /dev/null +++ b/source/Controls.hx @@ -0,0 +1,606 @@ +package; + +import flixel.FlxG; +import flixel.input.FlxInput; +import flixel.input.actions.FlxAction; +import flixel.input.actions.FlxActionInput; +import flixel.input.actions.FlxActionInputDigital; +import flixel.input.actions.FlxActionManager; +import flixel.input.actions.FlxActionSet; +import flixel.input.gamepad.FlxGamepadButton; +import flixel.input.gamepad.FlxGamepadInputID; +import flixel.input.keyboard.FlxKey; + +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 JUMP = "jump"; + var JUMP_P = "jump-press"; + var JUMP_R = "jump-release"; + var ACCEPT = "accept"; + var BACK = "back"; + var PAUSE = "pause"; + var RESET = "reset"; +} + +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 + * an input so, for instance, they can't set jump-press and jump-release to different keys. + */ +enum Control +{ + UP; + LEFT; + RIGHT; + DOWN; + JUMP; + RESET; + ACCEPT; + BACK; + PAUSE; +} + +enum KeyboardScheme +{ + Solo; + Duo(first:Bool); + None; + Custom; +} + +/** + * A list of actions that a player would invoke via some input device. + * Uses FlxActions to funnel various inputs to a single action. + */ +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 _jump = new FlxActionDigital(Action.JUMP); + var _jumpP = new FlxActionDigital(Action.JUMP_P); + var _jumpR = new FlxActionDigital(Action.JUMP_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); + + var byName:Map = []; + + public var gamepadsAdded:Array = []; + public var keyboardScheme = KeyboardScheme.None; + + public var UP(get, never):Bool; + + inline function get_UP() + return _up.check(); + + public var LEFT(get, never):Bool; + + inline function get_LEFT() + return _left.check(); + + public var RIGHT(get, never):Bool; + + 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 _upP.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 JUMP(get, never):Bool; + + inline function get_JUMP() + return _jump.check(); + + public var JUMP_P(get, never):Bool; + + inline function get_JUMP_P() + return _jumpP.check(); + + public var JUMP_R(get, never):Bool; + + inline function get_JUMP_R() + return _jumpR.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 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(_jump); + add(_jumpP); + add(_jumpR); + add(_accept); + add(_back); + add(_pause); + add(_reset); + + for (action in digitalActions) + byName[action.name] = action; + + setKeyboardScheme(scheme, false); + } + + override function update() + { + super.update(); + } + + // inline + public function checkByName(name:Action):Bool + { + #if debug + if (!byName.exists(name)) + throw 'Invalid name: $name'; + #end + return byName[name].check(); + } + + public function getDialogueName(action:FlxActionDigital):String + { + var input = action.inputs[0]; + return switch input.device + { + case KEYBOARD: return '[${(input.inputID : FlxKey)}]'; + case GAMEPAD: return '(${(input.inputID : FlxGamepadInputID)})'; + case device: throw 'unhandled device: $device'; + } + } + + public function getDialogueNameFromToken(token:String):String + { + return getDialogueName(getActionFromControl(Control.createByName(token.toUpperCase()))); + } + + function getActionFromControl(control:Control):FlxActionDigital + { + return switch (control) + { + case UP: _up; + case DOWN: _down; + case LEFT: _left; + case RIGHT: _right; + case JUMP: _jump; + case ACCEPT: _accept; + case BACK: _back; + case PAUSE: _pause; + case RESET: _reset; + } + } + + static function init():Void + { + var actions = new FlxActionManager(); + FlxG.inputs.add(actions); + } + + /** + * Calls a function passing each action bound by the specified control + * @param control + * @param func + * @return ->Void) + */ + function forEachBound(control:Control, func:(FlxActionDigital, FlxInputState) -> Void) + { + 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 JUMP: + func(_jump, PRESSED); + func(_jumpP, JUST_PRESSED); + func(_jumpR, JUST_RELEASED); + case ACCEPT: + func(_accept, JUST_PRESSED); + case BACK: + func(_back, JUST_PRESSED); + case PAUSE: + func(_pause, JUST_PRESSED); + case RESET: + func(_reset, JUST_PRESSED); + } + } + + public function replaceBinding(control:Control, device:Device, ?toAdd:Int, ?toRemove:Int) + { + if (toAdd == toRemove) + return; + + switch (device) + { + case Keys: + if (toRemove != null) + unbindKeys(control, [toRemove]); + if (toAdd != null) + bindKeys(control, [toAdd]); + + case Gamepad(id): + if (toRemove != null) + unbindButtons(control, id, [toRemove]); + if (toAdd != null) + bindButtons(control, id, [toAdd]); + } + } + + public function copyFrom(controls:Controls, ?device:Device) + { + for (name => action in controls.byName) + { + for (input in action.inputs) + { + if (device == null || isDevice(input, device)) + byName[name].add(cast input); + } + } + + switch (device) + { + case null: + // add all + for (gamepad in controls.gamepadsAdded) + if (!gamepadsAdded.contains(gamepad)) + gamepadsAdded.push(gamepad); + + mergeKeyboardScheme(controls.keyboardScheme); + + case Gamepad(id): + gamepadsAdded.push(id); + case Keys: + mergeKeyboardScheme(controls.keyboardScheme); + } + } + + inline public function copyTo(controls:Controls, ?device:Device) + { + controls.copyFrom(this, device); + } + + function mergeKeyboardScheme(scheme:KeyboardScheme):Void + { + if (scheme != None) + { + switch (keyboardScheme) + { + case None: + keyboardScheme = scheme; + default: + keyboardScheme = Custom; + } + } + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function bindKeys(control:Control, keys:Array) + { + inline forEachBound(control, (action, state) -> addKeys(action, keys, state)); + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function unbindKeys(control:Control, keys:Array) + { + inline forEachBound(control, (action, _) -> removeKeys(action, keys)); + } + + inline static function addKeys(action:FlxActionDigital, keys:Array, state:FlxInputState) + { + for (key in keys) + action.addKey(key, state); + } + + static function removeKeys(action:FlxActionDigital, keys:Array) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (input.device == KEYBOARD && keys.indexOf(cast input.inputID) != -1) + action.remove(input); + } + } + + public function setKeyboardScheme(scheme:KeyboardScheme, reset = true) + { + if (reset) + removeKeyboard(); + + keyboardScheme = scheme; + 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.JUMP, [Z, Y, FlxKey.UP]); + inline bindKeys(Control.ACCEPT, [Z, SPACE]); + inline bindKeys(Control.BACK, [X]); + inline bindKeys(Control.PAUSE, [P, ENTER]); + 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.JUMP, [G, W, Z]); + 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.JUMP, [O, FlxKey.UP]); + 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 + } + } + + function removeKeyboard() + { + for (action in this.digitalActions) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (input.device == KEYBOARD) + action.remove(input); + } + } + } + + public function addGamepad(id:Int, ?buttonMap:Map>):Void + { + gamepadsAdded.push(id); + for (control => buttons in buttonMap) + bindButtons(control, id, buttons); + } + + inline function addGamepadLiteral(id:Int, ?buttonMap:Map>):Void + { + gamepadsAdded.push(id); + for (control => buttons in buttonMap) + inline bindButtons(control, id, buttons); + } + + public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void + { + for (action in this.digitalActions) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID)) + action.remove(input); + } + } + + gamepadsAdded.remove(deviceID); + } + + public function addDefaultGamepad(id):Void + { + 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.JUMP => [A], + Control.PAUSE => [START], + Control.RESET => [Y] + ]); + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function bindButtons(control:Control, id, buttons) + { + inline forEachBound(control, (action, state) -> addButtons(action, buttons, state, id)); + } + + /** + * Sets all actions that pertain to the binder to trigger when the supplied keys are used. + * If binder is a literal you can inline this + */ + public function unbindButtons(control:Control, gamepadID:Int, buttons) + { + inline forEachBound(control, (action, _) -> removeButtons(action, gamepadID, buttons)); + } + + inline static function addButtons(action:FlxActionDigital, buttons:Array, state, id) + { + for (button in buttons) + action.addGamepad(button, state, id); + } + + static function removeButtons(action:FlxActionDigital, gamepadID:Int, buttons:Array) + { + var i = action.inputs.length; + while (i-- > 0) + { + var input = action.inputs[i]; + if (isGamepad(input, gamepadID) && buttons.indexOf(cast input.inputID) != -1) + action.remove(input); + } + } + + public function getInputsFor(control:Control, device:Device, ?list:Array):Array + { + if (list == null) + list = []; + + switch (device) + { + case Keys: + for (input in getActionFromControl(control).inputs) + { + if (input.device == KEYBOARD) + list.push(input.inputID); + } + case Gamepad(id): + for (input in getActionFromControl(control).inputs) + { + if (input.deviceID == id) + list.push(input.inputID); + } + } + return list; + } + + public function removeDevice(device:Device) + { + switch (device) + { + case Keys: + setKeyboardScheme(None); + case Gamepad(id): + removeGamepad(id); + } + } + + static function isDevice(input:FlxActionInput, device:Device) + { + return switch device + { + case Keys: input.device == KEYBOARD; + case Gamepad(id): isGamepad(input, id); + } + } + + inline static function isGamepad(input:FlxActionInput, deviceID:Int) + { + return input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID); + } +} diff --git a/source/ControlsSubState.hx b/source/ControlsSubState.hx new file mode 100644 index 000000000..d63e978e1 --- /dev/null +++ b/source/ControlsSubState.hx @@ -0,0 +1,11 @@ +package; + +import flixel.FlxSubState; + +class ControlsSubState extends FlxSubState +{ + public function new() + { + super(); + } +} diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 1cd5e1dd1..cfbd52379 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -49,6 +49,12 @@ class FreeplayState extends MusicBeatState selector.y = (26 * curSelected) + 30; + if (FlxG.keys.justPressed.ENTER) + { + PlayState.SONG = Song.loadFromJson(songs[curSelected].toLowerCase()); + FlxG.switchState(new PlayState()); + } + super.update(elapsed); } } diff --git a/source/Main.hx b/source/Main.hx index d4bd9a4a7..e2e0f4dee 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -9,7 +9,7 @@ class Main extends Sprite public function new() { super(); - addChild(new FlxGame(0, 0, ChartingState)); + addChild(new FlxGame(0, 0, FreeplayState)); #if !mobile addChild(new FPS(10, 3, 0xFFFFFF)); diff --git a/source/PlayState.hx b/source/PlayState.hx index 25fc71367..6650f7193 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -65,13 +65,20 @@ class PlayState extends MusicBeatState private var healthHeads:FlxSprite; + var controls(get, never):Controls; + + inline function get_controls():Controls + return PlayerSettings.player1.controls; + override public function create() { + PlayerSettings.init(); + persistentUpdate = true; persistentDraw = true; if (SONG == null) - SONG = Song.loadFromJson('tutorial'); + SONG = Song.loadFromJson(curLevel); var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(AssetPaths.stageback__png); // bg.setGraphicSize(Std.int(bg.width * 2.5)); @@ -774,84 +781,86 @@ class PlayState extends MusicBeatState private function keyShit():Void { // HOLDING - var up = FlxG.keys.anyPressed([W, UP]); - var right = FlxG.keys.anyPressed([D, RIGHT]); - var down = FlxG.keys.anyPressed([S, DOWN]); - var left = FlxG.keys.anyPressed([A, LEFT]); + var up = controls.UP; + var right = controls.RIGHT; + var down = controls.DOWN; + var left = controls.LEFT; - var upP = FlxG.keys.anyJustPressed([W, UP]); - var rightP = FlxG.keys.anyJustPressed([D, RIGHT]); - var downP = FlxG.keys.anyJustPressed([S, DOWN]); - var leftP = FlxG.keys.anyJustPressed([A, LEFT]); + var upP = controls.UP_P; + var rightP = controls.RIGHT_P; + var downP = controls.DOWN_P; + var leftP = controls.LEFT_P; - var upR = FlxG.keys.anyJustReleased([W, UP]); - var rightR = FlxG.keys.anyJustReleased([D, RIGHT]); - var downR = FlxG.keys.anyJustReleased([S, DOWN]); - var leftR = FlxG.keys.anyJustReleased([A, LEFT]); + var upR = controls.UP_R; + var rightR = controls.RIGHT_R; + var downR = controls.DOWN_R; + var leftR = controls.LEFT_R; - var gamepad = FlxG.gamepads.lastActive; - if (gamepad != null) - { - if (gamepad.anyPressed(["DPAD_LEFT", "LEFT_STICK_DIGITAL_LEFT", X])) + /* + var gamepad = FlxG.gamepads.lastActive; + if (gamepad != null) { - left = true; - } + if (gamepad.anyPressed(["DPAD_LEFT", "LEFT_STICK_DIGITAL_LEFT", X])) + { + left = true; + } - if (gamepad.anyPressed(["DPAD_RIGHT", "LEFT_STICK_DIGITAL_RIGHT", B])) - { - right = true; - } + if (gamepad.anyPressed(["DPAD_RIGHT", "LEFT_STICK_DIGITAL_RIGHT", B])) + { + right = true; + } - if (gamepad.anyPressed(['DPAD_UP', "LEFT_STICK_DIGITAL_UP", Y])) - { - up = true; - } + if (gamepad.anyPressed(['DPAD_UP', "LEFT_STICK_DIGITAL_UP", Y])) + { + up = true; + } - if (gamepad.anyPressed(["DPAD_DOWN", "LEFT_STICK_DIGITAL_DOWN", A])) - { - down = true; - } + if (gamepad.anyPressed(["DPAD_DOWN", "LEFT_STICK_DIGITAL_DOWN", A])) + { + down = true; + } - if (gamepad.anyJustPressed(["DPAD_LEFT", "LEFT_STICK_DIGITAL_LEFT", X])) - { - leftP = true; - } + if (gamepad.anyJustPressed(["DPAD_LEFT", "LEFT_STICK_DIGITAL_LEFT", X])) + { + leftP = true; + } - if (gamepad.anyJustPressed(["DPAD_RIGHT", "LEFT_STICK_DIGITAL_RIGHT", B])) - { - rightP = true; - } + if (gamepad.anyJustPressed(["DPAD_RIGHT", "LEFT_STICK_DIGITAL_RIGHT", B])) + { + rightP = true; + } - if (gamepad.anyJustPressed(['DPAD_UP', "LEFT_STICK_DIGITAL_UP", Y])) - { - upP = true; - } + if (gamepad.anyJustPressed(['DPAD_UP', "LEFT_STICK_DIGITAL_UP", Y])) + { + upP = true; + } - if (gamepad.anyJustPressed(["DPAD_DOWN", "LEFT_STICK_DIGITAL_DOWN", A])) - { - downP = true; - } + if (gamepad.anyJustPressed(["DPAD_DOWN", "LEFT_STICK_DIGITAL_DOWN", A])) + { + downP = true; + } - if (gamepad.anyJustReleased(["DPAD_LEFT", "LEFT_STICK_DIGITAL_LEFT", X])) - { - leftR = true; - } + if (gamepad.anyJustReleased(["DPAD_LEFT", "LEFT_STICK_DIGITAL_LEFT", X])) + { + leftR = true; + } - if (gamepad.anyJustReleased(["DPAD_RIGHT", "LEFT_STICK_DIGITAL_RIGHT", B])) - { - rightR = true; - } + if (gamepad.anyJustReleased(["DPAD_RIGHT", "LEFT_STICK_DIGITAL_RIGHT", B])) + { + rightR = true; + } - if (gamepad.anyJustReleased(['DPAD_UP', "LEFT_STICK_DIGITAL_UP", Y])) - { - upR = true; - } + if (gamepad.anyJustReleased(['DPAD_UP', "LEFT_STICK_DIGITAL_UP", Y])) + { + upR = true; + } - if (gamepad.anyJustReleased(["DPAD_DOWN", "LEFT_STICK_DIGITAL_DOWN", A])) - { - downR = true; + if (gamepad.anyJustReleased(["DPAD_DOWN", "LEFT_STICK_DIGITAL_DOWN", A])) + { + downR = true; + } } - } + */ FlxG.watch.addQuick('asdfa', upP); if ((upP || rightP || downP || leftP) && !boyfriend.stunned && generatedMusic) @@ -1008,10 +1017,10 @@ class PlayState extends MusicBeatState { // just double pasting this shit cuz fuk u // REDO THIS SYSTEM! - var upP = FlxG.keys.anyJustPressed([W, UP]); - var rightP = FlxG.keys.anyJustPressed([D, RIGHT]); - var downP = FlxG.keys.anyJustPressed([S, DOWN]); - var leftP = FlxG.keys.anyJustPressed([A, LEFT]); + var upP = controls.UP_P; + var rightP = controls.RIGHT_P; + var downP = controls.DOWN_P; + var leftP = controls.LEFT_P; var gamepad = FlxG.gamepads.lastActive; if (gamepad != null) diff --git a/source/PlayerSettings.hx b/source/PlayerSettings.hx new file mode 100644 index 000000000..fa034581d --- /dev/null +++ b/source/PlayerSettings.hx @@ -0,0 +1,151 @@ +package; + +import Controls; +import flixel.FlxCamera; +import flixel.FlxG; +import flixel.util.FlxSignal; + +// import ui.DeviceManager; +// import props.Player; +class PlayerSettings +{ + static public var numPlayers(default, null) = 0; + static public var numAvatars(default, null) = 0; + static public var player1(default, null):PlayerSettings; + static public var player2(default, null):PlayerSettings; + + static public final onAvatarAdd = new FlxTypedSignalVoid>(); + static public final onAvatarRemove = new FlxTypedSignalVoid>(); + + public var id(default, null):Int; + + public final controls:Controls; + + // public var avatar:Player; + // public var camera(get, never):PlayCamera; + + function new(id, scheme) + { + this.id = id; + this.controls = new Controls('player$id', scheme); + } + + 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 + { + 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 (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 public function reset() + { + player1 = null; + player2 = null; + numPlayers = 0; + } +}