UNPKG

@rpgjs/physic

Version:

A deterministic 2D top-down physics library for RPG, sandbox and MMO games

71 lines (70 loc) 2.36 kB
class Oscillate { /** * Creates an oscillating movement. * * @param direction - Base direction (will be normalized) * @param amplitude - Maximum displacement from the anchor position * @param period - Duration of a full cycle in seconds * @param type - Oscillation pattern * @param duration - Total life time in seconds (undefined for infinite) */ constructor(direction, amplitude, period, type = "sine", duration) { this.amplitude = amplitude; this.period = period; this.type = type; this.duration = duration; this.elapsed = 0; this.anchor = null; const magnitude = Math.hypot(direction.x, direction.y); this.direction = magnitude > 0 ? { x: direction.x / magnitude, y: direction.y / magnitude } : { x: 1, y: 0 }; } update(body, dt) { if (this.anchor === null) { this.anchor = { x: body.position.x, y: body.position.y }; } this.elapsed += dt; if (this.duration !== void 0 && this.elapsed >= this.duration) { body.setVelocity({ x: 0, y: 0 }); return; } const cycle = this.period <= 0 ? 0 : this.elapsed % this.period / this.period; const frequency = this.period > 0 ? 2 * Math.PI / this.period : 0; let velocityScale; switch (this.type) { case "sine": velocityScale = Math.cos(cycle * Math.PI * 2) * frequency * this.amplitude; break; case "circular": velocityScale = Math.cos(cycle * Math.PI * 2) * frequency * this.amplitude; break; case "linear": const halfCycle = cycle < 0.5; velocityScale = (halfCycle ? 1 : -1) * (2 * this.amplitude) / (this.period / 2); break; default: velocityScale = 0; } const vx = this.direction.x * velocityScale; const vy = this.direction.y * velocityScale; if (this.type === "circular") { const perpendicularScale = -Math.sin(cycle * Math.PI * 2) * frequency * this.amplitude; body.setVelocity({ x: vx - this.direction.y * perpendicularScale, y: vy + this.direction.x * perpendicularScale }); } else { body.setVelocity({ x: vx, y: vy }); } } isFinished() { return this.duration !== void 0 && this.elapsed >= this.duration; } reset() { this.elapsed = 0; this.anchor = null; } } export { Oscillate }; //# sourceMappingURL=index38.js.map