game_space_path_path.js

/**
 * @module Path
 * @fileoverview Contains Path class.
 */

/**
 * @class
 * Used to store and keep track of a path.
 *
 * The Path holds an array of points and a counter to indicate the next one up. Whatever object
 * is using the Path can call getDestination() with its updated position to get the next point
 * in the path, and increment the counter if necessary.
 */
class Path {
    /**
     * Create a new Path.
     * @param {Space} space The space the Path is being used in
     * @param {Vec2[]} points The points (Vec2) that will make up the Path
     * @constructor
     */
    constructor(space, points = []) {
        this.space = space;
        this.points = points;

        this.curr = 0;
    }


    //
    // Getters
    //

    /**
     * Get the next destination in the path, based on a specified current position. Will advance the counter and
     * return the next point if the specified position is close enough.
     * @param {Vec2} pos Position to check with
     * @returns Next point in path
     */
    getDestination(pos) {
        if (pos.dist(this.points[this.curr]) < 2) {
            this.curr++;
            if (this.curr === this.points.length)
                return null;
        }

        return this.points[this.curr];
    }

    /**
     * Get the last position in the path.
     * @returns {Vec2} Last path position
     */
    getEnd() {
        return this.points[this.points.length - 1];
    }


    //
    // Drawing
    //

    /**
     * Draw a visualization of the Path for debugging purposes. Will show each point with lines connecting them,
     * and will show which points have been completed based on the counter.
     * @param {CanvasRenderingContext2D} ctx Canvas context to draw on
     */
    drawDebug(ctx) {
        if ($$.debug.actors) {
            ctx.lineWidth = 2 / this.space.camera.calcZoom();

            let i = 0;
            let prev = null;
            for (const point of this.points) {
                if (i < this.curr) {
                    ctx.fillStyle = $$.colors.debug_path_complete;
                    ctx.strokeStyle = $$.colors.debug_path_complete;
                } else {
                    ctx.fillStyle = $$.colors.debug_path;
                    ctx.strokeStyle = $$.colors.debug_path2;
                }
                if (prev !== null) {
                    ctx.beginPath();
                    ctx.moveTo(prev.x, prev.y);
                    ctx.lineTo(point.x, point.y);
                    ctx.stroke();
                }

                ctx.fillRect(point.x - 2, point.y - 2, 4, 4);
                prev = point;

                i++;
            }
        }
    }
}

export default Path;