using canvas engine and tiled map editor get "Uncaught TypeError: Cannot read property 'firstgid' of undefined"

using canvas engine and tiled map editor get "Uncaught TypeError: Cannot read property 'firstgid' of undefined"

我正在用 javascript 和 HTML5 canvas 编程游戏,我在绘制地图时遇到一个错误。

我使用 canvasEngine 框架提供的 Tiled class,但出现此错误:

Uncaught TypeError: Cannot read property 'firstgid' of undefined

Tiled.js 行 1.

有我的map.json文件:

{ "height":400,
"layers":[
    {
     "compression":"zlib",
     "data":"eJzt3U1u20YYBmAZaLY+gFctklP0B2m3\/blA7VzAdtfOXZJF7W17g\/Yctm\/Q5BalkApVJA45M\/woUuLzAIOBGIh2vJgXesUhP9ytVl+8XeYAoN7umvpiBuu6DAGYv+219GPHZ5Hv7\/pH7Rpecq7Uv9f+bgDU2ayj\/yTW2JzcOKYhPwBilH42uDrC0ZUhANQpyY83zfjzYrX64+K45kv5ARAuNz9+aMa7Zi1+f3F88zpHXssPgFBLyI938gMgXEl+TN1DDZlfJzosAOqU5MdfzTr898VxzvIDINYS+yv5ATBc7rVX+isAtpXkxxx6KP0VwDzorwCo4forAGpEXX91fbZ\/\/L45dttyvGYeen75ARArqr9ar+W7x9fH2o7XzEPPn8oPOQJQJ6q\/Wq\/ju8c363tE\/zT0\/PIDIFZUf3Wf6JfajtfMQ8+fkx9yBCBfZH\/VNh4C+6sh50\/d\/8rnEIA6Uf3VY2J9fw7qr4aev+\/zh\/wAKBPVX819lh8AsZa+f1B+ANRZ6v7BVIYAkKcrO74asb8ae7+h\/gpgXKl19MXbz9fb6P5q7P2G+iuAceV0V2P0V2PvN8zpr+QIQL2Szx+RfdLY+w37+iv5ATBMzmePsfqrMfcb9vVX8gNgmPVa+aFZRz\/e9edHZJ809n5D\/RXAuLb7qlR2nOL+QfcyARhmvU5+mfn9+SH3+03dX8kQgG5TXX81h\/2DOfkhQwDaleTHHHqo6P7KZxCAOiX5MYceKrq\/kiEAdaL6q\/X9SG7O9o\/fBl1Pdd1ynpuz\/PPLD4BYUf3V7\/9df7t7\/GGmzx+UHwDDRPVXm\/zYPh65H\/Cp5TzrY23HS\/sr2QFQLic7cvqrTX7s3s\/qIai\/Su1Xz71flvwAiFWSHzn9Vdv9SKL6q6eW8z8N7K9cvwtQpyQ\/uvqhx7P\/+6Tt8RzUXw09v\/3nALGi+qu5zpsMqemvAEiL6q\/mOm+ypCQ\/AOgX1V\/Ndd5kSd\/1u7sDgG76KxkCUCNq\/+Bc55z+Sn4AlIvaPzjXOae\/aiNXALqV5Mcc+qja+bL5\/a8So4QMAfjk1Purzfz1+Wr1TTO+bcZ35\/uvAShz6v3VZv6xyYifmvFzM345338NQJml9Fe\/Nhlx2YyrZrw5338NQJml9FfXTUbcNOO2Gb+d778GoEzfvQNPpb\/y\/QdArJL8qOmNrhPPfep6bmDXe2r7K99\/AMQqyY+a3ui+5f64fc8N7HpPbX\/l+w+AWGP3V23Pd9pkQep9Xe+p7a98\/wEQ6xD50fb5oi8\/Uu8p+fkvm9\/5VeYAoMzY1++mnjnb9VzbrveU\/PySe14BUGbs63cfE1nw3PH9R9d7Sn6+\/AAYzyk\/\/yM3PwAod8rP\/5AfAOMpyY+a\/mrKWX4AjEd\/JUMAauiv5AdADf2V\/ACoob\/6NDb\/783fBIBu+qvP\/9\/bfxMA0vRX6b8BAGlL76\/67v8FQLul91fyA6DOkvurvuyQHwBpS+6v5AdAvaX2VznZIUMA0pbYX5Vkh\/wAaLfE\/kp+AAy3xP5KfgAMp7+SHQA1lthflWQIAO2W2F\/JD4DhcrLj1Por+z8AhivJj6n7qMj+Sn4ADFOSH1P3UdH3v+rKDPkB0E1\/JT8Aaiz1+iv9FcAwS73+Sn4ADFOSH1P3UYe+\/gqAtCX3V6kMAaDfkvsr+QFQb8n9lfwAqKe\/kh8ANU41P15mZIf8AKjXdf3R7lr76ohGTnbID4B6JflxasN1uwD1cvbQTb3OHzI75AdAnpz82M2SU8gX+QEwTGl+RI7Sdb0mr3LyT3YAlJsyPw6RTaXvAyDP1Ov83AYA5aZeu+UGwHGbei2XHQCnY+o1XnYAHK+p13rZAcChyAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACj3L9pFmH4=",
     "encoding":"base64",
     "height":400,
     "name":"sol",
     "opacity":1,
     "type":"tilelayer",
     "visible":true,
     "width":400,
     "x":0,
     "y":0
    }, 
    {
     "compression":"zlib",
     "data":"eJzt2kFOFUEUQNG\/jr9jFJxjonMIOpeocxSYE4W1WERYgHfSVe05SaWnL3\/wKrf7Hw4AAAAAAAAAwL86OR4Ob8Z5+3JOJ36ejfPuuPUvBsDz3XG52D52hwBs73zs4feL7eIPY96Pi80MsDcXC\/bHpzHv58VmBtibL2MPXy+2i7+Neb8vNjPA3tyMPfxjsV2sPwC2t+L7K\/0BsL0V31\/pD4Dt6Q8ACv0BQKE\/ACj0BwCF\/gCg0B8AFPoDgEJ\/AFDoDwAK\/QFAoT8AKPQHAIX+AKDQHwAU+gOAQn8AUOgPAAr9AUChPwAo9AcAhf4AoNAfABT6A4BCfwBQ6A8ACv0BQKE\/ACj0BwCF\/gCg0B8AFPoDgEJ\/AFDoDwAK\/QFAoT8AKPQHAIX+AKDQHwAU+gOAQn8AUOgPAIrV+uN2zHo3zv1CMwPs0Ur98XpvPI7ztMjMAHu1Sn88f\/M4c28ATGOV\/vDNA2AuK\/WH\/1wBzEN\/AFDoDwAK\/QFAoT8AKPQHAIX+AKDQHwAU+gOAQn8AUOgPAAr9AUChPwAo9AcAhf4AoNAfABT6A4BCfwBQ6A8ACv0BQKE\/ACj0BwCF\/gCg0B8AFPoDgEJ\/AFDoDwAK\/QFAoT8AKGbvj6uX2fQHwFxm74+vx793x9049xPPCfC\/uRk7+ec4txM\/X++OJ\/cHwDQexk7+Nc7viZ+P7g4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICl\/AGj9H5s",
     "encoding":"base64",
     "height":400,
     "name":"relief",
     "opacity":1,
     "type":"tilelayer",
     "visible":true,
     "width":400,
     "x":0,
     "y":0
    }, 
    {
     "compression":"zlib",
     "data":"eJzt3cePVXUcxuHDnVHc2AuIvdH+Ad24soC9Cyptp4m9S+\/FrrTEpb1LrwPYlba3d+l1ALuCL0sXJsfJMcO98zzJZ3fzy1193wXMTFEAAAAAAAAAAAAAAAAAAAAAAABAfRpdK4oxaWwal8bXqn3\/1rx3W7o93ZHurPh9ANrHgtzzhWlRWpyWVHzfn817z6Xn0wvpRfsB0BC25J5vTdvS9rSj4vv+Sd77NH2WPk9f2A+AhnBaU1Gcns5IZ6azmqp9\/9C8d1g6PB2Rjqz4fQDaR7\/c8\/7phnRjuqni+35e3js\/XZAuTH3sB0BDeDz3\/In0ZHoqPV3xfR+a94al4WlEGmk\/ABrC+7nnH6QP00fp44rv+6y8NzvNSXPTPPsB0BB+yz3\/Pf2R\/kx\/VXzf1+W99WlD2pg22Q8AAKCkCbWimJgmpclpiv+PC0AJS7MXLWlZWp5W2A8AStiZvWhNu9LutMd+AFBC96ai6JF6pl6pt38PB6CEAdmLgWlQGpyG2A8ASpiavZiWpqcZaab9AKCEldmLVWl1WpPW2g8AStibvdi3fzOai6JTqjW39zcCAAAAAAD4p\/trRfFAejA9lIZW\/POAd+W9u9M96d50n583BGgIr+eev5HeTG+lWRXf95fy3svplfRqes1+ADSE73LPv08\/pB\/Tuorv+5d576v0dfomfWs\/ABpCl6ai6JqOT93SCRX\/PMdRee\/odEw6Nh3n50UAGsJlueeXpyvSlemqiu9737x3Ubo4XZIutR8ADWF87vmENDFNSpMrvu+j8t7oNCaNTePsB0BDWJJ7vjS1pGVpecX3fX7eW5AWpkVpsf0AaAg7cs93pta0K+2u+L5vzntb0ta0LW23HwAAAAAAwAHqmYPa+xsAAAAdTeeD2\/sbAFCPzrUfABwgOncrikO6tfe3AKDedMl2dLUfAPxHPbIdPe0HQF0aViuK4WlEGplGlfi7HRPymYlpUpqcprTxb32cne04x34A1KXZuf1z0tw0L80vsQVL85mWtCwtTyvauB99sh197QdAXVqf278hbUyb0uYSW7Azn2lNu9LutMd+AHQ4JzYVxUnp5HRKOrXE783tns\/0SD1Tr9S7jb9rt1+2o7\/9AKhLV+f2X5OuTdel60tswYB8ZmAalAanIW3cj5uzHbfYD4C6NCW3\/+H0SHo0PVZiC6bmM9PS9DQjzfS3PgA6nBW5\/W+nd9K76b0SW7Ayn1mVVqc1aa39AOhw9uT2\/5R+Tr+kX0tswd58Zt\/+zzUXRadUa\/7fvyYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8q78BhFapnA==",
     "encoding":"base64",
     "height":400,
     "name":"batiments",
     "opacity":1,
     "type":"tilelayer",
     "visible":true,
     "width":400,
     "x":0,
     "y":0
    }, 
    {
     "compression":"zlib",
     "data":"eJzt3UFOwkAUBuC6gCMoKNxIQeGieim9gyuHGBJSLS3TKe0M37cxIbS4en\/eTDuvqgAAAAAAAAAAAODX8m7s\/wCAHG3lB0AWVqFer9VsAC60C9mxlx8AjKBLD\/MtowCo0cMAAACpNa1BWZsCAAAAAABy8D6rqo9ZvvcHYByfobZ\/DVjfh74\/AONYzatqPf\/7eapnrZruD0DedqG27wes70PfH4D89O1RvE8CAAAAAABcgzlTAMRoO6O97X3A+p64PALIV8oafsn7gIcsMTMEIF8pa7j3AQGI4X1AAACgK7MFAZgS+QPAf+QDAAAAAFNm\/Qrg9pyr\/eafAxCj6TyS+5A5Dwl6DvPPAcrUdB7Jc8iOlwT54bwTgDKZfw7AtaVa4wLgtvRd4\/JMF0A+1GwAUumSKYfvyB4Ark32AORtEer4sqWWn6v1XXLgMXznSV4AFGUT6vp24Nr+Gu7\/Jj8AipIqP\/qsR1nLAgAAhqTnAAAAAKAra0kAdDF2Xoz9+wBcT8zcwLZrFnIEoHgxcwPbrtnID4DixcwNNGsQoDyX7kHEzA00axCgXPayAQCAodT7DWerAxDD2eoADEnfAkAK5\/qW06w5nZMucwDo4pgbx7\/WygDK0\/Yc76XP+Z72HTHXAzBN9XreNz+65IMMAShPvV8AgBh9ssQ+OQAx7JMDkJo1MgAAuE16AQAAYKpi+xV9DgAAAAAAMAZ7FABMmbNNAIjhbBMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgOn5Abr7YNM=",
     "encoding":"base64",
     "height":400,
     "name":"decors",
     "opacity":1,
     "type":"tilelayer",
     "visible":true,
     "width":400,
     "x":0,
     "y":0
    }],
"nextobjectid":1,
"orientation":"orthogonal",
"properties":
{

},
"renderorder":"right-down",
"tileheight":16,
"tilesets":[
    {
     "firstgid":1,
     "image":"..\/tilesets\/tileset1.png",
     "imageheight":705,
     "imagewidth":864,
     "margin":0,
     "name":"tileset1",
     "properties":
        {

        },
     "spacing":0,
     "tilecount":2376,
     "tileheight":16,
     "tilewidth":16
    }, 
    {
     "firstgid":2377,
     "image":"..\/tilesets\/tileset2.png",
     "imageheight":28000,
     "imagewidth":256,
     "margin":0,
     "name":"tileset2",
     "properties":
        {

        },
     "spacing":0,
     "tilecount":28000,
     "tileheight":16,
     "tilewidth":16
    }, 
    {
     "firstgid":30377,
     "image":"..\/tilesets\/tileset3.png",
     "imageheight":800,
     "imagewidth":477,
     "margin":1,
     "name":"tileset3",
     "properties":
        {

        },
     "spacing":1,
     "tilecount":1316,
     "tileheight":16,
     "tilewidth":16
    }],
"tilewidth":16,
"version":1,
"width":400
}

