开发者

Javascript scripting error

After reading up on Field of View algorithms,开发者_运维问答 I decided to create one myself for a game I'm working on. After a couple of hours, I came up with the following script:

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;
}

It's supposed to spread a light-value outward from a source, decreasing as it goes. It uses a Closed list of tiles which have already been given a light value in order to avoid hitting a single cell multiple times. This should theoretically increase the efficiency a lot.

Unfortunately, there seems to be an error, perhaps more than one, with it. My tired brain is failing to locate it (or them), so I would really appreciate some help with this. Does it even make sense?

Also, in case you might need it, here's the Tile class:

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];
        }
    },
}

Thanks, and apologies for posting such a long question; I just don't know where else to turn at the moment.


I can see the following typo:

highestLightValue = neighbors[j];

should be

highestLightValue = neighbors[j].light;

Furthermore, if you are concerned about efficiency, you might want to redesign how you store the set of closed elements. With the array of closed tiles you need O(n) time to execute FindValue (in fact, with current implementations of javascript arrays, O(n*log(n))). If you use an array of true/false indexed by a tile id, you get O(1) (or O(log(n)) in the real javascript world). Since this is in the inner loop of the calculation, the speedup may be noticeable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