UNPKG

@rpgjs/physic

Version:

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

87 lines (86 loc) 2.81 kB
class IceMovement { /** * Creates an ice-like movement behaviour. * * @param direction - Initial desired direction (normalized automatically) * @param maxSpeed - Maximum speed in units per second * @param acceleration - Fraction of the gap closed per second (0-1) * @param friction - Fraction of velocity retained per second when stopping (0-1) * @param duration - Optional duration in seconds */ constructor(direction, maxSpeed = 4, acceleration = 0.2, friction = 0.08, duration) { this.maxSpeed = maxSpeed; this.acceleration = acceleration; this.friction = friction; this.duration = duration; this.currentVelocity = { x: 0, y: 0 }; this.elapsed = 0; this.stopped = false; const magnitude = Math.hypot(direction.x, direction.y); this.targetDirection = magnitude > 0 ? { x: direction.x / magnitude, y: direction.y / magnitude } : { x: 0, y: 0 }; } update(body, dt) { if (this.duration !== void 0) { this.elapsed += dt; if (this.elapsed >= this.duration) { this.stopped = true; } } if (!this.stopped) { const accelFactor = this.perSecondFactor(this.acceleration, dt); const targetVx = this.targetDirection.x * this.maxSpeed; const targetVy = this.targetDirection.y * this.maxSpeed; this.currentVelocity.x += (targetVx - this.currentVelocity.x) * accelFactor; this.currentVelocity.y += (targetVy - this.currentVelocity.y) * accelFactor; } else { const frictionFactor = this.perSecondFactor(this.friction, dt); this.currentVelocity.x *= 1 - frictionFactor; this.currentVelocity.y *= 1 - frictionFactor; } body.setVelocity({ x: this.currentVelocity.x, y: this.currentVelocity.y }); } isFinished() { if (!this.stopped) { return false; } const speed = Math.hypot(this.currentVelocity.x, this.currentVelocity.y); return speed < 0.05; } stop() { this.stopped = true; } resume() { this.stopped = false; } setTargetDirection(direction) { const magnitude = Math.hypot(direction.x, direction.y); this.targetDirection.x = magnitude > 0 ? direction.x / magnitude : 0; this.targetDirection.y = magnitude > 0 ? direction.y / magnitude : 0; this.stopped = false; } setParameters(maxSpeed, acceleration, friction) { if (maxSpeed !== void 0) { this.maxSpeed = maxSpeed; } if (acceleration !== void 0) { this.acceleration = acceleration; } if (friction !== void 0) { this.friction = friction; } } perSecondFactor(value, dt) { const clamped = Math.max(0, Math.min(1, value)); if (dt <= 0) { return clamped; } return 1 - Math.pow(1 - clamped, dt); } } export { IceMovement }; //# sourceMappingURL=index34.js.map