DelayNoMore/frontend/assets/scripts/modules/Collisions.js

197 lines
56 KiB
JavaScript
Raw Normal View History

/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/Collisions.mjs");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./src/Collisions.mjs":
/*!****************************!*\
!*** ./src/Collisions.mjs ***!
\****************************/
/*! no exports provided */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _modules_BVH_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modules/BVH.mjs */ \"./src/modules/BVH.mjs\");\n/* harmony import */ var _modules_Circle_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/Circle.mjs */ \"./src/modules/Circle.mjs\");\n/* harmony import */ var _modules_Polygon_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modules/Polygon.mjs */ \"./src/modules/Polygon.mjs\");\n/* harmony import */ var _modules_Point_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/Point.mjs */ \"./src/modules/Point.mjs\");\n/* harmony import */ var _modules_Result_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modules/Result.mjs */ \"./src/modules/Result.mjs\");\n/* harmony import */ var _modules_SAT_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./modules/SAT.mjs */ \"./src/modules/SAT.mjs\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * A collision system used to track bodies in order to improve collision detection performance\r\n * @class\r\n */\r\nclass Collisions {\r\n\t/**\r\n\t * @constructor\r\n\t */\r\n\tconstructor() {\r\n\t\t/** @private */\r\n\t\tthis._bvh = new _modules_BVH_mjs__WEBPACK_IMPORTED_MODULE_0__[\"default\"]();\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link Circle} and inserts it into the collision system\r\n\t * @param {Number} [x = 0] The starting X coordinate\r\n\t * @param {Number} [y = 0] The starting Y coordinate\r\n\t * @param {Number} [radius = 0] The radius\r\n\t * @param {Number} [scale = 1] The scale\r\n\t * @param {Number} [padding = 0] The amount to pad the bounding volume when testing for potential collisions\r\n\t * @returns {Circle}\r\n\t */\r\n\tcreateCircle(x = 0, y = 0, radius = 0, scale = 1, padding = 0) {\r\n\t\tconst body = new _modules_Circle_mjs__WEBPACK_IMPORTED_MODULE_1__[\"default\"](x, y, radius, scale, padding);\r\n\r\n\t\tthis._bvh.insert(body);\r\n\r\n\t\treturn body;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link Polygon} and inserts it into the collision system\r\n\t * @param {Number} [x = 0] The starting X coordinate\r\n\t * @param {Number} [y = 0] The starting Y coordinate\r\n\t * @param {Array<Number[]>} [points = []] An array of coordinate pairs making up the polygon - [[x1, y1], [x2, y2], ...]\r\n\t * @param {Number} [angle = 0] The starting rotation in radians\r\n\t * @param {Number} [scale_x = 1] The starting scale along the X axis\r\n\t * @param {Number} [scale_y = 1] The starting scale long the Y axis\r\n\t * @param {Number} [padding = 0] The amount to pad the bounding volume when testing for potential collisions\r\n\t * @returns {Polygon}\r\n\t */\r\n\tcreatePolygon(x = 0, y = 0, points = [[0, 0]], angle = 0, scale_x = 1, scale_y = 1, padding = 0) {\r\n\t\tconst body = new _modules_Polygon_mjs__WEBPACK_IMPORTED_MODULE_2__[\"default\"](x, y, points, angle, scale_x, scale_y, padding);\r\n\r\n\t\tthis._bvh.insert(body);\r\n\r\n\t\treturn body;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link Point} and inserts it into the collision system\r\n\t * @param {Number} [x = 0] The starting X coordinate\r\n\t * @param {Number} [y = 0] The starting Y coordinate\r\n\t * @param {Number} [padding = 0] The amount to pad the bounding volume when testing for potential collisions\r\n\t * @returns {Point}\r\n\t */\r\n\tcreatePoint(x = 0, y = 0, padding = 0) {\r\n\t\tconst body = new _modules_Point_mjs__WEBPACK_IMPORTED_MODULE_3__[\"default\"](x, y, padding);\r\n\r\n\t\tthis._bvh.insert(body);\r\n\r\n\t\treturn body;\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link Result} used to collect the detailed results of a collision test\r\n\t */\r\n\tcreateResult() {\r\n\t\treturn new _modules_Result_mjs__WEBPACK_IMPORTED_MODULE_4__[\"default\"]();\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a Result used to collect the detailed results of a collision test\r\n\t */\r\n\tstatic createResult() {\r\n\t\treturn new _modules_Result_mjs__WEBPACK_IMPORTED_MODULE_4__[\"default\"]();\r\n\t}\r\n\r\n\t/**\r\n\t * Inserts bodies into the collision system\r\n\t
/***/ }),
/***/ "./src/modules/BVH.mjs":
/*!*****************************!*\
!*** ./src/modules/BVH.mjs ***!
\*****************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return BVH; });\n/* harmony import */ var _BVHBranch_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BVHBranch.mjs */ \"./src/modules/BVHBranch.mjs\");\n\r\n\r\n/**\r\n * A Bounding Volume Hierarchy (BVH) used to find potential collisions quickly\r\n * @class\r\n * @private\r\n */\r\nclass BVH {\r\n\t/**\r\n\t * @constructor\r\n\t */\r\n\tconstructor() {\r\n\t\t/** @private */\r\n\t\tthis._hierarchy = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bodies = [];\r\n\r\n\t\t/** @private */\r\n\t\tthis._dirty_branches = [];\r\n\t}\r\n\r\n\t/**\r\n\t * Inserts a body into the BVH\r\n\t * @param {Circle|Polygon|Point} body The body to insert\r\n\t * @param {Boolean} [updating = false] Set to true if the body already exists in the BVH (used internally when updating the body's position)\r\n\t */\r\n\tinsert(body, updating = false) {\r\n\t\tif(!updating) {\r\n\t\t\tconst bvh = body._bvh;\r\n\r\n\t\t\tif(bvh && bvh !== this) {\r\n\t\t\t\tthrow new Error('Body belongs to another collision system');\r\n\t\t\t}\r\n\r\n\t\t\tbody._bvh = this;\r\n\t\t\tthis._bodies.push(body);\r\n\t\t}\r\n\r\n\t\tconst polygon = body._polygon;\r\n\t\tconst body_x = body.x;\r\n\t\tconst body_y = body.y;\r\n\r\n\t\tif(polygon) {\r\n\t\t\tif(\r\n\t\t\t\tbody._dirty_coords ||\r\n\t\t\t\tbody.x !== body._x ||\r\n\t\t\t\tbody.y !== body._y ||\r\n\t\t\t\tbody.angle !== body._angle ||\r\n\t\t\t\tbody.scale_x !== body._scale_x ||\r\n\t\t\t\tbody.scale_y !== body._scale_y\r\n\t\t\t) {\r\n\t\t\t\tbody._calculateCoords();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst padding = body._bvh_padding;\r\n\t\tconst radius = polygon ? 0 : body.radius * body.scale;\r\n\t\tconst body_min_x = (polygon ? body._min_x : body_x - radius) - padding;\r\n\t\tconst body_min_y = (polygon ? body._min_y : body_y - radius) - padding;\r\n\t\tconst body_max_x = (polygon ? body._max_x : body_x + radius) + padding;\r\n\t\tconst body_max_y = (polygon ? body._max_y : body_y + radius) + padding;\r\n\r\n\t\tbody._bvh_min_x = body_min_x;\r\n\t\tbody._bvh_min_y = body_min_y;\r\n\t\tbody._bvh_max_x = body_max_x;\r\n\t\tbody._bvh_max_y = body_max_y;\r\n\r\n\t\tlet current = this._hierarchy;\r\n\t\tlet sort = 0;\r\n\r\n\t\tif(!current) {\r\n\t\t\tthis._hierarchy = body;\r\n\t\t}\r\n\t\telse {\r\n\t\t\twhile(true) {\r\n\t\t\t\t// Branch\r\n\t\t\t\tif(current._bvh_branch) {\r\n\t\t\t\t\tconst left = current._bvh_left;\r\n\t\t\t\t\tconst left_min_y = left._bvh_min_y;\r\n\t\t\t\t\tconst left_max_x = left._bvh_max_x;\r\n\t\t\t\t\tconst left_max_y = left._bvh_max_y;\r\n\t\t\t\t\tconst left_new_min_x = body_min_x < left._bvh_min_x ? body_min_x : left._bvh_min_x;\r\n\t\t\t\t\tconst left_new_min_y = body_min_y < left_min_y ? body_min_y : left_min_y;\r\n\t\t\t\t\tconst left_new_max_x = body_max_x > left_max_x ? body_max_x : left_max_x;\r\n\t\t\t\t\tconst left_new_max_y = body_max_y > left_max_y ? body_max_y : left_max_y;\r\n\t\t\t\t\tconst left_volume = (left_max_x - left._bvh_min_x) * (left_max_y - left_min_y);\r\n\t\t\t\t\tconst left_new_volume = (left_new_max_x - left_new_min_x) * (left_new_max_y - left_new_min_y);\r\n\t\t\t\t\tconst left_difference = left_new_volume - left_volume;\r\n\r\n\t\t\t\t\tconst right = current._bvh_right;\r\n\t\t\t\t\tconst right_min_x = right._bvh_min_x;\r\n\t\t\t\t\tconst right_min_y = right._bvh_min_y;\r\n\t\t\t\t\tconst right_max_x = right._bvh_max_x;\r\n\t\t\t\t\tconst right_max_y = right._bvh_max_y;\r\n\t\t\t\t\tconst right_new_min_x = body_min_x < right_min_x ? body_min_x : right_min_x;\r\n\t\t\t\t\tconst right_new_min_y = body_min_y < right_min_y ? body_min_y : right_min_y;\r\n\t\t\t\t\tconst right_new_max_x = body_max_x > right_max_x ? body_max_x : right_max_x;\r\n\t\t\t\t\tconst right_new_max_y = body_max_y > right_max_y ? body_max_y : right_max_y;\r\n\t\t\t\t\tconst right_volume = (right_max_x - right_min_x) * (right_ma
/***/ }),
/***/ "./src/modules/BVHBranch.mjs":
/*!***********************************!*\
!*** ./src/modules/BVHBranch.mjs ***!
\***********************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return BVHBranch; });\n/**\r\n * @private\r\n */\r\nconst branch_pool = [];\r\n\r\n/**\r\n * A branch within a BVH\r\n * @class\r\n * @private\r\n */\r\nclass BVHBranch {\r\n\t/**\r\n\t * @constructor\r\n\t */\r\n\tconstructor() {\r\n\t\t/** @private */\r\n\t\tthis._bvh_parent = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_branch = true;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_left = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_right = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_sort = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_min_x = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_min_y = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_max_x = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_max_y = 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns a branch from the branch pool or creates a new branch\r\n\t * @returns {BVHBranch}\r\n\t */\r\n\tstatic getBranch() {\r\n\t\tif(branch_pool.length) {\r\n\t\t\treturn branch_pool.pop();\r\n\t\t}\r\n\r\n\t\treturn new BVHBranch();\r\n\t}\r\n\r\n\t/**\r\n\t * Releases a branch back into the branch pool\r\n\t * @param {BVHBranch} branch The branch to release\r\n\t */\r\n\tstatic releaseBranch(branch) {\r\n\t\tbranch_pool.push(branch);\r\n\t}\r\n\r\n\t/**\r\n\t * Sorting callback used to sort branches by deepest first\r\n\t * @param {BVHBranch} a The first branch\r\n\t * @param {BVHBranch} b The second branch\r\n\t * @returns {Number}\r\n\t */\r\n\tstatic sortBranches(a, b) {\r\n\t\treturn a.sort > b.sort ? -1 : 1;\r\n\t}\r\n};\r\n\n\n//# sourceURL=webpack:///./src/modules/BVHBranch.mjs?");
/***/ }),
/***/ "./src/modules/Body.mjs":
/*!******************************!*\
!*** ./src/modules/Body.mjs ***!
\******************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Body; });\n/* harmony import */ var _Result_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Result.mjs */ \"./src/modules/Result.mjs\");\n/* harmony import */ var _SAT_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SAT.mjs */ \"./src/modules/SAT.mjs\");\n\r\n\r\n\r\n/**\r\n * The base class for bodies used to detect collisions\r\n * @class\r\n * @protected\r\n */\r\nclass Body {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Number} [x = 0] The starting X coordinate\r\n\t * @param {Number} [y = 0] The starting Y coordinate\r\n\t * @param {Number} [padding = 0] The amount to pad the bounding volume when testing for potential collisions\r\n\t */\r\n\tconstructor(x = 0, y = 0, padding = 0) {\r\n\t\t/**\r\n\t\t * @desc The X coordinate of the body\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.x = x;\r\n\r\n\t\t/**\r\n\t\t * @desc The Y coordinate of the body\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.y = y;\r\n\r\n\t\t/**\r\n\t\t * @desc The amount to pad the bounding volume when testing for potential collisions\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.padding = padding;\r\n\r\n\t\t/** @private */\r\n\t\tthis._circle = false;\r\n\r\n\t\t/** @private */\r\n\t\tthis._polygon = false;\r\n\r\n\t\t/** @private */\r\n\t\tthis._point = false;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_parent = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_branch = false;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_padding = padding;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_min_x = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_min_y = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_max_x = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._bvh_max_y = 0;\r\n\t}\r\n\r\n\t/**\r\n\t * Determines if the body is colliding with another body\r\n\t * @param {Circle|Polygon|Point} target The target body to test against\r\n\t * @param {Result} [result = null] A Result object on which to store information about the collision\r\n\t * @param {Boolean} [aabb = true] Set to false to skip the AABB test (useful if you use your own potential collision heuristic)\r\n\t * @returns {Boolean}\r\n\t */\r\n\tcollides(target, result = null, aabb = true) {\r\n\t\treturn Object(_SAT_mjs__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(this, target, result, aabb);\r\n\t}\r\n\r\n\t/**\r\n\t * Returns a list of potential collisions\r\n\t * @returns {Array<Body>}\r\n\t */\r\n\tpotentials() {\r\n\t\tconst bvh = this._bvh;\r\n\r\n\t\tif(bvh === null) {\r\n\t\t\tthrow new Error('Body does not belong to a collision system');\r\n\t\t}\r\n\r\n\t\treturn bvh.potentials(this);\r\n\t}\r\n\r\n\t/**\r\n\t * Removes the body from its current collision system\r\n\t */\r\n\tremove() {\r\n\t\tconst bvh = this._bvh;\r\n\r\n\t\tif(bvh) {\r\n\t\t\tbvh.remove(this, false);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a {@link Result} used to collect the detailed results of a collision test\r\n\t */\r\n\tcreateResult() {\r\n\t\treturn new _Result_mjs__WEBPACK_IMPORTED_MODULE_0__[\"default\"]();\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a Result used to collect the detailed results of a collision test\r\n\t */\r\n\tstatic createResult() {\r\n\t\treturn new _Result_mjs__WEBPACK_IMPORTED_MODULE_0__[\"default\"]();\r\n\t}\r\n};\r\n\n\n//# sourceURL=webpack:///./src/modules/Body.mjs?");
/***/ }),
/***/ "./src/modules/Circle.mjs":
/*!********************************!*\
!*** ./src/modules/Circle.mjs ***!
\********************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Circle; });\n/* harmony import */ var _Body_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Body.mjs */ \"./src/modules/Body.mjs\");\n\r\n\r\n/**\r\n * A circle used to detect collisions\r\n * @class\r\n */\r\nclass Circle extends _Body_mjs__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Number} [x = 0] The starting X coordinate\r\n\t * @param {Number} [y = 0] The starting Y coordinate\r\n\t * @param {Number} [radius = 0] The radius\r\n\t * @param {Number} [scale = 1] The scale\r\n\t * @param {Number} [padding = 0] The amount to pad the bounding volume when testing for potential collisions\r\n\t */\r\n\tconstructor(x = 0, y = 0, radius = 0, scale = 1, padding = 0) {\r\n\t\tsuper(x, y, padding);\r\n\r\n\t\t/**\r\n\t\t * @desc\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.radius = radius;\r\n\r\n\t\t/**\r\n\t\t * @desc\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.scale = scale;\r\n\t}\r\n\r\n\t/**\r\n\t * Draws the circle to a CanvasRenderingContext2D's current path\r\n\t * @param {CanvasRenderingContext2D} context The context to add the arc to\r\n\t */\r\n\tdraw(context) {\r\n\t\tconst x = this.x;\r\n\t\tconst y = this.y;\r\n\t\tconst radius = this.radius * this.scale;\r\n\r\n\t\tcontext.moveTo(x + radius, y);\r\n\t\tcontext.arc(x, y, radius, 0, Math.PI * 2);\r\n\t}\r\n};\r\n\n\n//# sourceURL=webpack:///./src/modules/Circle.mjs?");
/***/ }),
/***/ "./src/modules/Point.mjs":
/*!*******************************!*\
!*** ./src/modules/Point.mjs ***!
\*******************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Point; });\n/* harmony import */ var _Polygon_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Polygon.mjs */ \"./src/modules/Polygon.mjs\");\n\r\n\r\n/**\r\n * A point used to detect collisions\r\n * @class\r\n */\r\nclass Point extends _Polygon_mjs__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Number} [x = 0] The starting X coordinate\r\n\t * @param {Number} [y = 0] The starting Y coordinate\r\n\t * @param {Number} [padding = 0] The amount to pad the bounding volume when testing for potential collisions\r\n\t */\r\n\tconstructor(x = 0, y = 0, padding = 0) {\r\n\t\tsuper(x, y, [[0, 0]], 0, 1, 1, padding);\r\n\r\n\t\t/** @private */\r\n\t\tthis._point = true;\r\n\t}\r\n};\r\n\r\nPoint.prototype.setPoints = undefined;\r\n\n\n//# sourceURL=webpack:///./src/modules/Point.mjs?");
/***/ }),
/***/ "./src/modules/Polygon.mjs":
/*!*********************************!*\
!*** ./src/modules/Polygon.mjs ***!
\*********************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Polygon; });\n/* harmony import */ var _Body_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Body.mjs */ \"./src/modules/Body.mjs\");\n\r\n\r\n/**\r\n * A polygon used to detect collisions\r\n * @class\r\n */\r\nclass Polygon extends _Body_mjs__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\r\n\t/**\r\n\t * @constructor\r\n\t * @param {Number} [x = 0] The starting X coordinate\r\n\t * @param {Number} [y = 0] The starting Y coordinate\r\n\t * @param {Array<Number[]>} [points = []] An array of coordinate pairs making up the polygon - [[x1, y1], [x2, y2], ...]\r\n\t * @param {Number} [angle = 0] The starting rotation in radians\r\n\t * @param {Number} [scale_x = 1] The starting scale along the X axis\r\n\t * @param {Number} [scale_y = 1] The starting scale long the Y axis\r\n\t * @param {Number} [padding = 0] The amount to pad the bounding volume when testing for potential collisions\r\n\t */\r\n\tconstructor(x = 0, y = 0, points = [], angle = 0, scale_x = 1, scale_y = 1, padding = 0) {\r\n\t\tsuper(x, y, padding);\r\n\r\n\t\t/**\r\n\t\t * @desc The angle of the body in radians\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.angle = angle;\r\n\r\n\t\t/**\r\n\t\t * @desc The scale of the body along the X axis\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.scale_x = scale_x;\r\n\r\n\t\t/**\r\n\t\t * @desc The scale of the body along the Y axis\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.scale_y = scale_y;\r\n\r\n\r\n\t\t/** @private */\r\n\t\tthis._polygon = true;\r\n\r\n\t\t/** @private */\r\n\t\tthis._x = x;\r\n\r\n\t\t/** @private */\r\n\t\tthis._y = y;\r\n\r\n\t\t/** @private */\r\n\t\tthis._angle = angle;\r\n\r\n\t\t/** @private */\r\n\t\tthis._scale_x = scale_x;\r\n\r\n\t\t/** @private */\r\n\t\tthis._scale_y = scale_y;\r\n\r\n\t\t/** @private */\r\n\t\tthis._min_x = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._min_y = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._max_x = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._max_y = 0;\r\n\r\n\t\t/** @private */\r\n\t\tthis._points = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._coords = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._edges = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._normals = null;\r\n\r\n\t\t/** @private */\r\n\t\tthis._dirty_coords = true;\r\n\r\n\t\t/** @private */\r\n\t\tthis._dirty_normals = true;\r\n\r\n\t\tPolygon.prototype.setPoints.call(this, points);\r\n\t}\r\n\r\n\t/**\r\n\t * Draws the polygon to a CanvasRenderingContext2D's current path\r\n\t * @param {CanvasRenderingContext2D} context The context to add the shape to\r\n\t */\r\n\tdraw(context) {\r\n\t\tif(\r\n\t\t\tthis._dirty_coords ||\r\n\t\t\tthis.x !== this._x ||\r\n\t\t\tthis.y !== this._y ||\r\n\t\t\tthis.angle !== this._angle ||\r\n\t\t\tthis.scale_x !== this._scale_x ||\r\n\t\t\tthis.scale_y !== this._scale_y\r\n\t\t) {\r\n\t\t\tthis._calculateCoords();\r\n\t\t}\r\n\r\n\t\tconst coords = this._coords;\r\n\r\n\t\tif(coords.length === 2) {\r\n\t\t\tcontext.moveTo(coords[0], coords[1]);\r\n\t\t\tcontext.arc(coords[0], coords[1], 1, 0, Math.PI * 2);\r\n\t\t}\r\n\t\telse {\r\n\t\t\tcontext.moveTo(coords[0], coords[1]);\r\n\r\n\t\t\tfor(let i = 2; i < coords.length; i += 2) {\r\n\t\t\t\tcontext.lineTo(coords[i], coords[i + 1]);\r\n\t\t\t}\r\n\r\n\t\t\tif(coords.length > 4) {\r\n\t\t\t\tcontext.lineTo(coords[0], coords[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Sets the points making up the polygon. It's important to use this function when changing the polygon's shape to ensure internal data is also updated.\r\n\t * @param {Array<Number[]>} new_points An array of coordinate pairs making up the polygon - [[x1, y1], [x2, y2], ...]\r\n\t */\r\n\tsetPoints(new_points) {\r\n\t\tconst count = new_points.length;\r\n\r\n\t\tthis._points = new Float64Array(count * 2);\r\n\t\tthis._coords = new Float64Array(count * 2);\r\n\t\tthis._edges = new Float64Array(count * 2);\r\n\t\tthis._normals = new Float64Array(count
/***/ }),
/***/ "./src/modules/Result.mjs":
/*!********************************!*\
!*** ./src/modules/Result.mjs ***!
\********************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Result; });\n/**\r\n * An object used to collect the detailed results of a collision test\r\n *\r\n * > **Note:** It is highly recommended you recycle the same Result object if possible in order to avoid wasting memory\r\n * @class\r\n */\r\nclass Result {\r\n\t/**\r\n\t * @constructor\r\n\t */\r\n\tconstructor() {\r\n\t\t/**\r\n\t\t * @desc True if a collision was detected\r\n\t\t * @type {Boolean}\r\n\t\t */\r\n\t\tthis.collision = false;\r\n\r\n\t\t/**\r\n\t\t * @desc The source body tested\r\n\t\t * @type {Circle|Polygon|Point}\r\n\t\t */\r\n\t\tthis.a = null;\r\n\r\n\t\t/**\r\n\t\t * @desc The target body tested against\r\n\t\t * @type {Circle|Polygon|Point}\r\n\t\t */\r\n\t\tthis.b = null;\r\n\r\n\t\t/**\r\n\t\t * @desc True if A is completely contained within B\r\n\t\t * @type {Boolean}\r\n\t\t */\r\n\t\tthis.a_in_b = false;\r\n\r\n\t\t/**\r\n\t\t * @desc True if B is completely contained within A\r\n\t\t * @type {Boolean}\r\n\t\t */\r\n\t\tthis.b_in_a = false;\r\n\r\n\t\t/**\r\n\t\t * @desc The magnitude of the shortest axis of overlap\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.overlap = 0;\r\n\r\n\t\t/**\r\n\t\t * @desc The X direction of the shortest axis of overlap\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.overlap_x = 0;\r\n\r\n\t\t/**\r\n\t\t * @desc The Y direction of the shortest axis of overlap\r\n\t\t * @type {Number}\r\n\t\t */\r\n\t\tthis.overlap_y = 0;\r\n\t}\r\n};\r\n\n\n//# sourceURL=webpack:///./src/modules/Result.mjs?");
/***/ }),
/***/ "./src/modules/SAT.mjs":
/*!*****************************!*\
!*** ./src/modules/SAT.mjs ***!
\*****************************/
/*! exports provided: default */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return SAT; });\n/**\r\n * Determines if two bodies are colliding using the Separating Axis Theorem\r\n * @private\r\n * @param {Circle|Polygon|Point} a The source body to test\r\n * @param {Circle|Polygon|Point} b The target body to test against\r\n * @param {Result} [result = null] A Result object on which to store information about the collision\r\n * @param {Boolean} [aabb = true] Set to false to skip the AABB test (useful if you use your own collision heuristic)\r\n * @returns {Boolean}\r\n */\r\nfunction SAT(a, b, result = null, aabb = true) {\r\n\tconst a_polygon = a._polygon;\r\n\tconst b_polygon = b._polygon;\r\n\r\n\tlet collision = false;\r\n\r\n\tif(result) {\r\n\t\tresult.a = a;\r\n\t\tresult.b = b;\r\n\t\tresult.a_in_b = true;\r\n\t\tresult.b_in_a = true;\r\n\t\tresult.overlap = null;\r\n\t\tresult.overlap_x = 0;\r\n\t\tresult.overlap_y = 0;\r\n\t}\r\n\r\n\tif(a_polygon) {\r\n\t\tif(\r\n\t\t\ta._dirty_coords ||\r\n\t\t\ta.x !== a._x ||\r\n\t\t\ta.y !== a._y ||\r\n\t\t\ta.angle !== a._angle ||\r\n\t\t\ta.scale_x !== a._scale_x ||\r\n\t\t\ta.scale_y !== a._scale_y\r\n\t\t) {\r\n\t\t\ta._calculateCoords();\r\n\t\t}\r\n\t}\r\n\r\n\tif(b_polygon) {\r\n\t\tif(\r\n\t\t\tb._dirty_coords ||\r\n\t\t\tb.x !== b._x ||\r\n\t\t\tb.y !== b._y ||\r\n\t\t\tb.angle !== b._angle ||\r\n\t\t\tb.scale_x !== b._scale_x ||\r\n\t\t\tb.scale_y !== b._scale_y\r\n\t\t) {\r\n\t\t\tb._calculateCoords();\r\n\t\t}\r\n\t}\r\n\r\n\tif(!aabb || aabbAABB(a, b)) {\r\n\t\tif(a_polygon && a._dirty_normals) {\r\n\t\t\ta._calculateNormals();\r\n\t\t}\r\n\r\n\t\tif(b_polygon && b._dirty_normals) {\r\n\t\t\tb._calculateNormals();\r\n\t\t}\r\n\r\n\t\tcollision = (\r\n\t\t\ta_polygon && b_polygon ? polygonPolygon(a, b, result) :\r\n\t\t\ta_polygon ? polygonCircle(a, b, result, false) :\r\n\t\t\tb_polygon ? polygonCircle(b, a, result, true) :\r\n\t\t\tcircleCircle(a, b, result)\r\n\t\t);\r\n\t}\r\n\r\n\tif(result) {\r\n\t\tresult.collision = collision;\r\n\t}\r\n\r\n\treturn collision;\r\n};\r\n\r\n/**\r\n * Determines if two bodies' axis aligned bounding boxes are colliding\r\n * @param {Circle|Polygon|Point} a The source body to test\r\n * @param {Circle|Polygon|Point} b The target body to test against\r\n */\r\nfunction aabbAABB(a, b) {\r\n\tconst a_polygon = a._polygon;\r\n\tconst a_x = a_polygon ? 0 : a.x;\r\n\tconst a_y = a_polygon ? 0 : a.y;\r\n\tconst a_radius = a_polygon ? 0 : a.radius * a.scale;\r\n\tconst a_min_x = a_polygon ? a._min_x : a_x - a_radius;\r\n\tconst a_min_y = a_polygon ? a._min_y : a_y - a_radius;\r\n\tconst a_max_x = a_polygon ? a._max_x : a_x + a_radius;\r\n\tconst a_max_y = a_polygon ? a._max_y : a_y + a_radius;\r\n\r\n\tconst b_polygon = b._polygon;\r\n\tconst b_x = b_polygon ? 0 : b.x;\r\n\tconst b_y = b_polygon ? 0 : b.y;\r\n\tconst b_radius = b_polygon ? 0 : b.radius * b.scale;\r\n\tconst b_min_x = b_polygon ? b._min_x : b_x - b_radius;\r\n\tconst b_min_y = b_polygon ? b._min_y : b_y - b_radius;\r\n\tconst b_max_x = b_polygon ? b._max_x : b_x + b_radius;\r\n\tconst b_max_y = b_polygon ? b._max_y : b_y + b_radius;\r\n\r\n\treturn a_min_x < b_max_x && a_min_y < b_max_y && a_max_x > b_min_x && a_max_y > b_min_y;\r\n}\r\n\r\n/**\r\n * Determines if two polygons are colliding\r\n * @param {Polygon} a The source polygon to test\r\n * @param {Polygon} b The target polygon to test against\r\n * @param {Result} [result = null] A Result object on which to store information about the collision\r\n * @returns {Boolean}\r\n */\r\nfunction polygonPolygon(a, b, result = null) {\r\n\tconst a_count = a._coords.length;\r\n\tconst b_count = b._coords.length;\r\n\r\n\t// Handle points specially\r\n\tif(a_count === 2 && b_count === 2) {\r\n\t\tconst a_coords = a._coords;\r\n\t\tconst b_coords = b._coords;\r\n\r\n\t\tif(result) {\r\n\t\t\tresult.overlap = 0;\r\n\t\t}\r\n\r\n\t\treturn a_coords[0] ===
/***/ })
/******/ });