public/js-roguelike-skeleton/src/array-2d.js
function(startX, startY, settings) {
            settings = settings || {};

            var maxRadius   = settings.maxRadius    || 1,
                filter      = settings.filter       || false,
                withCoords  = settings.withCoords    || false;

            var currentDistance = 1,
                results = [],
                x, y;

            var checkVal = function(val, x, y) {
                var result;
                if ((filter && filter(val, x, y)) || (!filter && val)) {
                    if (withCoords) {
                        results.push({
                            x: x,
                            y: y,
                            value: val
                        });
                    } else {
                        return results.push(val);
                    }
                }
            };

            while (currentDistance <= maxRadius) {

                var minX = startX - currentDistance,
                    maxX = startX + currentDistance,
                    minY = startY - currentDistance,
                    maxY = startY + currentDistance,
                    len = currentDistance * 2 + 1;

                for (var i = len - 1; i >= 0; i--) {

                    var val;

                    // top and bottom edges skip first and last coords to prevent double checking
                    if (i < len - 1 && i > 0) {
                        // top edge
                        if (minY >= 0) {
                            x = minX + i;
                            y = minY;
                            val = this.get(x, y);
                            checkVal(val, x, y);

                        }

                        if (maxY < this.height) {
                            // bottom edge
                            x = minX + i;
                            y = maxY;
                            val = this.get(x, y);
                            checkVal(val, x, y);
                        }
                    }

                    if (minX >= 0) {
                        // left edge
                        x = minX;
                        y = minY + i;
                        val = this.get(x, y);
                        checkVal(val, x, y);
                    }

                    if (maxX < this.width) {
                        // right edge
                        x = maxX;
                        y = minY + i;
                        val = this.get(x, y);
                        checkVal(val, x, y);
                    }
                }
                if (results.length) {
                    return results;
                }
                currentDistance++;
            }

            return false;
        }
function(startX, startY, settings) {
            settings = settings || {};

            var maxRadius   = settings.maxRadius    || 1,
                filter      = settings.filter       || false,
                withCoords  = settings.withCoords    || false;

            var currentDistance = 1,
                results = [],
                x, y;

            var checkVal = function(val, x, y) {
                var result;
                if ((filter && filter(val, x, y)) || (!filter && val)) {
                    if (withCoords) {
                        results.push({
                            x: x,
                            y: y,
                            value: val
                        });
                    } else {
                        return results.push(val);
                    }
                }
            };

            while (currentDistance <= maxRadius) {

                var minX = startX - currentDistance,
                    maxX = startX + currentDistance,
                    minY = startY - currentDistance,
                    maxY = startY + currentDistance,
                    len = currentDistance * 2 + 1;

                for (var i = len - 1; i >= 0; i--) {

                    var val;

                    // top and bottom edges skip first and last coords to prevent double checking
                    if (i < len - 1 && i > 0) {
                        // top edge
                        if (minY >= 0) {
                            x = minX + i;
                            y = minY;
                            val = this.get(x, y);
                            checkVal(val, x, y);

                        }

                        if (maxY < this.height) {
                            // bottom edge
                            x = minX + i;
                            y = maxY;
                            val = this.get(x, y);
                            checkVal(val, x, y);
                        }
                    }

                    if (minX >= 0) {
                        // left edge
                        x = minX;
                        y = minY + i;
                        val = this.get(x, y);
                        checkVal(val, x, y);
                    }

                    if (maxX < this.width) {
                        // right edge
                        x = maxX;
                        y = minY + i;
                        val = this.get(x, y);
                        checkVal(val, x, y);
                    }
                }
                if (results.length) {
                    return results;
                }
                currentDistance++;
            }

            return false;
        }
function ( startX , startY , settings ) { settings = settings || { } ; var maxRadius = settings . maxRadius || 1 , filter = settings . filter || false , withCoords = settings . withCoords || false ; var currentDistance = 1 , results = [ ] , x , y ; var checkVal = function ( val , x , y ) { var result ; if ( ( filter && filter ( val , x , y ) ) || ( ! filter && val ) ) { if ( withCoords ) { results . push ( { x : x , y : y , value : val } ) ; } else { return results . push ( val ) ; } } } ; while ( currentDistance <= maxRadius ) { var minX = startX - currentDistance , maxX = startX + currentDistance , minY = startY - currentDistance , maxY = startY + currentDistance , len = currentDistance * 2 + 1 ; for ( var i = len - 1 ; i >= 0 ; i -- ) { var val ; // top and bottom edges skip first and last coords to prevent double checking if ( i < len - 1 && i > 0 ) { // top edge if ( minY >= 0 ) { x = minX + i ; y = minY ; val = this . get ( x , y ) ; checkVal ( val , x , y ) ; } if ( maxY < this . height ) { // bottom edge x = minX + i ; y = maxY ; val = this . get ( x , y ) ; checkVal ( val , x , y ) ; } } if ( minX >= 0 ) { // left edge x = minX ; y = minY + i ; val = this . get ( x , y ) ; checkVal ( val , x , y ) ; } if ( maxX < this . width ) { // right edge x = maxX ; y = minY + i ; val = this . get ( x , y ) ; checkVal ( val , x , y ) ; } } if ( results . length ) { return results ; } currentDistance ++ ; } return false ; }
Retrieves an array of the nearest coord values meeting checked requirements. If multiple coord values were matched at the same nearest distance, the returned array will contain multiple matched coord values.
Used for projecting path of ranged attacks, pushed entities, ect.
@method getNearest
@param {Number} tileX - Map tile x coord of the center of the radius.
@param {Number} tileY - Map tile x coord of the center of the radius.
@param {Object} [settings] -
@param {Number} [settings.maxRadius=1] - Maxium search radius from given coord.
@param {Function} [settings.filter=false] - A function to determine when the desired coord value is matched. A coord value returning true when passed to the function would be added to the list of results. (function(value, x, y){ return true;}) If no check function is provided any tile with a truthy value will be matched.
@param {Bool} [settings.withCoords=false] - If true the returned array will include the coords of each value ([{x: 0, y: 0, value: 1}, ...])
@return {Array} An array of coord values within a square radius of the given coords.
Retrieves an array of the nearest coord values meeting checked requirements . If multiple coord values were matched at the same nearest distance the returned array will contain multiple matched coord values . Used for projecting path of ranged attacks pushed entities ect .