UNPKG

@hiddentao/clockwork-engine

Version:

A TypeScript/PIXI.js game engine for deterministic, replayable games with built-in rendering

124 lines (123 loc) 3.61 kB
export class Vector2D { constructor(x, y) { this.x = x; this.y = y; } add(other) { return new Vector2D(this.x + other.x, this.y + other.y); } subtract(other) { return new Vector2D(this.x - other.x, this.y - other.y); } scale(scalar) { return new Vector2D(this.x * scalar, this.y * scalar); } dot(other) { return this.x * other.x + this.y * other.y; } length() { return Math.sqrt(this.x * this.x + this.y * this.y); } distance(other) { return Vector2D.distance(this, other); } normalize() { const len = this.length(); if (len === 0) { return new Vector2D(0, 0); } return new Vector2D(this.x / len, this.y / len); } rotate(angle) { const cos = Math.cos(angle); const sin = Math.sin(angle); return new Vector2D(this.x * cos - this.y * sin, this.x * sin + this.y * cos); } /** * Calculate the angle of this vector in radians * @returns The angle in radians [-PI, PI] */ angle() { return Math.atan2(this.y, this.x); } /** * Calculate the angle between this vector and another vector * @param other The other vector * @returns The angle in radians between the two vectors */ angleBetween(other) { return Math.atan2(other.y - this.y, other.x - this.x); } clone() { return new Vector2D(this.x, this.y); } toString() { return `(${this.x}, ${this.y})`; } /** * Serialize this Vector2D to a plain object */ serialize() { return { x: this.x, y: this.y }; } /** * Deserialize a plain object to a Vector2D */ static deserialize(data) { return new Vector2D(data.x, data.y); } /** * Calculate distance between two vectors */ static distance(v1, v2) { const dx = v1.x - v2.x; const dy = v1.y - v2.y; return Math.sqrt(dx * dx + dy * dy); } /** * Calculate squared distance between two vectors (more efficient for comparisons) */ static distanceSquared(v1, v2) { const dx = v1.x - v2.x; const dy = v1.y - v2.y; return dx * dx + dy * dy; } /** * Check if two positions are within a specified distance of each other * @param v1 First position * @param v2 Second position * @param distance Maximum distance between positions * @returns True if the positions are within the specified distance */ static isWithinDistance(v1, v2, distance) { return Vector2D.distanceSquared(v1, v2) <= distance * distance; } /** * Normalize angle to (-PI, PI) range */ static normalizeAngle(angle) { while (angle > Math.PI) angle -= 2 * Math.PI; while (angle < -Math.PI) angle += 2 * Math.PI; return angle; } /** * Calculate the shortest angle difference between two angles * @param angle1 First angle in radians * @param angle2 Second angle in radians * @returns The shortest angle difference in radians */ static angleDifference(angle1, angle2) { // Normalize both angles to (-PI, PI) range angle1 = Vector2D.normalizeAngle(angle1); angle2 = Vector2D.normalizeAngle(angle2); // Find the shortest angle difference let diff = angle2 - angle1; if (diff > Math.PI) diff -= 2 * Math.PI; if (diff < -Math.PI) diff += 2 * Math.PI; return diff; } }