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