class Path
{
constructor()
{
this.onComplete = new Action();
this.complete = true;
this.pathNodes = [];//new List<Vector2>();
this.currentIndex = 0;
this.distanceAlongCurrentNodePair = 0;
}
movePath(offset /*Vector2*/)
{
for (var i = 0; i < this.pathNodes.length; i++)
{
this.pathNodes[i].x += offset.x;
this.pathNodes[i].y += offset.y;
}
}
addNode(node /*Vector2*/)
{
this.pathNodes.push(node);
this.complete = false;
}
clear()
{
if (this.hasPath && !this.complete)
{
this.callOnComplete();
}
this.pathNodes.length = 0;
this.distanceAlongCurrentNodePair = 0;
this.currentIndex = 0;
this.complete = true;
}
resetPosition()
{
this.distanceAlongCurrentNodePair = 0;
this.currentIndex = 0;
this.complete = false;
}
get percentAlongtPath()
{
var totalDistance = 0;
var traveledDistance = 0;
var segment = new Vector2();
for (var i = 0; i < this.pathNodes.length - 1; i++)
{
segment.subVectors(this.pathNodes[i + 1], this.pathNodes[i]);
totalDistance += segment.length();
if (this.currentIndex < i)
{
traveledDistance += segment.magnitude;
}
else if(this.currentIndex == i)
{
traveledDistance += this.distanceAlongCurrentNodePair;
}
}
return traveledDistance / totalDistance;
}
getTotalDistance()
{
let segment = new Vector2();
let totalDistance = 0;
for (var i = 0; i < this.pathNodes.length - 1; i++)
{
segment.subVectors(this.pathNodes[i + 1], this.pathNodes[i]);
totalDistance += segment.length();
}
return totalDistance;
}
set percentAlongPath(value)
{
var totalDistance = 0;
var segment = new Vector2();
for (var i = 0; i < this.pathNodes.length - 1; i++)
{
segment.subVectors(this.pathNodes[i + 1], this.pathNodes[i]);
totalDistance += segment.length();
}
this.move(totalDistance * value);
}
move(distance /*float*/)
{
var nextPoint = new Vector2();
var segment = new Vector2();
if (this.pathNodes.length == 1) nextPoint = this.pathNodes[0];
if (this.pathNodes.length > 1 && this.currentIndex < this.pathNodes.length - 1)
{
var startPoint = this.pathNodes[this.currentIndex];
var endPoint = this.pathNodes[this.currentIndex + 1];
segment.subVectors(endPoint, startPoint);
nextPoint.addVectors(startPoint, segment.normalize().multiplyScalar(this.distanceAlongCurrentNodePair));
}
while (distance > 0)
{
//if we are out of pathnodes then return the last node, or 0 if the path has no nodes for some crazy reason.
if (this.currentIndex >= this.pathNodes.length - 1)
{
this.complete = true;
this.callOnComplete();
return this.pathNodes.length > 0 ? this.pathNodes[this.currentIndex] : new Vector2(0, 0);
}
var startPoint = this.pathNodes[this.currentIndex];
var endPoint = this.pathNodes[this.currentIndex + 1];
segment.subVectors(endPoint, startPoint);
var availableLength = segment.length() - this.distanceAlongCurrentNodePair;
if (availableLength > distance)
{
//nextPoint = startPoint + segment * ((this.distanceAlongCurrentNodePair + distance) / segment.length());
nextPoint.addVectors(startPoint, segment.multiplyScalar( (this.distanceAlongCurrentNodePair + distance) / segment.length()) );
this.distanceAlongCurrentNodePair += distance;
distance = 0;
}
else
{
distance -= availableLength;
this.distanceAlongCurrentNodePair = 0;
this.currentIndex++;
}
}
return nextPoint;
}
callOnComplete()
{
this.onComplete.clearAndCall();
}
get hasPath()
{
return this.pathNodes.length > 0;
}
getPositionIn(distance /*float*/)
{
var nextPoint = new Vector2();
var localIndex = this.currentIndex;
var localDistanceCurrent = this.distanceAlongCurrentNodePair;
var segment = new Vector2();
while (distance > 0)
{
//if we are out of pathnodes then return the last node, or 0 if the path has no nodes for some crazy reason.
if (localIndex >= this.pathNodes.length - 1)
{
return this.pathNodes.length > 0 ? this.pathNodes[localIndex] : new Vector2(0, 0);
}
var startPoint = this.pathNodes[localIndex];
var endPoint = this.pathNodes[localIndex + 1];
segment.subVectors(endPoint, startPoint);
var availableLength = segment.length() - localDistanceCurrent;
if (availableLength > distance)
{
//startPoint + segment * ((localDistanceCurrent + distance) / segment.length());
nextPoint.addVectors(startPoint, segment.multiplyScalar((localDistanceCurrent + distance) / segment.length()));
localDistanceCurrent += distance;
distance = 0;
}
else
{
distance -= availableLength;
localDistanceCurrent = 0;
localIndex++;
}
}
return nextPoint;
}
}