BULLSHIT CONTROLS

This commit is contained in:
Cameron Taylor 2020-10-21 16:33:43 -07:00
parent 539a5f8550
commit bea3ca7fd8
7 changed files with 853 additions and 69 deletions

View File

@ -7,4 +7,5 @@ Tom Fulp
StuffedWombat
mmatt_ugh
Squidly
Luis
Luis
GeoKureli

606
source/Controls.hx Normal file
View File

@ -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<String, FlxActionDigital> = [];
public var gamepadsAdded:Array<Int> = [];
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<FlxKey>)
{
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<FlxKey>)
{
inline forEachBound(control, (action, _) -> removeKeys(action, keys));
}
inline static function addKeys(action:FlxActionDigital, keys:Array<FlxKey>, state:FlxInputState)
{
for (key in keys)
action.addKey(key, state);
}
static function removeKeys(action:FlxActionDigital, keys:Array<FlxKey>)
{
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<Control, Array<FlxGamepadInputID>>):Void
{
gamepadsAdded.push(id);
for (control => buttons in buttonMap)
bindButtons(control, id, buttons);
}
inline function addGamepadLiteral(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):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<FlxGamepadInputID>, state, id)
{
for (button in buttons)
action.addGamepad(button, state, id);
}
static function removeButtons(action:FlxActionDigital, gamepadID:Int, buttons:Array<FlxGamepadInputID>)
{
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<Int>):Array<Int>
{
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);
}
}

View File

@ -0,0 +1,11 @@
package;
import flixel.FlxSubState;
class ControlsSubState extends FlxSubState
{
public function new()
{
super();
}
}

View File

@ -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);
}
}

View File

@ -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));

View File

@ -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)

151
source/PlayerSettings.hx Normal file
View File

@ -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 FlxTypedSignal<PlayerSettings->Void>();
static public final onAvatarRemove = new FlxTypedSignal<PlayerSettings->Void>();
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;
}
}