Guest User

controls.hx

a guest
Sep 12th, 2021
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.68 KB | None | 0 0
  1. package;
  2.  
  3. import flixel.FlxG;
  4. import flixel.input.FlxInput;
  5. import flixel.input.actions.FlxAction;
  6. import flixel.input.actions.FlxActionInput;
  7. import flixel.input.actions.FlxActionInputDigital;
  8. import flixel.input.actions.FlxActionManager;
  9. import flixel.input.actions.FlxActionSet;
  10. import flixel.input.gamepad.FlxGamepadButton;
  11. import flixel.input.gamepad.FlxGamepadInputID;
  12. import flixel.input.keyboard.FlxKey;
  13.  
  14. enum abstract Action(String) to String from String
  15. {
  16. var UP = "up";
  17. var LEFT = "left";
  18. var RIGHT = "right";
  19. var DOWN = "down";
  20. var UP_P = "up-press";
  21. var LEFT_P = "left-press";
  22. var RIGHT_P = "right-press";
  23. var DOWN_P = "down-press";
  24. var UP_R = "up-release";
  25. var LEFT_R = "left-release";
  26. var RIGHT_R = "right-release";
  27. var DOWN_R = "down-release";
  28. var ACCEPT = "accept";
  29. var BACK = "back";
  30. var PAUSE = "pause";
  31. var RESET = "reset";
  32. var CHEAT = "cheat";
  33. }
  34. enum Device
  35. {
  36. Keys;
  37. Gamepad(id:Int);
  38. }
  39.  
  40. enum Control
  41. {
  42. UP;
  43. LEFT;
  44. RIGHT;
  45. DOWN;
  46. RESET;
  47. ACCEPT;
  48. BACK;
  49. PAUSE;
  50. CHEAT;
  51. }
  52.  
  53. // Types of keyboard bindings
  54. enum KeyboardScheme
  55. {
  56. Solo;
  57. Duo(first:Bool);
  58. None;
  59. Custom;
  60. }
  61.  
  62.  
  63. class Controls extends FlxActionSet
  64. {
  65. var _up = new FlxActionDigital(Action.UP);
  66. var _left = new FlxActionDigital(Action.LEFT);
  67. var _right = new FlxActionDigital(Action.RIGHT);
  68. var _down = new FlxActionDigital(Action.DOWN);
  69. var _upP = new FlxActionDigital(Action.UP_P);
  70. var _leftP = new FlxActionDigital(Action.LEFT_P);
  71. var _rightP = new FlxActionDigital(Action.RIGHT_P);
  72. var _downP = new FlxActionDigital(Action.DOWN_P);
  73. var _upR = new FlxActionDigital(Action.UP_R);
  74. var _leftR = new FlxActionDigital(Action.LEFT_R);
  75. var _rightR = new FlxActionDigital(Action.RIGHT_R);
  76. var _downR = new FlxActionDigital(Action.DOWN_R);
  77. var _accept = new FlxActionDigital(Action.ACCEPT);
  78. var _back = new FlxActionDigital(Action.BACK);
  79. var _pause = new FlxActionDigital(Action.PAUSE);
  80. var _reset = new FlxActionDigital(Action.RESET);
  81. var _cheat = new FlxActionDigital(Action.CHEAT);
  82.  
  83. var byName:Map<String, FlxActionDigital> = [];
  84.  
  85. public var gamepadsAdded:Array<Int> = [];
  86. public var keyboardScheme = KeyboardScheme.None;
  87.  
  88. public var UP(get, never):Bool;
  89.  
  90. inline function get_UP()
  91. return _up.check();
  92.  
  93. public var LEFT(get, never):Bool;
  94.  
  95. inline function get_LEFT()
  96. return _left.check();
  97.  
  98. public var RIGHT(get, never):Bool;
  99.  
  100. inline function get_RIGHT()
  101. return _right.check();
  102.  
  103. public var DOWN(get, never):Bool;
  104.  
  105. inline function get_DOWN()
  106. return _down.check();
  107.  
  108. public var UP_P(get, never):Bool;
  109.  
  110. inline function get_UP_P()
  111. return _upP.check();
  112.  
  113. public var LEFT_P(get, never):Bool;
  114.  
  115. inline function get_LEFT_P()
  116. return _leftP.check();
  117.  
  118. public var RIGHT_P(get, never):Bool;
  119.  
  120. inline function get_RIGHT_P()
  121. return _rightP.check();
  122.  
  123. public var DOWN_P(get, never):Bool;
  124.  
  125. inline function get_DOWN_P()
  126. return _downP.check();
  127.  
  128. public var UP_R(get, never):Bool;
  129.  
  130. inline function get_UP_R()
  131. return _upR.check();
  132.  
  133. public var LEFT_R(get, never):Bool;
  134.  
  135. inline function get_LEFT_R()
  136. return _leftR.check();
  137.  
  138. public var RIGHT_R(get, never):Bool;
  139.  
  140. inline function get_RIGHT_R()
  141. return _rightR.check();
  142.  
  143. public var DOWN_R(get, never):Bool;
  144.  
  145. inline function get_DOWN_R()
  146. return _downR.check();
  147.  
  148. public var ACCEPT(get, never):Bool;
  149.  
  150. inline function get_ACCEPT()
  151. return _accept.check();
  152.  
  153. public var BACK(get, never):Bool;
  154.  
  155. inline function get_BACK()
  156. return _back.check();
  157.  
  158. public var PAUSE(get, never):Bool;
  159.  
  160. inline function get_PAUSE()
  161. return _pause.check();
  162.  
  163. public var RESET(get, never):Bool;
  164.  
  165. inline function get_RESET()
  166. return _reset.check();
  167.  
  168. public var CHEAT(get, never):Bool;
  169.  
  170. inline function get_CHEAT()
  171. return _cheat.check();
  172.  
  173. public function new(name, scheme = None)
  174. {
  175. super(name);
  176.  
  177. add(_up);
  178. add(_left);
  179. add(_right);
  180. add(_down);
  181. add(_upP);
  182. add(_leftP);
  183. add(_rightP);
  184. add(_downP);
  185. add(_upR);
  186. add(_leftR);
  187. add(_rightR);
  188. add(_downR);
  189. add(_accept);
  190. add(_back);
  191. add(_pause);
  192. add(_reset);
  193. add(_cheat);
  194.  
  195. for (action in digitalActions)
  196. byName[action.name] = action;
  197.  
  198. setKeyboardScheme(scheme, false);
  199. }
  200.  
  201. override function update()
  202. {
  203. super.update();
  204. }
  205.  
  206. // inline
  207. public function checkByName(name:Action):Bool
  208. {
  209. return byName[name].check();
  210. }
  211.  
  212. public function getDialogueName(action:FlxActionDigital):String
  213. {
  214. var input = action.inputs[0];
  215. return switch input.device
  216. {
  217. case KEYBOARD: return '[${(input.inputID : FlxKey)}]';
  218. case GAMEPAD: return '(${(input.inputID : FlxGamepadInputID)})';
  219. case device: throw 'unhandled device: $device';
  220. }
  221. }
  222.  
  223. public function getDialogueNameFromToken(token:String):String
  224. {
  225. return getDialogueName(getActionFromControl(Control.createByName(token.toUpperCase())));
  226. }
  227.  
  228. function getActionFromControl(control:Control):FlxActionDigital
  229. {
  230. return switch (control)
  231. {
  232. case UP: _up;
  233. case DOWN: _down;
  234. case LEFT: _left;
  235. case RIGHT: _right;
  236. case ACCEPT: _accept;
  237. case BACK: _back;
  238. case PAUSE: _pause;
  239. case RESET: _reset;
  240. case CHEAT: _cheat;
  241. }
  242. }
  243.  
  244. static function init():Void
  245. {
  246. var actions = new FlxActionManager();
  247. FlxG.inputs.add(actions);
  248. }
  249.  
  250. /**
  251. * Calls a function passing each action bound by the specified control
  252. * @param control
  253. * @param func
  254. * @return ->Void)
  255. */
  256.  
  257. function forEachBound(control:Control, func:FlxActionDigital->FlxInputState->Void)
  258. {
  259. switch (control)
  260. {
  261. case UP:
  262. func(_up, PRESSED);
  263. func(_upP, JUST_PRESSED);
  264. func(_upR, JUST_RELEASED);
  265. case LEFT:
  266. func(_left, PRESSED);
  267. func(_leftP, JUST_PRESSED);
  268. func(_leftR, JUST_RELEASED);
  269. case RIGHT:
  270. func(_right, PRESSED);
  271. func(_rightP, JUST_PRESSED);
  272. func(_rightR, JUST_RELEASED);
  273. case DOWN:
  274. func(_down, PRESSED);
  275. func(_downP, JUST_PRESSED);
  276. func(_downR, JUST_RELEASED);
  277. case ACCEPT:
  278. func(_accept, JUST_PRESSED);
  279. case BACK:
  280. func(_back, JUST_PRESSED);
  281. case PAUSE:
  282. func(_pause, JUST_PRESSED);
  283. case RESET:
  284. func(_reset, JUST_PRESSED);
  285. case CHEAT:
  286. func(_cheat, JUST_PRESSED);
  287. }
  288. }
  289.  
  290. public function replaceBinding(control:Control, device:Device, ?toAdd:Int, ?toRemove:Int)
  291. {
  292. if (toAdd == toRemove)
  293. return;
  294.  
  295. switch (device)
  296. {
  297. case Keys:
  298. if (toRemove != null)
  299. unbindKeys(control, [toRemove]);
  300. if (toAdd != null)
  301. bindKeys(control, [toAdd]);
  302.  
  303. case Gamepad(id):
  304. if (toRemove != null)
  305. unbindButtons(control, id, [toRemove]);
  306. if (toAdd != null)
  307. bindButtons(control, id, [toAdd]);
  308. }
  309. }
  310.  
  311. public function copyFrom(controls:Controls, ?device:Device)
  312. {
  313. for (name => action in controls.byName)
  314. {
  315. for (input in action.inputs)
  316. {
  317. if (device == null || isDevice(input, device))
  318. byName[name].add(cast input);
  319. }
  320. }
  321.  
  322. switch (device)
  323. {
  324. case null:
  325. // add all
  326. for (gamepad in controls.gamepadsAdded)
  327. if (!gamepadsAdded.contains(gamepad))
  328. gamepadsAdded.push(gamepad);
  329.  
  330. mergeKeyboardScheme(controls.keyboardScheme);
  331.  
  332. case Gamepad(id):
  333. gamepadsAdded.push(id);
  334. case Keys:
  335. mergeKeyboardScheme(controls.keyboardScheme);
  336. }
  337. }
  338.  
  339. inline public function copyTo(controls:Controls, ?device:Device)
  340. {
  341. controls.copyFrom(this, device);
  342. }
  343.  
  344. function mergeKeyboardScheme(scheme:KeyboardScheme):Void
  345. {
  346. if (scheme != None)
  347. {
  348. switch (keyboardScheme)
  349. {
  350. case None:
  351. keyboardScheme = scheme;
  352. default:
  353. keyboardScheme = Custom;
  354. }
  355. }
  356. }
  357.  
  358. /**
  359. * Sets all actions that pertain to the binder to trigger when the supplied keys are used.
  360. * If binder is a literal you can inline this
  361. */
  362. public function bindKeys(control:Control, keys:Array<FlxKey>)
  363. {
  364. inline forEachBound(control, (action, state) -> addKeys(action, keys, state));
  365. }
  366.  
  367. /**
  368. * Sets all actions that pertain to the binder to trigger when the supplied keys are used.
  369. * If binder is a literal you can inline this
  370. */
  371. public function unbindKeys(control:Control, keys:Array<FlxKey>)
  372. {
  373. inline forEachBound(control, (action, _) -> removeKeys(action, keys));
  374. }
  375.  
  376. inline static function addKeys(action:FlxActionDigital, keys:Array<FlxKey>, state:FlxInputState)
  377. {
  378. for (key in keys)
  379. action.addKey(key, state);
  380. }
  381.  
  382.  
  383. static function removeKeys(action:FlxActionDigital, keys:Array<FlxKey>)
  384. {
  385. var i = action.inputs.length;
  386. while (i-- > 0)
  387. {
  388. var input = action.inputs[i];
  389. if (input.device == KEYBOARD && keys.indexOf(cast input.inputID) != -1)
  390. action.remove(input);
  391. }
  392. }
  393.  
  394. public function setKeyboardScheme(scheme:KeyboardScheme, reset = true)
  395. {
  396.  
  397. if (reset)
  398. removeKeyboard();
  399.  
  400. keyboardScheme = scheme;
  401.  
  402. switch (scheme)
  403. {
  404. case Solo:
  405. inline bindKeys(Control.UP, [W, FlxKey.UP]);
  406. inline bindKeys(Control.DOWN, [S, FlxKey.DOWN]);
  407. inline bindKeys(Control.LEFT, [A, FlxKey.LEFT]);
  408. inline bindKeys(Control.RIGHT, [D, FlxKey.RIGHT]);
  409. inline bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]);
  410. inline bindKeys(Control.BACK, [BACKSPACE, ESCAPE]);
  411. inline bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]);
  412. inline bindKeys(Control.RESET, [R]);
  413. case Duo(true):
  414. inline bindKeys(Control.UP, [W]);
  415. inline bindKeys(Control.DOWN, [S]);
  416. inline bindKeys(Control.LEFT, [A]);
  417. inline bindKeys(Control.RIGHT, [D]);
  418. inline bindKeys(Control.ACCEPT, [G, Z]);
  419. inline bindKeys(Control.BACK, [H, X]);
  420. inline bindKeys(Control.PAUSE, [ONE]);
  421. inline bindKeys(Control.RESET, [R]);
  422. case Duo(false):
  423. inline bindKeys(Control.UP, [FlxKey.UP]);
  424. inline bindKeys(Control.DOWN, [FlxKey.DOWN]);
  425. inline bindKeys(Control.LEFT, [FlxKey.LEFT]);
  426. inline bindKeys(Control.RIGHT, [FlxKey.RIGHT]);
  427. inline bindKeys(Control.ACCEPT, [O]);
  428. inline bindKeys(Control.BACK, [P]);
  429. inline bindKeys(Control.PAUSE, [ENTER]);
  430. inline bindKeys(Control.RESET, [BACKSPACE]);
  431. case None: // nothing
  432. case Custom: // nothing
  433. }
  434. }
  435.  
  436. function removeKeyboard()
  437. {
  438. for (action in this.digitalActions)
  439. {
  440. var i = action.inputs.length;
  441. while (i-- > 0)
  442. {
  443. var input = action.inputs[i];
  444. if (input.device == KEYBOARD)
  445. action.remove(input);
  446. }
  447. }
  448. }
  449.  
  450. public function addGamepad(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
  451. {
  452. gamepadsAdded.push(id);
  453.  
  454. for (control => buttons in buttonMap)
  455. inline bindButtons(control, id, buttons);
  456. }
  457.  
  458. inline function addGamepadLiteral(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
  459. {
  460. gamepadsAdded.push(id);
  461.  
  462. for (control => buttons in buttonMap)
  463. inline bindButtons(control, id, buttons);
  464. }
  465.  
  466. public function removeGamepad(deviceID:Int = FlxInputDeviceID.ALL):Void
  467. {
  468. for (action in this.digitalActions)
  469. {
  470. var i = action.inputs.length;
  471. while (i-- > 0)
  472. {
  473. var input = action.inputs[i];
  474. if (input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID))
  475. action.remove(input);
  476. }
  477. }
  478.  
  479. gamepadsAdded.remove(deviceID);
  480. }
  481.  
  482. public function addDefaultGamepad(id):Void
  483. {
  484. addGamepadLiteral(id, [
  485. Control.ACCEPT => [A],
  486. Control.BACK => [B],
  487. Control.UP => [DPAD_UP, LEFT_STICK_DIGITAL_UP],
  488. Control.DOWN => [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN],
  489. Control.LEFT => [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT],
  490. Control.RIGHT => [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT],
  491. Control.PAUSE => [START],
  492. Control.RESET => [Y]
  493. ]);
  494. }
  495.  
  496.  
  497. /**
  498. * Sets all actions that pertain to the binder to trigger when the supplied keys are used.
  499. * If binder is a literal you can inline this
  500. */
  501. public function bindButtons(control:Control, id, buttons)
  502. {
  503. inline forEachBound(control, (action, state) -> addButtons(action, buttons, state, id));
  504. }
  505.  
  506. /**
  507. * Sets all actions that pertain to the binder to trigger when the supplied keys are used.
  508. * If binder is a literal you can inline this
  509. */
  510. public function unbindButtons(control:Control, gamepadID:Int, buttons)
  511. {
  512.  
  513. inline forEachBound(control, (action, _) -> removeButtons(action, gamepadID, buttons));
  514. }
  515.  
  516. inline static function addButtons(action:FlxActionDigital, buttons:Array<FlxGamepadInputID>, state, id)
  517. {
  518. for (button in buttons)
  519. action.addGamepad(button, state, id);
  520. }
  521.  
  522. static function removeButtons(action:FlxActionDigital, gamepadID:Int, buttons:Array<FlxGamepadInputID>)
  523. {
  524. var i = action.inputs.length;
  525. while (i-- > 0)
  526. {
  527. var input = action.inputs[i];
  528. if (isGamepad(input, gamepadID) && buttons.indexOf(cast input.inputID) != -1)
  529. action.remove(input);
  530. }
  531. }
  532.  
  533. public function getInputsFor(control:Control, device:Device, ?list:Array<Int>):Array<Int>
  534. {
  535. if (list == null)
  536. list = [];
  537.  
  538. switch (device)
  539. {
  540. case Keys:
  541. for (input in getActionFromControl(control).inputs)
  542. {
  543. if (input.device == KEYBOARD)
  544. list.push(input.inputID);
  545. }
  546. case Gamepad(id):
  547. for (input in getActionFromControl(control).inputs)
  548. {
  549. if (input.deviceID == id)
  550. list.push(input.inputID);
  551. }
  552. }
  553. return list;
  554. }
  555.  
  556. public function removeDevice(device:Device)
  557. {
  558. switch (device)
  559. {
  560. case Keys:
  561. setKeyboardScheme(None);
  562. case Gamepad(id):
  563. removeGamepad(id);
  564. }
  565. }
  566.  
  567. static function isDevice(input:FlxActionInput, device:Device)
  568. {
  569. return switch device
  570. {
  571. case Keys: input.device == KEYBOARD;
  572. case Gamepad(id): isGamepad(input, id);
  573. }
  574. }
  575.  
  576. inline static function isGamepad(input:FlxActionInput, deviceID:Int)
  577. {
  578. return input.device == GAMEPAD && (deviceID == FlxInputDeviceID.ALL || input.deviceID == deviceID);
  579. }
  580.  
  581. }
  582.  
  583.  
Advertisement
Add Comment
Please, Sign In to add comment