UNPKG

@theatrejs/theatrejs

Version:

🎮 A JavaScript 2D Game Engine focused on creating pixel art games.

355 lines (283 loc) • 7.74 kB
import {Vector2} from '../index.js'; /** * Creates AABBs. * * @example * * const aabb = new AABB(new Vector2(-1, -1), new Vector2(1, 1)); */ class AABB { /** * Stores the maximum values of the AABB. * @type {Vector2} * @private */ $maximum; /** * Stores the minimum values of the AABB. * @type {Vector2} * @private */ $minimum; /** * Gets the bottom boundary of the AABB. * @type {Vector2} * @public */ get boundaryBottom() { return new Vector2(this.center.x, this.$minimum.y); } /** * Gets the bottom-left boundary of the AABB. * @type {Vector2} * @public */ get boundaryBottomLeft() { return this.$minimum; } /** * Gets the bottom-right boundary of the AABB. * @type {Vector2} * @public */ get boundaryBottomRight() { return new Vector2(this.$maximum.x, this.$minimum.y); } /** * Gets the left boundary of the AABB. * @type {Vector2} * @public */ get boundaryLeft() { return new Vector2(this.$minimum.x, this.center.y); } /** * Gets the right boundary of the AABB. * @type {Vector2} * @public */ get boundaryRight() { return new Vector2(this.$maximum.x, this.center.y); } /** * Gets the top boundary of the AABB. * @type {Vector2} * @public */ get boundaryTop() { return new Vector2(this.center.x, this.$maximum.y); } /** * Gets the top-left boundary of the AABB. * @type {Vector2} * @public */ get boundaryTopLeft() { return new Vector2(this.$minimum.x, this.$maximum.y); } /** * Gets the top-right boundary of the AABB. * @type {Vector2} * @public */ get boundaryTopRight() { return this.$maximum; } /** * Gets the center of the AABB. * @type {Vector2} * @public */ get center() { return this.$minimum.clone().add(this.halfSize); } /** * Gets the half-size of the AABB. * @type {Vector2} * @public */ get halfSize() { return this.size.clone().scale(0.5); } /** * Gets the maximum values of the AABB. * @type {Vector2} * @public */ get maximum() { return this.$maximum; } /** * Gets the minimum values of the AABB. * @type {Vector2} * @public */ get minimum() { return this.$minimum; } /** * Gets the size of the AABB. * @type {Vector2} * @public */ get size() { return this.$maximum.clone().subtract(this.$minimum); } /** * Creates a new AABB. * @param {Vector2} $minimum The minimum values of the AABB to create. * @param {Vector2} $maximum The maximum values of the AABB to create. */ constructor($minimum, $maximum) { this.$maximum = $maximum.clone(); this.$minimum = $minimum.clone(); } /** * Gets the manhattan distance between the two given AABBs. * @param {AABB} $a The first AABB to compare. * @param {AABB} $b The second AABB to compare. * @returns {number} * @public * @static */ static distanceManhattan($a, $b) { const distanceX = AABB.distanceX($a, $b); const distanceY = AABB.distanceY($a, $b); if (distanceX > 0 || distanceY > 0) { return Math.max(distanceX, 0) + Math.max(distanceY, 0); } return distanceX + distanceY; } /** * Gets the distance between the two given AABBs on the x-axis. * @param {AABB} $a The first AABB to compare. * @param {AABB} $b The second AABB to compare. * @returns {number} * @public * @static */ static distanceX($a, $b) { const distanceCenter = Math.abs($b.center.x - $a.center.x); const distanceMinimum = $a.halfSize.x + $b.halfSize.x; return distanceCenter - distanceMinimum; } /** * Gets the distance between the two given AABBs on the y-axis. * @param {AABB} $a The first AABB to compare. * @param {AABB} $b The second AABB to compare. * @returns {number} * @public * @static */ static distanceY($a, $b) { const distanceCenter = Math.abs($b.center.y - $a.center.y); const distanceMinimum = $a.halfSize.y + $b.halfSize.y; return distanceCenter - distanceMinimum; } /** * Creates a new AABB from the given AABB. * @param {AABB} $aabb The given AABB. * @returns {AABB} * @public * @static */ static from($aabb) { return $aabb.clone(); } /** * Creates a new AABB from the given size. * @param {Vector2} $size The given size. * @returns {AABB} * @public * @static */ static fromSize($size) { return new AABB( $size.clone().scale(-0.5), $size.clone().scale(0.5) ); } /** * Gets the delta penetration between the two given AABBs strictly overlapping with each other on the x-axis (the common area). * @param {AABB} $a The first AABB to compare. * @param {AABB} $b The second AABB to compare. * @returns {number} * @public * @static */ static overlapX($a, $b) { const distanceCenter = Math.abs($b.center.x - $a.center.x); const distanceMinimum = $a.halfSize.x + $b.halfSize.x; return distanceMinimum - distanceCenter; } /** * Gets the delta penetration between the two given AABBs strictly overlapping with each other on the y-axis (the common area). * @param {AABB} $a The first AABB to compare. * @param {AABB} $b The second AABB to compare. * @returns {number} * @public * @static */ static overlapY($a, $b) { const distanceCenter = Math.abs($b.center.y - $a.center.y); const distanceMinimum = $a.halfSize.y + $b.halfSize.y; return distanceMinimum - distanceCenter; } /** * Clones the AABB. * @returns {AABB} * @public */ clone() { return new AABB(this.$minimum.clone(), this.$maximum.clone()); } /** * Checks the equality with the given AABB. * @param {AABB} $aabb The AABB to check with. * @returns {boolean} * @public */ equal($aabb) { return this.$minimum.equal($aabb.minimum) === true && this.$maximum.equal($aabb.maximum) === true; } /** * Translates the AABB in the world space from a third person point of view. * @param {Vector2} $vector The translation to apply. * @returns {this} * @public */ translate($vector) { this.$maximum.add($vector); this.$minimum.add($vector); return this; } /** * Translates the AABB in the world space from a third person point of view on the x-axis. * @param {number} $x The translation to apply on the x-axis. * @returns {this} * @public */ translateX($x) { const translation = new Vector2($x, 0); this.$maximum.add(translation); this.$minimum.add(translation); return this; } /** * Translates the AABB in the world space from a third person point of view on the y-axis. * @param {number} $y The translation to apply on the y-axis. * @returns {this} * @public */ translateY($y) { const translation = new Vector2($y, 0); this.$maximum.add(translation); this.$minimum.add(translation); return this; } } export { AABB }; export default AABB;