Ошибка сценариев Javascript - PullRequest
0 голосов
/ 15 апреля 2011

После прочтения алгоритмов Field of View я решил создать их самостоятельно для игры, над которой я работаю. Через пару часов я придумал следующий скрипт:

function CalculateFOV() {
    ClearFOV();

    map[player.x][player.y].light = 100;

    var open = new Array();
    var closed = new Array();

    sourceNeighbors = map[player.x][player.y].neighbors;

    for(var i = 0;i<sourceNeighbors.length;i++) {
        open.push(sourceNeighbors[i]);
    }

    while(open.length > 0) {
        var curTile = open[0];

        var highestLightValue = 0;

        for(j in curTile.neighbors) {
            if(curTile.neighbors[j].light > highestLightValue) {
                highestLightValue = neighbors[j];               
            }
        }

        curTile.light = highestLightValue-10;

        if(curTile.light > 10) {
            for(var j = 0;j<curTile.neighbors.length;j++) {
                var addCell = true;

                if(FindValue(closed, open[0].neighbors[j])) addCell = false;

                if(addCell) {
                    open.push(neighbors[j]);
                }
            }
        }

        closed.push(curTile);
        open.shift();
    }
}

function ClearFOV() {
    for(var x = 0;x<mapSizeX;x++) {
        for(var y = 0;y<mapSizeY;y++) {
            map[x][y].lightValue = 0;
        }
    }
}

function FindValue(list, value) {
    for(var i = 0;i<list.length;i++) {
        if(list[i] == value) {
            return true;
        }
    }

    return false;
}

Он должен распространять световую ценность наружу от источника, постепенно уменьшаясь. Он использует закрытый список тайлов, которым уже было дано светлое значение, чтобы избежать многократного попадания в одну ячейку. Это должно теоретически значительно повысить эффективность.

К сожалению, похоже, что с ней произошла ошибка, возможно, более одной. Мой усталый мозг не может определить его (или их), поэтому я был бы очень признателен за помощь. Имеет ли это смысл?

Кроме того, если вам это может понадобиться, вот класс Tile:

function Tile(x,y,character, thisMap, blocked, blockSight) {
    this.x = x;
    this.y = y;
    this.character = character;
    this.blocked = blocked;
    this.blockSight = blockSight;
    this.lightValue = 25;

    this.neighbors = new Array();
}

Tile.prototype = {
    create: function(blocked, blockSight, character) {
        this.blocked = blocked;
        this.blockSight = blockSight;
        this.character = character;

        var rockTile = RandomRange(1,4);
        var rockTileStr = "rock"+rockTile;
    },

    draw: function() {
        var id = '#t' + this.x + '_' + this.y;

        var lightColor = this.lightValue/100;

        $(id).css("opacity", lightColor); 
    },

    assign: function() {
        var north = this.x-1;
        var south = this.x+1;
        var east = this.y+1;
        var west = this.y-1;

        if(north >= 0 && south <= mapSizeX && west >= 0 && east <= mapSizeY) {

            //1st: we add the northwest neighbor.
            // *|/
            // -#-
            // /|\
            this.neighbors[0] = map[north][west];

            //2nd: we add the north neighbor.
            // \*/
            // -#-
            // /|\
            this.neighbors[1] = map[north][this.y];

            //3rd: we add the northeast neighbor.
            // \|*
            // -#-
            // /|\
            this.neighbors[2] = map[north][east];

            //4th: we add the east neighbor.
            // \|/
            // -#*
            // /|\
            this.neighbors[3] = map[this.x][east];

            //5th: we add the southeast neighbor.
            // \|/
            // -#-
            // /|*
            this.neighbors[4] = map[south][east];

            //6th: we add the south neighbor.
            // \|/
            // -#-
            // /*\
            this.neighbors[5] = map[south][this.y];

            //7th: we add the southwest neighbor.
            // \|/
            // -#-
            // *|\
            this.neighbors[6] = map[south][west];

            //8th: we add the west neighbor.
            // \|/
            // *#-
            // /|\
            this.neighbors[7] = map[this.x][west];
        }
    },
}

Спасибо и извинения за размещение такого длинного вопроса; Я просто не знаю, куда еще обратиться в данный момент.

1 Ответ

1 голос
/ 15 апреля 2011

Я вижу следующую опечатку:

самое высокое значениеLightValue = соседей [j];

должно быть

самое высокое значение LightValue = соседей [j] .light;

Кроме того, если вы беспокоитесь об эффективности, вы можете изменить способ хранения набора закрытых элементов.С массивом закрытых тайлов вам нужно O (n) время для выполнения FindValue (фактически, с текущими реализациями массивов JavaScript, O (n * log (n))).Если вы используете массив значений true / false, проиндексированных идентификатором тайла, вы получите O (1) (или O (log (n)) в реальном мире JavaScript.Поскольку это находится во внутреннем цикле расчета, ускорение может быть заметным.

...