【问题标题】:Javascript for loop not looping through arrayJavascript for循环不循环数组
【发布时间】:2015-09-13 18:02:08
【问题描述】:

我正在尝试为平台游戏级别读取 TMX 文件。我试图绘制图块集以查看我的代码是否正常工作。这就是我加载地图的方式:

function TileMapLayer(mapWidth, mapHeight, tileWidth, tileHeight, layerName, tileData) {
'use strict';
    var name = layerName,
    width = mapWidth, height = mapHeight,
    // An array of integers used to figure out whether there is a tile in the
    // player's position
    map = [width][height];
    // The tileset that makes up the tilemap
    this.tileSet = Game.res.getImage('tileSet');
    var data = tileData;

    function getWidth() {return width;}
    function getHeight() {return height;}
}

TileMapLayer.prototype.draw = function() {
        'use strict';
    ctx.beginPath();
    ctx.drawImage(this.tileSet, canvasWidth / 2, canvasHeight / 2);
    ctx.closePath();
};

function TileMap() {
    'use strict';
    this.mapLayers = [];
}

TileMap.prototype.loadFile = function(pathToFile) {
    'use strict';
    var xhr = new XMLHttpRequest();
    var that = this;
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
            // read in xml file
            var domParser = new DOMParser();
            var mapData = domParser.parseFromString(xhr.responseText, 'text/xml');
            var mapAttributes = mapData.getElementsByTagName('map')[0].attributes;
            // get tileset location
            var tileSet = mapData.getElementsByTagName('tileset')[0].getElementsByTagName('image')[0].attributes;
            Game.res.addImage('tileSet', '/home/agoston/Documents/js/platformer/res/maps/' + tileSet.getNamedItem('source').nodeValue);
            // get map & tile dimensions
            that.width = parseInt(mapAttributes.getNamedItem('width').nodeValue);
            that.height = parseInt(mapAttributes.getNamedItem('height').nodeValue);
            that.tileWidth = parseInt(mapAttributes.getNamedItem('tilewidth').nodeValue);
            that.tileHeight = parseInt(mapAttributes.getNamedItem('tileheight').nodeValue);

            // get layer data
            var layers = mapData.getElementsByTagName('layer');

            // create layers
            for(var i = 0; i < layers.length; ++i) {
                that.mapLayers[i] = new TileMapLayer(that.width, that.height, 
                                                                    that.tileWidth, 
                                                                    that.tileHeight,
                                                                    layers[i].attributes.getNamedItem('name').nodeValue,
                                                                    layers[i].getElementsByTagName('data')[0]);
            }

        }
    };
    xhr.open('GET', pathToFile, true);
    xhr.send(null);
};

TileMap.prototype.draw = function() {
    // this block of code doesn't execute
    for(var i = 0; i < this.mapLayers; ++i) {
        console.log('drawing map layers');
        this.mapLayers[i].draw();
    }
};

但是,应该通过地图图层数组的循环根本不循环。当我尝试使用以下方法绘制数组中的第一个地图图层时:

TileMap.prototype.draw = function() {
    this.mapLayers[0].draw();
};

它绘制了tileset图像,但它给出了这个错误:

TypeError: this.mapLayers[0] is undefined

有人知道为什么会这样吗?如果您愿意,可以在此处找到 TMX 文件:http://pastebin.com/MYdJCHfQ

【问题讨论】:

  • 你的意思是for(var i = 0; i &lt; this.mapLayers.length; ++i)
  • map = [width][height]; 应该做什么?
  • @scrapdog 是的。对不起,愚蠢的错误。
  • 请参考我的答案以获得优化的解决方案。
  • 我的猜测是,由于您正在执行 get 请求,因此在调用 draw 函数时地图图层未初始化,因为 get 需要一些时间来处理并且它是异步的

标签: javascript arrays


【解决方案1】:

似乎 mapLayers 是一个您想要迭代的数组,但是您缺少它的长度属性来告诉循环何时停止循环。也许这会有所帮助:

for(var i = 0, j = this.mapLayers.length; i < j; ++i) {
        console.log('drawing map layers');
        this.mapLayers[i].draw();
    }

【讨论】:

  • 谢谢。我把它改成了scrapdog在cmets中发布的内容。
猜你喜欢
  • 2015-05-21
  • 2018-11-24
  • 2013-06-16
  • 1970-01-01
  • 1970-01-01
  • 2018-10-25
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多