这是我的 app.js 我调用场景的地方:

 canvas.Scene.New({
  name: "map", // Obligatory
 materials: {
    images: {
        tileset1: "tilesets/tileset1.png",
        tileset2: "tilesets/tileset2.png",
        tileset3: "tilesets/tileset3.png"
    }
  },
  called: function(stage) {

  },
  preload: function(stage, pourcent, material) {

  },
  ready: function(stage, params) {

var tiled = canvas.Tiled.new();
tiled.load(this, stage, "maps/map.json");
tiled.ready(function() {
//sol = this.getLayer('sol');
});

  },
  render: function(stage) {
stage.refresh();
  },
  exit: function(stage) {

  }
});

谢谢你的帮助,抱歉我的英语可能不好。

编辑:这里是 Tiled.js 文件:

/*
Copyright (C) 2012 by Samuel Ronce

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

if (typeof exports != "undefined") {
    var CE = require("canvasengine").listen(),
        CanvasEngine = false,
        Class = CE.Class;
}

Class.create("Tiled", {
    el: null,
    url: "",
    tile_w: 0,
    tile_h: 0,
    tile_image_h:0,
    tile_image_w:0,
    tilesets: [],
    width: 0,
    height: 0,
    layers: [],
    objects: {},
    scene: null,
    _ready: null,
    initialize: function() {
    },
     /**
        @doc tiled/
        @method ready Calls the function when the layers are drawn
        @param {Function} callback
     */
    ready: function(callback) {
        this._ready = callback;
    },
