Newer
Older
lostmynuts / shared / js / Game / Utils / Path.js
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;
		

	}


}