UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

339 lines (287 loc) • 5.9 kB
import { assert } from "../assert.js"; import Signal from "../events/signal/Signal.js"; import { clamp } from "../math/clamp.js"; import { computeHashFloat } from "../primitives/numbers/computeHashFloat.js"; /** * Wrapper around a scalar value, `Vector1` is used for consistence with {@link Vector2} and {@link Vector3} * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class Vector1 extends Number { /** * * @param {number} [x=0] * @constructor * @class * @property {number} x */ constructor(x = 0) { super(); assert.isNumber(x, 'x'); assert.notNaN(x, 'x'); this.x = x; /** * * @type {Signal<number,number>} */ this.onChanged = new Signal(); } /** * Inherited from Number class * @returns {number} */ valueOf() { return this.x; } /** * * @returns {string} */ toString() { return String(this.x); } /** * Currently held value * @returns {number} */ getValue() { return this.x; } /** * Useful for sorting * @param {Vector1} other * @returns {number} */ compareTo(other) { return this.x - other.x; } /** * * @param {number} x * @returns {Vector1} */ set(x) { assert.isNumber(x, 'x'); assert.notNaN(x, 'x'); const oldValue = this.x; if (oldValue !== x) { this.x = x; if (this.onChanged.hasHandlers()) { this.onChanged.send2(x, oldValue); } } return this; } /** * Set value without triggering {@link #onChanged} signal * @param {number} x */ setSilent(x) { assert.isNumber(x, 'x'); assert.notNaN(x, 'x'); this.x = x; } /** * * @return {boolean} */ isZero() { return this.x === 0; } /** * Increase value by 1. * `value++` */ increment() { this._add(1); } /** * Decrease value by 1. * `value--` */ decrement() { this._add(-1); } /** * * @param {Number} v * @return {Vector1} */ _add(v) { return this.set(this.x + v); } /** * * @param {Vector1|Vector2|Vector3|Vector4} other */ add(other) { assert.isObject(other, "other"); return this._add(other.x); } /** * * @param {Number} v * @return {Vector1} */ _sub(v) { return this._add(-v); } /** * * @param {Vector1} other * @returns {Vector1} */ sub(other) { return this._sub(other.x); } /** * * @param {Vector1} other * @returns {Vector1} */ multiply(other) { return this.set(this.x * other.x); } /** * * @param {number} v */ multiplyScalar(v) { this.set(this.x * v); } /** * * @param {number} low * @param {number} high * @returns {Vector1} */ clamp(low, high) { return this.set(clamp(this.x, low, high)); } /** * Negate sign of the value, if value is 7, it will become -7 and vice versa * Zero is unaffected */ negate() { this.set(-this.x); } /** * * @param {Vector1|Vector2|Vector3|Vector4} other */ copy(other) { this.set(other.x); } /** * * @returns {Vector1} */ clone() { return new Vector1(this.x); } /** * * @param {Vector1} other * @returns {boolean} */ equals(other) { return this.x === other.x; } /** * @returns {number} */ hash() { return computeHashFloat(this.x); } /** * * @param {function(newValue:number, oldValue:number)} handler */ process(handler) { handler(this.x, this.x); this.onChanged.add(handler); } toJSON() { return this.x; } fromJSON(val) { this.set(val); } /** * * @param {number[]} array * @param {number} offset */ readFromArray(array, offset = 0) { this.set(array[offset]); } /** * * @param {number[]} array * @param {number} offset */ writeToArray(array, offset = 0) { array[offset] = this.x; } asArray() { return [this.x]; } /** * * @param {BinaryBuffer} buffer */ toBinaryBuffer(buffer) { buffer.writeFloat64(this.x); } /** * * @param {BinaryBuffer} buffer */ fromBinaryBuffer(buffer) { const x = buffer.readFloat64(); this.set(x); } /** * * @param {Vector1} a * @param {Vector1} b * @return {number} */ static compare(a, b) { return a.x - b.x; } // pretending to be an array get 0() { return this.x; } set 0(v) { this.x = v; } * [Symbol.iterator]() { yield this.x; } } /** * @readonly * @type {boolean} */ Vector1.prototype.isVector1 = true; /** * @readonly * @type {string} */ Vector1.typeName = "Vector1"; /** * Utility singleton * @readonly * @type {Vector1} */ Vector1.zero = Object.freeze(new Vector1(0)); /** * Utility singleton * @readonly * @type {Vector1} */ Vector1.one = Object.freeze(new Vector1(1)); export default Vector1;