/**
@doc tiled/
@method load Load JSON file and draw layers in the element of the scene. View Tiled class description for more informations (http://canvasengine.net/doc/?p=editor.tiled)
@param {CanvasEngine.Scene} scene
@param {CanvasEngine.Element} el The element containing layers of Tiled
@param {String} url Path to JSON file of Tiled Map Editor
@example

Example with Node.js :

Server :

    var CE = require("canvasengine").listen(8333),
        Tiled = CE.Core.requireExtend("Tiled").Class,
        Class = CE.Class;

    CE.Model.init("Main", {

        initialize: function(socket) {

            var tiled = Class.New("Tiled");
            tiled.ready(function(map) {
                socket.emit("Scene_Map.load", map);
            });
            tiled.load("Map/map.json");

        }
    });

Client :

    canvas.Scene.New({
        name: "Scene_Map",
        events: ["load"],
        materials: {
            images: {
                tileset: "my_tileset.png"
            }
        },
        load: function(data) {

            var tiled = canvas.Tiled.New();

            tiled.ready(function() {
             var tile_w = this.getTileWidth(),
                 tile_h = this.getTileHeight(),
                 layer_object = this.getLayerObject();
            });

            tiled.load(this, this.getStage(), data);

        }

    });

*/
    load: function(scene, el, url) {
        var self = this;

        if (typeof scene == "string") {
            this.url = url = scene;
        }
        else {
            this.el = el;
            this.url = url;
            this.scene = scene;
        }

        function ready(data) {
            var clone_data = CE.Core.extend({}, data);
            self.tile_h = data.tileheight;
            self.tile_w = data.tilewidth;
            self.width = data.width;
            self.height = data.height;
            self.tilesets = data.tilesets;
            self.layers = data.layers;
            self.tilesetsIndexed = [];

            for (var i=0 ; i < self.tilesets.length ; i++) {
                var props = self.tilesets[i].tileproperties,
                    new_props = {};
                if (props) {
                    for (var key in props) {
                        new_props[+key+1] = props[key];
                    }
                    self.tilesets[i].tileproperties = new_props;
                }
                self.tilesetsIndexed[self.tilesets[i].firstgid] = self.tilesets[i];
            }

            //
            // Check to see if the tileset uses a different height/width to the layer
            // For example, pseudo-3d tiles such as PlanetCute are 101x171 sprites 
            // on a Tiled layer grid of 101x80
            //
            if (self.tilesets[0].tileheight && self.tilesets[0].tilewidth) {
                self.tile_image_h = self.tilesets[0].tileheight;
                self.tile_image_w = self.tilesets[0].tilewidth;
            } else {
                self.tile_image_h = self.tile_h;
                self.tile_image_w = self.tile_w;
            }
            var _id, length = self.tilesetsIndexed.length + (Math.round(self.tilesets[self.tilesets.length-1].imageheight / self.tile_h) * (Math.round(self.tilesets[self.tilesets.length-1].imagewidth / self.tile_w)));

            for (var m=0; m < length; m++) {
                _id = self.tilesetsIndexed[m] ? m : _id;
                self.tilesetsIndexed[m] = self.tilesetsIndexed[_id];
            }

            if (typeof exports == "undefined") {
                self._draw();
            }
            else {
                if (self._ready) self._ready.call(self, clone_data);
            }


        }

        if (typeof url === 'string') {
            (CanvasEngine || CE.Core).getJSON(this.url, ready);
        }   
        else {
            ready(url);
        }

    },

    _drawTile: function(_id, layer_name, data) {
        var _tile = this.scene.createElement(),
            tileset, tileoffset, nb_tile = {};

        if (data.position != "absolute") {
            data.x *= this.tile_w;
            data.y *= this.tile_h;
        }

        var flippedHorizontally = false, flippedVertically = false, flippedAntiDiagonally = false;
        if (_id & Tiled.FlippedHorizontallyFlag) {
            flippedHorizontally = true;
        }
        if (_id & Tiled.FlippedVerticallyFlag) {
            flippedVertically = true;
        }
        if (_id & Tiled.FlippedAntiDiagonallyFlag) {
            flippedAntiDiagonally = true;
        }

        _id &= ~(Tiled.FlippedHorizontallyFlag | Tiled.FlippedVerticallyFlag | Tiled.FlippedAntiDiagonallyFlag);

        tileset = this.tilesetsIndexed[_id];
        _id -= tileset.firstgid;

        nb_tile = {
            width: tileset.imagewidth / this.tile_image_w,
            height: tileset.imageheight / this.tile_image_h 
        };

        tileoffset = tileset.tileoffset || {x: 0, y: 0};

        y = this.tile_image_h * Math.floor(_id / (nb_tile.width - (nb_tile.width / 2 * tileset.margin)));        
        x = this.tile_w * (_id % Math.round((tileset.imagewidth - nb_tile.height / 2 * tileset.margin) / this.tile_w));

        _tile.drawImage(tileset.name, x + tileset.spacing * x / this.tile_w + tileset.margin, y + tileset.spacing * y / this.tile_h + tileset.margin, this.tile_w, this.tile_h, data.x + tileoffset.x, data.y + tileoffset.y, this.tile_w, this.tile_h);
        this.el_layers[layer_name].append(_tile);
        var scaleX = (flippedHorizontally) ? -1 : 1,
            scaleY = (flippedVertically) ? -1 : 1,
            rotation = 0;

        if (flippedAntiDiagonally) {
            rotation = 90;
            scaleX *= -1;

            halfDiff = nb_tile.height/2 - nb_tile.width/2
            y += halfDiff
        }
        _tile.drawImage(tileset.name, x + tileset.spacing * x / this.tile_image_w + tileset.margin, y + tileset.spacing * y / this.tile_image_h + tileset.margin, this.tile_image_w, this.tile_image_h, 0, 0, this.tile_image_w, this.tile_image_h);
        _tile.x = data.x + tileoffset.x
        _tile.y = data.y + tileoffset.y
        _tile.width = this.tile_w
        _tile.height = this.tile_h
        _tile.setOriginPoint("middle");
        _tile.scaleX = scaleX
        _tile.scaleY = scaleY
        _tile.rotation = rotation

        if (data.visible === false) {
            _tile.hide();
        }

        this.el_layers[layer_name].append(_tile);

        return _tile;
    },

    _draw: function() {
        this.map = this.scene.createElement();
        this.el_layers = {};
        var x, y, tileset, layer, self = this;
        var id, _id, obj, layer_type, el_objs = {};

        for (var i=0 ; i < this.layers.length ; i++) {
            id = 0;
            layer = this.layers[i];
            this.el_layers[layer.name] = this.scene.createElement();
            if (layer.type == "tilelayer") {
                for (var k=0 ; k < layer.height ; k++) {
                    for (var j=0 ; j < layer.width ; j++) {
                        _id = layer.data[id];
                        if (_id != 0) {                     
                            this._drawTile(_id, layer.name, {
                                x: j,
                                y: k
                            });
                        }
                        id++;
                    }
                }
            }
            else if (layer.type == "objectgroup") {
                for (var j=0 ; j < layer.objects.length ; j++) {
                    obj = layer.objects[j];
                    if (!el_objs[obj.name]) el_objs[obj.name] = [];

                    if (obj.gid) {
                        el_objs[obj.name].push(this._drawTile(obj.gid, layer.name, CE.extend(obj, {
                            y: obj.y - this.tile_h,
                            position: "absolute"
                        })));
                    }
                }
                this.objects[layer.name] = {
                    layer: this.el_layers[layer.name],
                    objects: el_objs
                };
            }
            this.map.append(this.el_layers[layer.name]);
        }
        this.el.append(this.map);
        if (this._ready) this._ready.call(this);
    },
     /**
        @doc tiled/
        @method getLayerObject Retrieves the object layer.
        @param {Integer} name  Returns the layer by name
        @return {CanvasEngine.Element}
     */
    getLayerObject: function(name) {
        if (!name) {
            for (var id in this.objects) {
                name = id;
                break;
            }
        }
        if (!this.objects[name]) {
            return false;
        }
        return this.objects[name].layer;
    },


    // TODO
    getObject: function(layer_name, obj_name, pos) {
        if (!pos) pos = 0;
        return this.objects[layer_name].objects[obj_name][pos];
    },

     /**
        @doc tiled/
        @method getLayer Retrieves the layer by its identifier.
        @param {String} id Layer name in Tiled Map Editor
        @return {CanvasEngine.Element}
     */
    getLayer: function(id) {
        return this.el_layers[id];
    },
     /**
        @doc tiled/
        @method getMap Returns the element containing all the layers
        @return {CanvasEngine.Element}
     */
    getMap: function() {
        return this.map;
    },
     /**
        @doc tiled/
        @method getTileWidth Returns the width of the map in tiles 
        @return {Integer}
     */
    getTileWidth: function() {
        return this.tile_w;
    },
     /**
        @doc tiled/
        @method getTileHeight Returns the height of the map in tiles 
        @return {Integer}
     */
    getTileHeight: function() {
        return this.tile_h;
    },
     /**
        @doc tiled/
        @method getWidthPixel Returns the width of the map in pixels
        @return {Integer}
     */
    getWidthPixel: function() {
        return this.width * this.getTileWidth();
    },
     /**
        @doc tiled/
        @method getHeightPixel Returns the height of the map in pixels
        @return {Integer}
     */
    getHeightPixel: function() {
        return this.height * this.getTileHeight();
    },
     /**
        @doc tiled/
        @method getDataLayers Returns the data for each map
        @return {Array}
     */
    getDataLayers: function() {
        var layer = [];
        for (var i=0 ; i < this.layers.length ; i++) {
            if (this.layers[i].data) layer.push(this.layers[i].data);
        }
        return layer;
    },
     /**
        @doc tiled/
        @method getTileInMap Retrieves the position of a tile to the Tileset according positions X and Y
        @params {Integer} x Position X
        @params {Integer} y Position Y
        @return {Array}
     */
    getTileInMap: function(x, y) {
        return this.width * y + x;
    },
     /**
        @doc tiled/
        @method getTileProperties Gets the properties of a tile depending on its identifier
        @params {Integer} tile Id of tile
        @params {String} (optional) layer Layer name
        @return {Object}
     */
      /**
        @doc tiled/
        @method getTileProperties Gets the properties of a tile depending on its positions
        @params {Integer} tile Id of tile. Put "null"
        @params {Integer} x Positon X
        @params {Integer} y Positon Y
        @return {Object}
     */
    getTileProperties: function(tile, layerOrX, y) {
        var self = this;
        var tileset = this.tilesets[0];
        function _getTileLayers(tile) {
            var _layers = [];
            for (var i=0 ; i < self.layers.length ; i++) {
                if (self.layers[i].data) _layers.push(tileset.tileproperties[self.layers[i].data[tile]]);
            }
            return _layers;
        }

        if (layerOrX === undefined) {
            return _getTileLayers(tile);
        }
        else if (y !== undefined) {
            var new_tile = this.getTileInMap(layerOrX, y);
            return _getTileLayers(new_tile);
        }
        return tileset.tileproperties[this.layers[layerOrX].data[tile]];
    },

    tileToProperty: function(prop_name) {
        var layers = this.getDataLayers(), val;
        var new_layers = [];
        for (var i=0 ; i < layers.length ; i++) {
            new_layers[i] = [];
            for (var j=0 ; j < layers[i].length ; j++) {
                val = this.tilesets[0].tileproperties[layers[i][j]]; // Hack Tiled Bug
                new_layers[i][j] =  val ? +val[prop_name] : 0;
            }
        }
        return new_layers;
    }


});

