@rpgjs/physic
Version:
A deterministic 2D top-down physics library for RPG, sandbox and MMO games
96 lines (95 loc) • 2.65 kB
JavaScript
class PathFollow {
/**
* Creates a path-following strategy.
*
* @param waypoints - List of waypoints to traverse
* @param speed - Travel speed in units per second
* @param loop - When true, restart from the first waypoint
* @param pauseAtWaypoints - Optional pause duration (seconds) at each waypoint
* @param tolerance - Distance tolerance to consider a waypoint reached
*/
constructor(waypoints, speed, loop = false, pauseAtWaypoints = 0, tolerance = 0.1) {
this.waypoints = waypoints;
this.speed = speed;
this.loop = loop;
this.pauseAtWaypoints = pauseAtWaypoints;
this.tolerance = tolerance;
this.currentWaypoint = 0;
this.elapsedPause = 0;
this.paused = false;
this.finished = false;
this.direction = { x: 0, y: 0 };
if (waypoints.length === 0) {
this.finished = true;
}
}
update(body, dt) {
if (this.finished || this.waypoints.length === 0) {
body.setVelocity({ x: 0, y: 0 });
return;
}
if (this.paused) {
this.elapsedPause += dt;
body.setVelocity({ x: 0, y: 0 });
if (this.elapsedPause >= this.pauseAtWaypoints) {
this.paused = false;
this.elapsedPause = 0;
} else {
return;
}
}
const target = this.waypoints[this.currentWaypoint];
if (!target) {
this.finished = true;
body.setVelocity({ x: 0, y: 0 });
return;
}
const dx = target.x - body.position.x;
const dy = target.y - body.position.y;
const distance = Math.hypot(dx, dy);
if (distance <= this.tolerance) {
this.currentWaypoint += 1;
if (this.currentWaypoint >= this.waypoints.length) {
if (this.loop) {
this.currentWaypoint = 0;
} else {
this.finished = true;
body.setVelocity({ x: 0, y: 0 });
return;
}
}
if (this.pauseAtWaypoints > 0) {
this.paused = true;
this.elapsedPause = 0;
body.setVelocity({ x: 0, y: 0 });
return;
}
}
if (distance > 0) {
this.direction = { x: dx / distance, y: dy / distance };
}
body.setVelocity({
x: this.direction.x * this.speed,
y: this.direction.y * this.speed
});
}
isFinished() {
return this.finished;
}
getCurrentWaypoint() {
return this.currentWaypoint;
}
setWaypoints(waypoints, reset = true) {
this.waypoints = waypoints;
this.finished = waypoints.length === 0;
if (reset) {
this.currentWaypoint = 0;
this.paused = false;
this.elapsedPause = 0;
}
}
}
export {
PathFollow
};
//# sourceMappingURL=index39.js.map