/************************************************************************ * Collisions.js ************************************************************************ * Copyright (c) 2021 Pedro Tonini Rosenberg Schneider. * * This file is part of Pandora. * * Pandora is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pandora is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pandora. If not, see . *************************************************************************/ /** * This {@code Collisions} singleton provides an interface for the engine to calculate collisions * with various differente shapes. They are used in the calculations of the Area2D GameObject, * to check collisions with the mouse. They can be utilized by the user if it fits the need. * * @author Pedro Schneider * * @namespace */ const Collisions = { /** * Rotates the (x, y) vector by a degrees clockwise, around the origin. * * @param {number} x X coordinate of the vector to rotate. * @param {number} y Y coordinate of the vector to rotate. * @param {number} a angle in degrees to rotate the vector. * * @returns {Array} static array containing the tow coordinates of the rotated vector. * Can be deconstructed. */ rotate(x, y, a) { var rotx = x, roty = y; var ra = radians(a) if (a % 360 != 0) { rotx = x * cos(-ra) - y * sin(-ra); roty = x * sin(-ra) + y * cos(-ra); } return Object.freeze([rotx, roty]); }, /** * Namespace to separate rectangle collision detection. * * @namespace */ Rect: { /** * Calculates if a point is inside a rect. * * @param {number} posx global X-axis position of the rect. * @param {number} posy global Y-axis position of the rect. * @param {number} rot global rotation in degrees of the rect. * @param {number} sx global X-axis scale of the rect. * @param {number} sy global Y-axis scale of the rect. * @param {Rect} rect Shape component with the rect data. * @param {number} x X-axis position of the point. * @param {number} y Y-axis position of the point. * * @returns {boolean} true if the point is inside the rect, false otherwise. */ point(posx, posy, rot, sx, sy, rect, x, y) { x -= posx; y -= posy; var [rotx, roty] = Collisions.rotate(x, y, rot); return abs(rotx) <= rect.w / 2 * sx && abs(roty) <= rect.h / 2 * sy; }, }, /** * Namespace to separate ellipse collision detection. * * @namespace */ Ellipse: { /** * Calculates if a point is inside a ellipse. * * @param {number} posx global X-axis position of the ellipse. * @param {number} posy global Y-axis position of the ellipse. * @param {number} rot global rotation in degrees of the ellipse. * @param {number} sx global X-axis scale of the ellipse. * @param {number} sy global Y-axis scale of the ellipse. * @param {Ellipse} e Shape component with the ellipse data. * @param {number} x X-axis position of the point. * @param {number} y Y-axis position of the point. * * @returns {boolean} true if the point is inside the ellipse, false otherwise. */ point(posx, posy, rot, sx, sy, e, x, y) { x -= posx; y -= posy; var [rotx, roty] = Collisions.rotate(x, y, rot); var srx = e.rx * sx, sry = e.ry * sy; return (rotx * rotx) * (sry * sry) + (roty * roty) * (srx * srx) <= (srx * srx) * (sry * sry); } } }