UNPKG

phaser3-merged-input

Version:

A Phaser 3 plugin to handle input from keyboard, gamepad & mouse, allowing for easy key definition and multiplayer input

1,202 lines (1,123 loc) 96.5 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("MergedInput", [], factory); else if(typeof exports === 'object') exports["MergedInput"] = factory(); else root["MergedInput"] = factory(); })(self, () => { return /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 348: /***/ ((module) => { /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** * Used internally by the KeyCombo class. * Return `true` if it reached the end of the combo, `false` if not. * * @function Phaser.Input.Keyboard.AdvanceKeyCombo * @private * @since 3.0.0 * * @param {KeyboardEvent} event - The native Keyboard Event. * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to advance. * * @return {boolean} `true` if it reached the end of the combo, `false` if not. */ var AdvanceKeyCombo = function (event, combo) { combo.timeLastMatched = event.timeStamp; combo.index++; if (combo.index === combo.size) { return true; } else { combo.current = combo.keyCodes[combo.index]; return false; } }; module.exports = AdvanceKeyCombo; /***/ }), /***/ 353: /***/ ((module) => { /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** * Used internally by the KeyCombo class. * * @function Phaser.Input.Keyboard.ResetKeyCombo * @private * @since 3.0.0 * * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo to reset. * * @return {Phaser.Input.Keyboard.KeyCombo} The KeyCombo. */ var ResetKeyCombo = function (combo) { combo.current = combo.keyCodes[0]; combo.index = 0; combo.timeLastMatched = 0; combo.matched = false; combo.timeMatched = 0; return combo; }; module.exports = ResetKeyCombo; /***/ }), /***/ 399: /***/ ((module) => { /** * Generic pad mapping */ module.exports = { padID: 'Xbox 360 controller (XInput STANDARD GAMEPAD)', padType: 'xbox', gamepadMapping: { RC_S: 0, RC_E: 1, RC_W: 2, RC_N: 3, START: 9, SELECT: 8, LB: 4, RB: 5, LT: 6, RT: 7, LS: 10, RS: 11, LC_N: 12, LC_S: 13, LC_W: 14, LC_E: 15, MENU: 16 } }; /***/ }), /***/ 436: /***/ ((module) => { /** * 081f-e401 - UnlicensedSNES */ module.exports = { padID: '081f-e401', padType: 'snes', gamepadMapping: { RC_S: 2, RC_E: 1, RC_W: 3, RC_N: 0, START: 9, SELECT: 8, LB: 4, RB: 5, LC_N: 12, LC_S: 13, LC_W: 14, LC_E: 15 } }; /***/ }), /***/ 518: /***/ ((module) => { /** * Generic pad mapping */ module.exports = { padID: 'Generic', padType: 'generic', gamepadMapping: { RC_S: 0, RC_E: 1, RC_W: 2, RC_N: 3, START: 9, SELECT: 8, LB: 4, RB: 5, LT: 6, RT: 7, LS: 10, RS: 11, LC_N: 12, LC_S: 13, LC_W: 14, LC_E: 15 } }; /***/ }), /***/ 635: /***/ ((module) => { /** * Dualshock mapping */ module.exports = { padID: 'Dualshock', padType: 'Sony', gamepadMapping: { RC_S: 0, RC_E: 1, RC_W: 2, RC_N: 3, START: 9, // Options SELECT: 8, // Share LB: 4, RB: 5, LT: 6, RT: 7, LS: 10, RS: 11, LC_N: 12, LC_S: 13, LC_W: 14, LC_E: 15, MENU: 16, TOUCH: 17 } }; /***/ }), /***/ 806: /***/ ((module) => { var bearings = { '-180': 'W', '-168.75': 'WBN', '-157.5': 'WNW', '-146.25': 'NWBW', '-135': 'NW', '-123.75': 'NWBN', '-112.5': 'NNW', '-101.25': 'NBW', '-90': 'N', '-78.75': 'NBE', '-67.5': 'NNE', '-56.25': 'NEBN', '-45': 'NE', '-33.75': 'NEBE', '-22.5': 'ENE', '-11.25': 'EBN', '0': 'E', '11.25': 'EBS', '22.5': 'ESE', '33.75': 'SEBE', '45': 'SE', '56.25': 'SEBS', '67.5': 'SSE', '78.75': 'SBE', '90': 'S', '101.25': 'SBW', '112.5': 'SSW', '123.75': 'SWBS', '135': 'SW', '146.25': 'SWBW', '157.5': 'WSW', '168.75': 'WBS', '180': 'W' }; module.exports = bearings; /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry needs to be wrapped in an IIFE because it needs to be in strict mode. (() => { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "default": () => (/* binding */ MergedInput) }); // EXTERNAL MODULE: ./configs/bearings.js var bearings = __webpack_require__(806); var bearings_default = /*#__PURE__*/__webpack_require__.n(bearings); // EXTERNAL MODULE: ./configs/pad_generic.js var pad_generic = __webpack_require__(518); var pad_generic_default = /*#__PURE__*/__webpack_require__.n(pad_generic); // EXTERNAL MODULE: ./configs/pad_unlicensedSNES.js var pad_unlicensedSNES = __webpack_require__(436); var pad_unlicensedSNES_default = /*#__PURE__*/__webpack_require__.n(pad_unlicensedSNES); // EXTERNAL MODULE: ./configs/pad_xbox360.js var pad_xbox360 = __webpack_require__(399); var pad_xbox360_default = /*#__PURE__*/__webpack_require__.n(pad_xbox360); // EXTERNAL MODULE: ./configs/pad_dualshock.js var pad_dualshock = __webpack_require__(635); var pad_dualshock_default = /*#__PURE__*/__webpack_require__.n(pad_dualshock); ;// ./controlManager.js function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } var controlManager = /*#__PURE__*/function () { function controlManager() { _classCallCheck(this, controlManager); } return _createClass(controlManager, [{ key: "mapGamepad", value: function mapGamepad(id) { id = id.toLowerCase(); var padConfig = (pad_generic_default()); if (id.includes('081f') && id.includes('e401')) { padConfig = (pad_unlicensedSNES_default()); } else if (id.includes('xbox') && id.includes('360')) { padConfig = (pad_xbox360_default()); } else if (id.includes('054c')) { padConfig = (pad_dualshock_default()); } else {} return padConfig; } }, { key: "getBaseControls", value: function getBaseControls() { return { 'direction': { 'UP': 0, 'DOWN': 0, 'LEFT': 0, 'RIGHT': 0, 'BEARING': '', 'BEARING_LAST': '', 'DEGREES': 0, 'DEGREES_LAST': 0, 'TIMESTAMP': 0 }, 'direction_secondary': { 'UP': 0, 'DOWN': 0, 'LEFT': 0, 'RIGHT': 0, 'BEARING': '', 'DEGREES': 0, 'BEARING_LAST': '', 'DEGREES_LAST': 0, 'TIMESTAMP': 0 }, 'buttons': {}, 'timers': {}, 'gamepadMapping': { RC_S: 0, RC_E: 1, RC_W: 2, RC_N: 3, START: 9, SELECT: 8, LB: 4, RB: 5, LT: 6, RT: 7, LS: 10, RS: 11, LC_N: 12, LC_S: 13, LC_W: 14, LC_E: 15, MENU: 16 }, 'pointer': { 'M1': 0, 'M2': 0, 'M3': 0, 'M4': 0, 'M5': 0, 'BEARING': '', 'BEARING_DEGREES': 0, 'ANGLE': 0, 'TIMESTAMP': 0 }, 'position': { x: 0, y: 0 }, 'position_last': { x: 0, y: 0 }, 'gamepad': {}, 'keys': { 'UP': [], 'DOWN': [], 'LEFT': [], 'RIGHT': [] }, 'internal': { 'fakedpadBuffer': [], 'fakedpadPressed': [], 'fakedpadReleased': [] }, 'interaction': { 'buffer': [], 'pressed': [], 'released': [], 'last': '', 'lastPressed': '', 'lastReleased': '', 'device': '' }, 'interaction_mapped': { 'pressed': [], 'released': [], 'last': '', 'lastPressed': '', 'lastReleased': '', 'gamepadType': '' }, 'buttons_mapped': { RC_S: 0, RC_E: 0, RC_W: 0, RC_N: 0, START: 0, SELECT: 0, MENU: 0, LB: 0, RB: 0, LT: 0, RT: 0, LS: 0, RS: 0, LC_N: 0, LC_S: 0, LC_W: 0, LC_E: 0 } }; } /** * Returns a struct to hold input control information * Set up a struct for each player in the game * Direction and Buttons contain the input from the devices * The keys struct contains arrays of keyboard characters that will trigger the action */ }, { key: "setupControls", value: function setupControls(numberOfButtons) { numberOfButtons = numberOfButtons || 16; var controls = this.getBaseControls(); // Add buttons for (var i = 0; i <= numberOfButtons; i++) { controls.buttons['B' + i] = 0; controls.keys['B' + i] = []; } // Add timers for (var _i = 0; _i <= numberOfButtons; _i++) { controls.timers['B' + _i] = { 'pressed': 0, 'released': 0, 'duration': 0 }; } for (var _i2 = 0, _arr = ['UP', 'DOWN', 'LEFT', 'RIGHT', 'ALT_UP', 'ALT_DOWN', 'ALT_LEFT', 'ALT_RIGHT']; _i2 < _arr.length; _i2++) { var thisDirection = _arr[_i2]; controls.timers[thisDirection] = { 'pressed': 0, 'released': 0, 'duration': 0 }; } for (var _i3 = 0, _arr2 = ['M1', 'M2', 'M3', 'M4', 'M5']; _i3 < _arr2.length; _i3++) { var thisPointer = _arr2[_i3]; controls.timers[thisPointer] = { 'pressed': 0, 'released': 0, 'duration': 0 }; } controls.setPosition = function (x, y) { this.position.x = x; this.position.y = y; }; return controls; } }]); }(); // EXTERNAL MODULE: ../node_modules/phaser/src/input/keyboard/combo/AdvanceKeyCombo.js var AdvanceKeyCombo = __webpack_require__(348); var AdvanceKeyCombo_default = /*#__PURE__*/__webpack_require__.n(AdvanceKeyCombo); // EXTERNAL MODULE: ../node_modules/phaser/src/input/keyboard/combo/ResetKeyCombo.js var ResetKeyCombo = __webpack_require__(353); var ResetKeyCombo_default = /*#__PURE__*/__webpack_require__.n(ResetKeyCombo); ;// ./ButtonCombo.js function ButtonCombo_typeof(o) { "@babel/helpers - typeof"; return ButtonCombo_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, ButtonCombo_typeof(o); } function ButtonCombo_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function ButtonCombo_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, ButtonCombo_toPropertyKey(o.key), o); } } function ButtonCombo_createClass(e, r, t) { return r && ButtonCombo_defineProperties(e.prototype, r), t && ButtonCombo_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function ButtonCombo_toPropertyKey(t) { var i = ButtonCombo_toPrimitive(t, "string"); return "symbol" == ButtonCombo_typeof(i) ? i : i + ""; } function ButtonCombo_toPrimitive(t, r) { if ("object" != ButtonCombo_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != ButtonCombo_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _possibleConstructorReturn(t, e) { if (e && ("object" == ButtonCombo_typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } function _get() { return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) { var p = _superPropBase(e, t); if (p) { var n = Object.getOwnPropertyDescriptor(p, t); return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value; } }, _get.apply(null, arguments); } function _superPropBase(t, o) { for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t));); return t; } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } var ButtonCombo = /*#__PURE__*/function (_Phaser$Input$Keyboar) { function ButtonCombo(mergedInput, player, buttons, config) { var _this; ButtonCombo_classCallCheck(this, ButtonCombo); _this = _callSuper(this, ButtonCombo, [mergedInput.systems.input.keyboard, buttons, config]); _this.player = player; _this.mergedInput = mergedInput; _this.keyCodes = buttons; // KeyCombo expects this to be an array of keycodes, we'll be checking against button names mergedInput.events.on('gamepad_buttondown', _this.onButtonDown, _this); _this.current = _this.keyCodes[0]; return _this; } _inherits(ButtonCombo, _Phaser$Input$Keyboar); return ButtonCombo_createClass(ButtonCombo, [{ key: "onButtonDown", value: function onButtonDown(event) { if (this.matched || !this.enabled) { return; } var matched = this.ProcessButtonCombo(event, this); if (matched) { this.mergedInput.eventEmitter.emit('mergedInput', { combo: this, player: this.player, action: 'Button combo matched' }); this.mergedInput.events.emit('buttoncombomatch', { player: this.player, combo: this }); if (this.resetOnMatch) { ResetKeyCombo_default()(this); } else if (this.deleteOnMatch) { this.destroy(); } } } }, { key: "ProcessButtonCombo", value: function ProcessButtonCombo(event, combo) { // Set a timestamp from the gamepad event.timeStamp = this.mergedInput.systems.time.now; // Don't check buttons on a different pad if (combo.player.index !== event.player) { return false; } // Check matched if (combo.matched) { return true; } // Compare the current action with the button pressed var buttonMatch = false; if (event.button === combo.current) { buttonMatch = true; } var mappedButton = this.mergedInput.getMappedButton(combo.player, event.button); if (mappedButton === combo.current) { buttonMatch = true; } var unMappedButton = this.mergedInput.getUnmappedButton(combo.player, mappedButton); if (unMappedButton === combo.current) { buttonMatch = true; } var comboMatched = false; var keyMatched = false; if (buttonMatch) { // Button was correct if (combo.index > 0 && combo.maxKeyDelay > 0) { // We have to check to see if the delay between // the new key and the old one was too long (if enabled) var timeLimit = combo.timeLastMatched + combo.maxKeyDelay; // Check if they pressed it in time or not if (event.timeStamp <= timeLimit) { keyMatched = true; comboMatched = AdvanceKeyCombo_default()(event, combo); } } else { keyMatched = true; // We don't check the time for the first key pressed, so just advance it comboMatched = AdvanceKeyCombo_default()(event, combo); } } if (!keyMatched && combo.resetOnWrongKey) { // Wrong key was pressed combo.index = 0; combo.current = combo.keyCodes[0]; } if (comboMatched) { combo.timeLastMatched = event.timeStamp; combo.matched = true; combo.timeMatched = event.timeStamp; } return comboMatched; } }, { key: "destroy", value: function destroy() { this.mergedInput.events.off('gamepad_buttondown', this.onButtonDown); _superPropGet(ButtonCombo, "destroy", this, 3)([]); } }]); }(Phaser.Input.Keyboard.KeyCombo); ;// ./main.js function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function main_typeof(o) { "@babel/helpers - typeof"; return main_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, main_typeof(o); } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function main_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function main_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, main_toPropertyKey(o.key), o); } } function main_createClass(e, r, t) { return r && main_defineProperties(e.prototype, r), t && main_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function main_toPropertyKey(t) { var i = main_toPrimitive(t, "string"); return "symbol" == main_typeof(i) ? i : i + ""; } function main_toPrimitive(t, r) { if ("object" != main_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != main_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function main_callSuper(t, o, e) { return o = main_getPrototypeOf(o), main_possibleConstructorReturn(t, main_isNativeReflectConstruct() ? Reflect.construct(o, e || [], main_getPrototypeOf(t).constructor) : o.apply(t, e)); } function main_possibleConstructorReturn(t, e) { if (e && ("object" == main_typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return main_assertThisInitialized(t); } function main_assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } function main_isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (main_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function main_getPrototypeOf(t) { return main_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, main_getPrototypeOf(t); } function main_inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && main_setPrototypeOf(t, e); } function main_setPrototypeOf(t, e) { return main_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, main_setPrototypeOf(t, e); } var MergedInput = /*#__PURE__*/function (_Phaser$Plugins$Scene) { /** * The Merged Input plugin is designed to run in the background and handle input. * Upon detecting a keypress or gamepad interaction, the plugin will update a player object and emit global events. * * @extends Phaser.Plugins.ScenePlugin * @param {*} scene * @param {*} pluginManager */ function MergedInput(scene, pluginManager) { var _this; main_classCallCheck(this, MergedInput); _this = main_callSuper(this, MergedInput, [scene, pluginManager]); _this.scene = scene; // Players _this.players = []; // Gamepads _this.gamepads = []; // Keys object to store Phaser key objects. We'll check these during update _this.keys = {}; _this.bearings = (bearings_default()); _this.dpadMappings = { 'UP': 12, 'DOWN': 13, 'LEFT': 14, 'RIGHT': 15 }; // A threshold (between 0 and 1) below which analog stick input will be ignored _this.axisThreshold = 0; // The number of directions to snap to when mapping input to bearings (Defaults to 32) _this.numDirections = Object.keys(_this.bearings).length - 1; _this.controlManager = new controlManager(); return _this; } main_inherits(MergedInput, _Phaser$Plugins$Scene); return main_createClass(MergedInput, [{ key: "boot", value: function boot() { var _this2 = this; // Scene event emitter this.eventEmitter = this.systems.events; // Plugin event emitter this.events = new Phaser.Events.EventEmitter(); this.game.events.on(Phaser.Core.Events.PRE_STEP, this.preupdate, this); this.game.events.on(Phaser.Core.Events.POST_STEP, this.postupdate, this); // Handle the game losing focus this.game.events.on(Phaser.Core.Events.BLUR, function () { _this2.loseFocus(); }); // Gamepad if (typeof this.systems.input.gamepad !== 'undefined') { this.systems.input.gamepad.on('connected', function (thisGamepad) { this.refreshGamepads(); this.setupGamepad(thisGamepad); }, this); // Check to see if the gamepad has already been setup by the browser this.systems.input.gamepad.refreshPads(); if (this.systems.input.gamepad.total) { this.refreshGamepads(); var _iterator = _createForOfIteratorHelper(this.gamepads), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var thisGamepad = _step.value; this.systems.input.gamepad.emit('connected', thisGamepad); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } this.systems.input.gamepad.on('down', this.gamepadButtonDown, this); this.systems.input.gamepad.on('up', this.gamepadButtonUp, this); } // Keyboard this.systems.input.keyboard.on('keydown', this.keyboardKeyDown, this); this.systems.input.keyboard.on('keyup', this.keyboardKeyUp, this); // Pointer this.systems.input.mouse.disableContextMenu(); } }, { key: "preupdate", value: function preupdate() { // If the first player has moved, we want to update the pointer position if (typeof this.players[0] !== 'undefined') { if (this.players[0].position.x !== this.players[0].position_last.x || this.players[0].position.y !== this.players[0].position_last.y) { this.pointerMove(this.systems.input.activePointer); } } this.players[0].position_last.x = this.players[0].position.x; this.players[0].position_last.y = this.players[0].position.y; this.checkKeyboardInput(); this.checkGamepadInput(); this.checkPointerInput(); // Loop through players and handle input var _iterator2 = _createForOfIteratorHelper(this.players), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var thisPlayer = _step2.value; // If the pointer hasn't moved, and the scene has changed, this can end up as undefined thisPlayer.pointer.BEARING = typeof thisPlayer.pointer.BEARING != 'undefined' ? thisPlayer.pointer.BEARING : ''; thisPlayer.pointer.BEARING_DEGREES = typeof thisPlayer.pointer.BEARING_DEGREES != 'undefined' ? thisPlayer.pointer.BEARING_DEGREES : 0; thisPlayer.pointer.ANGLE = typeof thisPlayer.pointer.ANGLE != 'undefined' ? thisPlayer.pointer.ANGLE : ''; thisPlayer.pointer.DEGREES = typeof thisPlayer.pointer.DEGREES != 'undefined' ? thisPlayer.pointer.DEGREES : 0; thisPlayer.pointer.POINTERANGLE = typeof thisPlayer.pointer.POINTERANGLE != 'undefined' ? thisPlayer.pointer.POINTERANGLE : ''; thisPlayer.pointer.POINTERDIRECTION = typeof thisPlayer.pointer.POINTERDIRECTION != 'undefined' ? thisPlayer.pointer.POINTERDIRECTION : ''; thisPlayer.pointer.PLAYERPOS = typeof thisPlayer.pointer.PLAYERPOS != 'undefined' ? thisPlayer.pointer.PLAYERPOS : ''; thisPlayer.direction.ANGLE = this.mapDirectionsToAngle(thisPlayer.direction); thisPlayer.direction.ANGLE_LAST = thisPlayer.direction.ANGLE != '' ? thisPlayer.direction.ANGLE : thisPlayer.direction.ANGLE_LAST; thisPlayer.direction.DEGREES = thisPlayer.direction.ANGLE !== -1 ? Math.round(Phaser.Math.RadToDeg(thisPlayer.direction.ANGLE) * 100) / 100 : -1; thisPlayer.direction.DEGREES_LAST = thisPlayer.direction.DEGREES != -1 ? thisPlayer.direction.DEGREES : thisPlayer.direction.DEGREES_LAST; thisPlayer.direction.BEARING = thisPlayer.direction.ANGLE !== -1 ? this.getBearingFromAngle(thisPlayer.direction.ANGLE) : ''; thisPlayer.direction.BEARING_LAST = thisPlayer.direction.BEARING != '' ? thisPlayer.direction.BEARING : thisPlayer.direction.BEARING_LAST; thisPlayer.direction.BEARING_DEGREES = thisPlayer.direction.BEARING != '' ? parseFloat(this.mapBearingToDegrees(thisPlayer.direction.BEARING)) : 0; thisPlayer.direction.BEARING_DEGREES_LAST = thisPlayer.direction.BEARING_LAST != '' ? parseFloat(this.mapBearingToDegrees(thisPlayer.direction.BEARING_LAST)) : 0; thisPlayer.direction_secondary.ANGLE = this.mapDirectionsToAngle(thisPlayer.direction_secondary); thisPlayer.direction_secondary.ANGLE_LAST = thisPlayer.direction_secondary.ANGLE != '' ? thisPlayer.direction_secondary.ANGLE : thisPlayer.direction_secondary.ANGLE_LAST; thisPlayer.direction_secondary.DEGREES = thisPlayer.direction_secondary.ANGLE !== -1 ? Math.round(Phaser.Math.RadToDeg(thisPlayer.direction_secondary.ANGLE) * 100) / 100 : -1; thisPlayer.direction_secondary.DEGREES_LAST = thisPlayer.direction_secondary.DEGREES != -1 ? thisPlayer.direction_secondary.DEGREES : thisPlayer.direction_secondary.DEGREES_LAST; thisPlayer.direction_secondary.BEARING = thisPlayer.direction_secondary.ANGLE !== -1 ? this.getBearingFromAngle(thisPlayer.direction_secondary.ANGLE) : ''; thisPlayer.direction_secondary.BEARING_LAST = thisPlayer.direction_secondary.BEARING != '' ? thisPlayer.direction_secondary.BEARING : thisPlayer.direction_secondary.BEARING_LAST; thisPlayer.direction_secondary.BEARING_DEGREES = thisPlayer.direction_secondary.BEARING != '' ? parseFloat(this.mapBearingToDegrees(thisPlayer.direction_secondary.BEARING)) : 0; thisPlayer.direction_secondary.BEARING_DEGREES_LAST = thisPlayer.direction_secondary.BEARING_LAST != '' ? parseFloat(this.mapBearingToDegrees(thisPlayer.direction_secondary.BEARING_LAST)) : 0; } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } } }, { key: "postupdate", value: function postupdate() { // Loop through players and manage buffered input var _iterator3 = _createForOfIteratorHelper(this.players), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var thisPlayer = _step3.value; // Clear the interaction buffer this.clearBuffer(thisPlayer); } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } } /** * Clear the interaction buffer for the given player * In the case of 'fake' DPad presses, we're using some convoluted buffers to keep the 'pressed' and 'released' values around for an extra tick * As they're created in this update loop, they're otherwise cleared before the consumer can use them. * @param {*} thisPlayer */ }, { key: "clearBuffer", value: function clearBuffer(thisPlayer) { if (thisPlayer.interaction.pressed.length > 0 && thisPlayer.internal.fakedpadPressed.length == 0) { thisPlayer.interaction.buffer = []; } if (thisPlayer.interaction.buffer.length == 0) { thisPlayer.interaction.pressed = []; thisPlayer.interaction_mapped.pressed = []; if (thisPlayer.internal.fakedpadReleased.length == 0) { thisPlayer.interaction.released = []; thisPlayer.interaction_mapped.released = []; } } thisPlayer.internal.fakedpadPressed = []; thisPlayer.internal.fakedpadReleased = []; } /** * Function to run when the game loses focus * We want to fake releasing the buttons here, so that they're not stuck down without an off event when focus returns to the game */ }, { key: "loseFocus", value: function loseFocus() { // Loop through defined keys and reset them for (var thisKey in this.keys) { this.keys[thisKey].reset(); } } /** * Set up the gamepad and associate with a player object */ }, { key: "setupGamepad", value: function setupGamepad(thisGamepad) { this.eventEmitter.emit('mergedInput', { device: 'gamepad', id: thisGamepad.id, player: thisGamepad.index, action: 'Connected' }); this.events.emit('gamepad_connected', thisGamepad); if (typeof this.players[thisGamepad.index] === 'undefined') { this.addPlayer(); } var gamepadID = thisGamepad.id.toLowerCase(); this.players[thisGamepad.index].gamepad = thisGamepad; // Map the gamepad buttons var mappedPad = this.controlManager.mapGamepad(gamepadID); this.players[thisGamepad.index].gamepadMapping = mappedPad.gamepadMapping; this.players[thisGamepad.index].interaction_mapped.gamepadType = mappedPad.padType; for (var thisButton in this.players[thisGamepad.index].gamepadMapping) { this.players[thisGamepad.index].buttons_mapped[thisButton] = 0; } } /** * Set a threshold (between 0 and 1) below which analog stick input will be ignored * @param {*} value * @returns */ }, { key: "setAxisThreshold", value: function setAxisThreshold(value) { this.axisThreshold = value; return this; } /** * Set the number of directions to snap to when mapping input to bearings */ }, { key: "setNumDirections", value: function setNumDirections(value) { if (typeof value === 'number' && value > 0) { this.numDirections = value; } return this; } }, { key: "refreshGamepads", value: function refreshGamepads() { // Sometimes, gamepads are undefined. For some reason. this.gamepads = this.systems.input.gamepad.gamepads.filter(function (el) { return el != null; }); var _iterator4 = _createForOfIteratorHelper(this.gamepads.entries()), _step4; try { for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { var _step4$value = _slicedToArray(_step4.value, 2), index = _step4$value[0], thisGamepad = _step4$value[1]; thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier /** * Some cheap gamepads use the first axis as a dpad, in which case we won't have the dpad buttons 12-15 */ thisGamepad.fakedpad = thisGamepad.buttons.length < 15; } } catch (err) { _iterator4.e(err); } finally { _iterator4.f(); } } /** * Add a new player object to the players array * @param {number} index Player index - if a player object at this index already exists, it will be returned instead of creating a new player object * @param {number} numberOfButtons The number of buttons to assign to the player object. Defaults to 16. Fewer than 16 is not recommended, as gamepad DPads typically map to buttons 12-15 */ }, { key: "addPlayer", value: function addPlayer(index, numberOfButtons) { numberOfButtons = numberOfButtons || 16; if (main_typeof(Number.isInteger(index)) && typeof this.players[index] !== 'undefined') { return this.players[index]; } else { // Set up player object var newPlayer = this.controlManager.setupControls(numberOfButtons); // Add helper functions to the player object this.addPlayerHelperFunctions(newPlayer); // Push new player to players array this.players.push(newPlayer); this.players[this.players.length - 1].index = this.players.length - 1; // If this is the first player, add the pointer events if (this.players.length == 1) { this.systems.input.on('pointermove', function (pointer) { this.pointerMove(pointer); }, this); this.systems.input.on('pointerdown', function (pointer) { this.pointerDown(pointer); }, this); this.systems.input.on('pointerup', function (pointer) { this.pointerUp(pointer); }, this); } return this.players[this.players.length - 1]; } } /** * Add helper functions to the player object * @param {*} player */ }, { key: "addPlayerHelperFunctions", value: function addPlayerHelperFunctions(player) { var _this3 = this; /** * Pass a button name, or an array of button names to check if any were pressed in this update step. * This will only fire once per button press. If you need to check for a button being held down, use isDown instead. * Returns the name of the matched button(s), in case you need it. */ player.interaction.isPressed = function (button) { button = typeof button === 'string' ? Array(button) : button; var matchedButtons = button.filter(function (x) { return player.interaction.pressed.includes(x); }); return matchedButtons.length ? matchedButtons : false; }, /** * Pass a button name, or an array of button names to check if any are currently pressed in this update step. * This differs from the isPressed function in that it will return true if the button is currently pressed, even if it was pressed in a previous update step. * Returns the name of the matched button(s), in case you need it. */ player.interaction.isDown = function (button) { button = typeof button === 'string' ? Array(button) : button; var matchedButtons = button.filter(function (x) { return player.buttons[x]; }); var matchedDirections = button.filter(function (x) { return player.direction[x]; }); var matchedPointer = button.filter(function (x) { return player.pointer[x]; }); var matchedAll = [].concat(_toConsumableArray(matchedButtons), _toConsumableArray(matchedDirections), _toConsumableArray(matchedPointer)); return matchedAll.length ? matchedAll : false; }, /** * Pass a button name, or an array of button names to check if any were released in this update step. * Returns the name of the matched button(s), in case you need it. */ player.interaction.isReleased = function (button) { button = typeof button === 'string' ? Array(button) : button; var matchedButtons = button.filter(function (x) { return player.interaction.released.includes(x); }); return matchedButtons.length ? matchedButtons : false; }; /** * Pass a mapped button name, or an array of mapped button names to check if any were pressed in this update step. * This will only fire once per button press. If you need to check for a button being held down, use isDown instead. * Returns the name of the matched mapped button(s), in case you need it. */ player.interaction_mapped.isPressed = function (button) { button = typeof button === 'string' ? Array(button) : button; var matchedButtons = button.filter(function (x) { return player.interaction_mapped.pressed.includes(x); }); return matchedButtons.length ? matchedButtons : false; }, /** * Pass a mapped button name, or an array of mapped button names to check if any are currently pressed in this update step. * This differs from the isPressed function in that it will return true if the button is currently pressed, even if it was pressed in a previous update step. * Returns the name of the matched button(s), in case you need it. */ player.interaction_mapped.isDown = function (button) { button = typeof button === 'string' ? Array(button) : button; var matchedButtons = button.filter(function (x) { return player.buttons_mapped[x]; }); return matchedButtons.length ? matchedButtons : false; }, /** * Pass a mapped button name, or an array of mapped button names to check if any were released in this update step. * Returns the name of the matched mapped button(s), in case you need it. */ player.interaction_mapped.isReleased = function (button) { button = typeof button === 'string' ? Array(button) : button; var matchedButtons = button.filter(function (x) { return player.interaction_mapped.released.includes(x); }); return matchedButtons.length ? matchedButtons : false; }; /** * Pass a button name, or an array of button names to check if any are currently pressed in this update step. * Similar to Phaser's keyboard plugin, the checkDown function can accept a 'duration' parameter, and will only register a press once every X milliseconds. * Returns the name of the matched button(s) * * @param {string|array} button Array of buttons to check * @param {number} duration The duration which must have elapsed before this button is considered as being down. * @param {boolean} includeFirst - When true, the initial press of the button will be included in the results. Defaults to false. */ player.interaction.checkDown = function (button, duration, includeFirst) { if (includeFirst === undefined) { includeFirst = false; } if (duration === undefined) { duration = 0; } var matchedButtons = []; var downButtons = player.interaction.isDown(button); if (downButtons.length) { var _iterator5 = _createForOfIteratorHelper(downButtons), _step5; try { var _loop = function _loop() { var thisButton = _step5.value; if (typeof player.timers[thisButton]._tick === 'undefined') { player.timers[thisButton]._tick = 0; if (includeFirst) { matchedButtons.push(thisButton); } } var t = Phaser.Math.Snap.Floor(_this3.scene.sys.time.now - player.timers[thisButton].pressed, duration); if (t > player.timers[thisButton]._tick) { _this3.game.events.once(Phaser.Core.Events.POST_STEP, function () { player.timers[thisButton]._tick = t; }); matchedButtons.push(thisButton); } }; for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { _loop(); } } catch (err) { _iterator5.e(err); } finally { _iterator5.f(); } } return matchedButtons.length ? matchedButtons : false; }, /** * Mapped version of the checkDown version - resolves mapped button names and calls the checkDown function */ player.interaction_mapped.checkDown = function (button, duration, includeFirst) { if (includeFirst === undefined) { includeFirst = false; } var unmappedButtons = []; // Resolve the unmapped button names to a new array var _iterator6 = _createForOfIteratorHelper(button), _step6; try { for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { var thisButton = _step6.value; var unmappedButton = _this3.getUnmappedButton(player, thisButton); if (unmappedButton) { unmappedButtons.push(unmappedButton); } } } catch (err) { _iterator6.e(err); } finally { _iterator6.f(); } var downButtons = player.interaction.checkDown(unmappedButtons, duration, includeFirst); return downButtons.length ? downButtons.map(function (x) { return _this3.getMappedButton(player, x); }) : false; }; /** * The previous functions are specific to the interaction and interaction_mapped definition of buttons. * In general you would pick a definition scheme and query that object (interaction or interaction_mapped), just for ease though, we'll add some functions that accept either type of convention */ /** * Pass a button name, or an array of button names to check if any were pressed in