@rpgjs/physic
Version:
A deterministic 2D top-down physics library for RPG, sandbox and MMO games
71 lines (70 loc) • 2.36 kB
JavaScript
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