/**
@doc tiled
@class Tiled Tiled is a general purpose tile map editor. It's built to be easy to use, yet flexible enough to work with varying game engines, whether your game is an RPG, platformer or Breakout clone. Tiled is free software and written in C++, using the Qt application framework.

http://www.mapeditor.org

Consider adding inserting Tiled.js

     <script src="extends/Tiled.js"></script>
     <script>
       var canvas = CE.defines("canvas_id").
        extend(Tiled).
        ready(function() {

        });
     </script>


@param {CanvasEngine.Scene} scene
@param {CanvasEngine.Element} el The layers are displayed on this element
@param {String} url Path to the JSON file of Tiled Map Editor
@example

    var canvas = CE.defines("canvas_id").
        extend(Tiled).
        ready(function() {
            canvas.Scene.call("MyScene");
        });

    canvas.Scene.new({
        name: "MyScene",
        materials: {
            images: {
                mytileset: "path/to/tileset.png"
            }
        },
        ready: function(stage) {
             var el = this.createElement();
             var tiled = canvas.Tiled.new();

            tiled.ready(function() {
                 var tile_w = this.getTileWidth(),
                     tile_h = this.getTileHeight(),
                     layer_object = this.getLayerObject();
                 stage.append(el);
            });
            tiled.load(this, el, "map/map.json");
        }
    });

1. `mytileset` in material object is the name of tileset in Tiled Map Editor
2. `getLayer()` retrieves a layer. The name is the same as in Tiled Map Editor

![](http://canvasengine.net/presentation/images/tiled2.png)

*/
var Tiled = {
    Tiled: {
        FlippedHorizontallyFlag: 0x80000000,
        FlippedVerticallyFlag: 0x40000000,
        FlippedAntiDiagonallyFlag: 0x20000000,
        New: function() { return this["new"].apply(this, arguments); },
        "new": function(scene, el, url) {
            return Class["new"]("Tiled", [scene, el, url]);
        }
    }
};

if (typeof exports != "undefined") {
    exports.Class = Tiled.Tiled;
}

编辑 2:我通过将编辑器中地图的编码修改为 XML.

解决了这个问题

我已经通过将编辑器中地图的编码修改为 XML 来解决这个问题。