API Docs for: 0.1.0
Show:

File: cangaja/tilemap/map.js

                        /**
                         * @description
                         *
                         * CG.Map supports loading and rendering maps from the editor Tiled.
                         * XML and JSON file types are supported.
                         * XML => supported tiled encodings are csv and xml (see settings!). base64, base64(gzip) and base64(zlib) are not supported!
                         *
                         * Supported types of the object layer are:
                         * - object/group (rectangle?)
                         * - tile element, reference point is bottom/left of the tile in the editor
                         *
                         * These object layer types are used to generate Point and Bound objects and can be used to position sprites, what ever in the map.
                         *
                         * @class CG.Map
                         * @extends CG.Entity
                         *
                         * TODO spacing and margin ?
                         * TODO own buffer for drawing => split screen possible?
                         * TODO update & draw method 50%
                         *
                         */
                        CG.Entity.extend('Map', {
                            /**
                             * @method init
                             * @constructor
                             * @return {*}
                             */
                            init: function (options) {
                                this._super()
                                this.instanceOf = 'Map'
                        
                                /**
                                 * @property elements
                                 * @type {Array}
                                 */
                                this.elements = [] //how handle elements in maps? experimental collision detection at the moment with only one
                                //point and areas from tilemap editor
                                //using as references for external objects in layers?
                                //how to handle the relative position to the position of the map?
                        
                                /**
                                 * @property points
                                 * @type {Array}
                                 */
                                this.points = [] // position points (tiles) of tilemap editor => position point and type?
                                /**
                                 * @property areas
                                 * @type {Array}
                                 */
                                this.areas = [] // group objects e.g. area for objects of tilemap editor => bound and type?
                                /**
                                 * @property position
                                 * @type {CG.Point}
                                 */
                                this.position = new CG.Point(0, 0) // needed as relative point for points and areas
                                /**
                                 * @property mapOffset
                                 * @type {CG.Point}
                                 */
                                this.mapOffset = new CG.Point(0, 0)
                                /**
                                 * @property animDelayFactor
                                 * @type {Number}
                                 */
                                this.animDelayFactor = 20
                                /**
                                 * @property atlas
                                 * @type {Image}
                                 */
                                this.atlas = new Image()
                                /**
                                 * @property atlaswidth
                                 * @type {Number}
                                 */
                                this.atlaswidth = 0
                                /**
                                 * @property atlasheight
                                 * @type {Number}
                                 */
                                this.atlasheight = 0
                                /**
                                 * @property atlastranscol
                                 * @type {String}
                                 */
                                this.atlastranscol = '' //
                                //ejecta and cocoonjs has no DOMParser!
                                if (typeof ejecta === 'undefined' && !navigator.isCocoonJS) {
                                    /**
                                     * @property xml
                                     * @type {String}
                                     */
                                    this.xml = ''
                                    /**
                                     * @property parser
                                     * @type {DOMParser}
                                     */
                                    this.parser = new DOMParser()
                                    /**
                                     * @property xmlDoc
                                     * @type {String}
                                     */
                                    this.xmlDoc = ''
                                }
                                /**
                                 * @property json
                                 * @type {Object}
                                 */
                                this.json = {}
                                /**
                                 * @description
                                 *
                                 * The tiled layer are parsed into separate layers
                                 *
                                 * @property layers
                                 * @type {Array}
                                 */
                                this.layers = [] //can contain maptilelayer or objectlayer
                                /**
                                 * @description
                                 *
                                 * Defines the layer to draw:
                                 * all - for all layers
                                 * name - the name of layer to draw
                                 * index - array index of layer
                                 *
                                 * @property renderlayer
                                 * @type {String}
                                 */
                                this.renderlayer = 'all' //render layer: all for all layers, name of layer or array index for example 0 ;o)
                                /**
                                 * @property tileproperties
                                 * @type {Array}
                                 */
                                this.tileproperties = [] //properties of the tiles
                                /**
                                 * @property orientation
                                 * @type {String}
                                 */
                                this.orientation = ''
                                /**
                                 * @property width
                                 * @type {Number}
                                 */
                                this.width = 0
                                /**
                                 * @property height
                                 * @type {Number}
                                 */
                                this.height = 0
                                /**
                                 * @property mapColumns
                                 * @type {Number}
                                 */
                                this.mapColumns = 0
                                /**
                                 * @property mapRows
                                 * @type {Number}
                                 */
                                this.mapRows = 0
                                /**
                                 * @property tilewidth
                                 * @type {Number}
                                 */
                                this.tilewidth = 0
                                /**
                                 * @property tileheight
                                 * @type {Number}
                                 */
                                this.tileheight = 0
                                /**
                                 * @property tileset
                                 * @type {Object}
                                 */
                                this.tileset = {
                                    tilewidth: 0,
                                    tileheight: 0,
                                    offsetx: 0,
                                    offsety: 0,
                                    spacing: 0,
                                    margin: 0
                                }
                                /**
                                 * @property xspeed
                                 * @type {Number}
                                 */
                                this.xspeed = 0
                                /**
                                 * @property yspeed
                                 * @type {Number}
                                 */
                                this.yspeed = 0
                                /**
                                 * @property xscale
                                 * @type {Number}
                                 */
                                this.xscale = 1
                                /**
                                 * @property yscale
                                 * @type {Number}
                                 */
                                this.yscale = 1
                                /**
                                 * @property alpha
                                 * @type {Number}
                                 */
                                this.alpha = 1
                                /**
                                 * @property wrapX
                                 * @deprecated
                                 * @type {Boolean}
                                 */
                                this.wrapX = false //stuff from diddy?
                                /**
                                 * @property wrapY
                                 * @deprecated
                                 * @type {Boolean}
                                 */
                                this.wrapY = false //stuff from diddy?
                                /**
                                 * @property layertocheck
                                 * @type {Number}
                                 */
                                this.layertocheck = 0 //as default use layer 0 for collision detection
                        
                                CG._extend(this, options)
                        
                                return this
                            },
                            /**
                             * @description
                             *
                             * Load and parse an xml tilemap file. It can handle the tiled XML and CSV format.
                             * All other formats are not supported!
                             *
                             * @method loadMapXml
                             * @param xmlfile {string/object} xmlfile path or mediaasset object with data of tiled map xml
                             */
                            loadMapXml: function (xmlfile) {
                                this.layers = []
                        
                                //from asset
                                if (typeof xmlfile == 'string') {
                                    this.xml = loadString(xmlfile)
                                } else {
                                    this.xml = xmlfile.data
                                }
                                this.removeJsonData()
                        
                                this.xmlDoc = this.parser.parseFromString(this.xml, 'text/xml')
                        
                                //get map
                                var tilemap = map.xmlDoc.getElementsByTagName('map')[0]
                                this.orientation = tilemap.getAttribute('orientation')
                                this.mapColumns = parseInt(tilemap.getAttribute('width'))
                                this.mapRows = parseInt(tilemap.getAttribute('height'))
                                this.tilewidth = parseInt(tilemap.getAttribute('tilewidth'))
                                this.tileheight = parseInt(tilemap.getAttribute('tileheight'))
                        
                                var childcount = tilemap.childElementCount
                        
                                //tilemap.firstElementChild.nextElementSibling.nextElementSibling
                                var element = tilemap.firstElementChild
                                for (var i = 0; i < childcount; i++) {
                                    console.log('>' + element.nodeName)
                                    switch (element.nodeName) {
                                        case 'tileset':
                                            //read tileset settings
                                            //only one tileset for the moment
                                            this.tileset.tilewidth = parseInt(element.getAttribute('tilewidth'))
                                            this.tileset.tileheight = parseInt(element.getAttribute('tileheight'))
                                            if (element.getAttribute('spacing')) {
                                                this.tileset.spacing = parseInt(element.getAttribute('spacing'))
                                            }
                                            if (element.getAttribute('margin')) {
                                                this.tileset.margin = parseInt(element.getAttribute('margin'))
                                            }
                                            if (element.getElementsByTagName('tileoffset')[0]) {
                                                this.tileset.offsetx = parseInt(element.getElementsByTagName('tileoffset')[0].getAttribute('x'))
                                                this.tileset.offsety = parseInt(element.getElementsByTagName('tileoffset')[0].getAttribute('y'))
                                            }
                                            var image = element.getElementsByTagName('image')[0]
                                            this.atlas.src = 'media/map/' + image.getAttribute('source')
                        
                                            this.atlaswidth = parseInt(image.getAttribute('width'))
                                            this.atlasheight = parseInt(image.getAttribute('height'))
                                            this.atlastranscol = image.getAttribute('trans')
                        
                                            break
                                        case 'layer':
                                            //get tilemap data of layer
                                            var tl = new CG.MapTileLayer()
                                            data = element.getElementsByTagName('data')[0]
                        
                                            if (data.getAttribute('encoding') == 'csv') {
                                                tl.tiles = data.textContent.replace(/(\r\n|\n|\r)/gm, '').split(',')
                                                console.log('map encoding csv [layer ' + i + ']')
                                            } else if (data.getAttribute('encoding') == 'base64' && data.getAttribute('compression') == 'gzip') {
                                                throw 'base64 gzip compressed map format not supported at the moment'
                                            } else if (data.getAttribute('encoding') == 'base64' && data.getAttribute('compression') == 'zlib') {
                                                throw 'base64 zlib compressed map format not supported at the moment'
                                            } else if (data.getAttribute('encoding') == 'base64') {
                                                throw 'base64 map format not supported at the moment'
                                            } else {
                                                console.log('map encoding xml [layer ' + i + ']')
                                                var tiles = element.getElementsByTagName('tile')
                                                for (x in tiles) {
                                                    if (x < tiles.length) {
                                                        tl.tiles[x] = parseInt(tiles[x].getAttribute('gid'))
                                                    }
                                                }
                                            }
                        
                                            tl.name = element.getAttribute('name')
                                            tl.width = parseInt(element.getAttribute('width'))
                                            tl.height = parseInt(element.getAttribute('height'))
                                            if (element.getAttribute('opacity')) {
                                                tl.opacity = parseFloat(element.getAttribute('opacity'))
                                            }
                                            if (element.getAttribute('visible') === '0') {
                                                tl.visible = false
                                            }
                                            this.layers.push(tl)
                                            break
                                        case 'objectgroup':
                                            //get tilemap data of grouplayer
                                            console.log('grouplayer found')
                                            var objects = element.getElementsByTagName('object')
                                            for (o in objects) {
                                                if (o < objects.length) {
                                                    var obj = objects[o]
                                                    var name = obj.getAttribute('name')
                                                    if (obj.getAttribute('gid')) {
                                                        //tile as object/point
                                                        this.points.push(
                                                            new CG.MapPoint({
                                                                position: new CG.Point(
                                                                    parseInt(obj.getAttribute('x')),
                                                                    parseInt(obj.getAttribute('y'))
                                                                ),
                                                                mapOffset: this.position,
                                                                name: obj.getAttribute('name'),
                                                                gid: parseInt(obj.getAttribute('gid'))
                                                            })
                                                        )
                                                        console.log('tile as oject found: ' + name)
                                                        console.log(obj)
                                                    } else if (obj.getAttribute('width')) {
                                                        type = false
                                                        properties = obj.getElementsByTagName('property')
                                                        console.log(properties.length)
                                                        for (var p = 0, l = properties.length; p < l; p++) {
                                                            if (properties[p].getAttribute('name') == 'type') {
                                                                type = properties[p].getAttribute('value')
                                                            }
                                                        }
                        
                                                        //object group
                                                        this.areas.push(
                                                            new CG.MapArea({
                                                                bound: new CG.Bound({
                                                                    x: parseInt(obj.getAttribute('x')),
                                                                    y: parseInt(obj.getAttribute('y')),
                                                                    width: parseInt(obj.getAttribute('width')),
                                                                    height: parseInt(obj.getAttribute('height'))
                                                                }),
                                                                mapOffset: this.position,
                                                                name: obj.getAttribute('name'),
                                                                type: type
                                                            })
                                                        )
                                                        console.log('group object found: ' + name)
                                                        console.log(obj)
                                                    } else if (obj.getElementsByTagName('polygon').length > 0) {
                                                        console.log('polygon found: ' + name)
                                                    } else if (obj.getElementsByTagName('polyline').length > 0) {
                                                        console.log('polyline found: ' + name)
                                                    }
                                                }
                                            }
                                            break
                        
                                    }
                                    element = element.nextElementSibling
                                }
                        
                        
                                //get tile properties
                                this.tileproperties = Array(parseInt((this.atlaswidth / this.tilewidth)) * parseInt((this.atlasheight / this.tileheight)))
                                var tiles = map.xmlDoc.getElementsByTagName('tileset')[0].getElementsByTagName('tile')
                                var time = new Date().getTime()
                                for (i in tiles) {
                                    var tprop = new CG.MapTileProperties()
                                    var tile = tiles[i]
                        
                                    if (i < this.tileproperties.length) {
                                        var id = tile.getAttribute('id')
                                        var properties = tile.getElementsByTagName('properties')[0].getElementsByTagName('property')
                                        for (p in properties) {
                                            if (p < properties.length) {
                                                var tp = properties[p]
                                                var elem = tp.getAttribute('name')
                                                var value = tp.getAttribute('value')
                                                if (elem == 'name') {
                                                    tprop.name = value
                                                } else if (elem == 'anim_delay') {
                                                    tprop.animDelay = parseInt(value)
                                                    tprop.delayTimer = time
                                                } else if (elem == 'anim_direction') {
                                                    tprop.animDirection = parseInt(value)
                                                } else if (elem == 'anim_next') {
                                                    tprop.animNext = parseInt(value)
                                                }
                                            }
                                        }
                                        this.tileproperties[id] = tprop
                                    }
                                }
                                return this
                            },
                        
                            /**
                             * @description
                             *
                             * Load and parse an tilemap json file. Use the tiled json export.
                             * Hopefully the json format has the same functionality as the xml loader ;o)
                             *
                             * @method loadMapJson
                             * @param jsonfile {string/object} jsonfile path or mediaasset object with data of tiled map xml
                             */
                            loadMapJson: function (jsonfile) {
                                this.layers = []
                        
                                //from asset
                                if (typeof jsonfile == 'string') {
                                    this.json = JSON.parse(loadString(jsonfile))
                                } else {
                                    this.json = jsonfile.data
                                }
                        
                                this.removeXmlData()
                        
                                //get map
                                this.orientation = this.json.orientation
                                this.mapColumns = this.json.width
                                this.mapRows = this.json.height
                                this.tilewidth = this.json.tilewidth
                                this.tileheight = this.json.tileheight
                        
                                //tilesets
                                for (i = 0, l = this.json.layers.length; i < l; i++) {
                                    switch (this.json.layers[i].type) {
                                        case 'tilelayer':
                                            //get tilemap data of layer
                                            var tl = new CG.MapTileLayer()
                                            tl.tiles = this.json.layers[i].data
                                            tl.name = this.json.layers[i].name
                                            tl.width = this.json.layers[i].width
                                            tl.height = this.json.layers[i].height
                                            tl.opacity = this.json.layers[i].opacity
                                            tl.visible = this.json.layers[i].visible
                                            this.layers.push(tl)
                                            break
                                        case 'objectgroup':
                                            //get tilemap data of grouplayer
                                            console.log('grouplayer found')
                                            var objects = this.json.layers[i].objects
                                            for (o in objects) {
                                                if (o < objects.length) {
                                                    var obj = objects[o]
                                                    var name = obj.name
                                                    if (obj.gid) {
                                                        //tile as object/point
                                                        this.points.push(
                                                            new CG.MapPoint({
                                                                position: new CG.Point(
                                                                    parseInt(obj.x),
                                                                    parseInt(obj.y)
                                                                ),
                                                                mapOffset: this.position,
                                                                name: obj.name,
                                                                gid: parseInt(obj.gid)
                                                            })
                                                        )
                        
                                                        console.log('tile as oject found: ' + name)
                                                        console.log(obj)
                                                    } else if (obj.width) {
                                                        //object group
                                                        this.areas.push(
                                                            new CG.MapArea({
                                                                bound: new CG.Bound({
                                                                    x: parseInt(obj.x),
                                                                    y: parseInt(obj.y),
                                                                    width: parseInt(obj.width),
                                                                    height: parseInt(obj.height)
                                                                }),
                                                                mapOffset: this.position,
                                                                name: obj.name,
                                                                type: obj.properties.type
                                                            })
                                                        )
                        
                                                        console.log('group object found: ' + name)
                                                        console.log(obj)
                                                    } else if (obj.polygon) {
                                                        console.log('polygon found: ' + name)
                                                    } else if (obj.polyline) {
                                                        console.log('polyline found: ' + name)
                                                    }
                                                }
                                            }
                                            break
                        
                                    }
                                }
                        
                        
                                //get tile properties
                                this.atlas.src = 'media/map/' + this.json.tilesets[0].image
                        
                                this.atlaswidth = this.json.tilesets[0].imagewidth
                                this.atlasheight = this.json.tilesets[0].imageheight
                                this.atlastranscol = this.json.tilesets[0].transparentcolor
                        
                                this.tileproperties = Array(parseInt((this.atlaswidth / this.tilewidth)) * parseInt((this.atlasheight / this.tileheight)))
                                var tiles = this.json.tilesets[0].tileproperties
                        
                                var time = new Date().getTime()
                        
                                for (id in tiles) {
                                    var tprop = new CG.MapTileProperties()
                                    var tile = tiles[id]
                                    tprop.name = tile.name
                                    tprop.animDelay = parseInt(tile.anim_delay)
                                    tprop.delayTimer = (tprop.animDelay > 0) ? time : 0
                                    tprop.animNext = parseInt(tile.anim_next)
                                    tprop.animDirection = parseInt(tile.anim_direction)
                                    this.tileproperties[id] = tprop
                        
                                }
                                return this
                            },
                        
                        
                            /**
                             * @description
                             *
                             * This is the main method for map drawing. Orthogonal maps works very well. Isometric maps are not well implemented yet.
                             *
                             * @method drawMap
                             *
                             * @param sx {Number} sx top left coord for canvas drawing
                             * @param sy {Number} sy top left coord for canvas drawing
                             * @param bx {Number} bx top left x coord of bound in tilemap
                             * @param by {Number} by top left y coord of bound in tilemap
                             * @param bw {Number} bw width of bound in tilemap
                             * @param bh {Number} bh height of bound in tilemap
                             * @param callback {callback} callback for collision handling - callback(obj,maptileproperties)
                             */
                            drawMap: function (sx, sy, bx, by, bw, bh, callback) {
                                this.bx = bx
                                this.by = by
                                this.bw = bw
                                this.bh = bh
                                this.sx = sx
                                this.sy = sy
                                this.callback = callback || false
                        
                                //for renderer
                                this.rx = 0
                                this.ry = 0
                                this.cx = 0
                                this.cy = 0
                                this.xpos = 0
                                this.ypos = 0
                                this.layer = 0
                        
                                //update all points an areas
                                this.updatePointsAndAreas()
                        
                                if (this.visible) {
                                    this.updateAnimation()
                                    if (this.layers.length > 0) {
                                        for (var layer = 0, l = this.layers.length; layer < l; layer++) {
                                            var tl = this.layers[layer]
                                            //render control, render by name, layer number or 'all''
                                            if (this.renderlayer === tl.name || this.renderlayer === layer || this.renderlayer === 'all') {
                                                // MAP ORTHOGONAL
                                                if (this.orientation == 'orthogonal' && tl.visible == true) {
                                                    var modx = (this.bx * this.xscale) % this.tilewidth,
                                                        mody = (this.by * this.yscale) % this.tileheight,
                                                        y = this.by,
                                                        my = Math.floor(this.by / this.tileheight),
                                                        tmpy = (this.by + this.bh + this.tileheight)
                        
                                                    while (y < tmpy) {
                                                        var x = this.bx, //- this.tilewidth
                                                            mx = Math.floor(this.bx / this.tilewidth),
                                                            tmpx = this.bx + this.bw + this.tilewidth
                                                        while (x < tmpx) {
                                                            if ((this.wrapX || (mx >= 0 && mx < this.mapColumns)) && (this.wrapY || (my >= 0 && my < this.mapRows))) {
                                                                var mx2 = mx,
                                                                    my2 = my
                        
                                                                while (mx2 < 0) {
                                                                    mx2 += this.width
                                                                }
                        
                                                                while (mx2 >= this.width) {
                                                                    mx2 -= this.width
                                                                }
                        
                                                                while (my2 < 0) {
                                                                    my2 += this.height
                                                                }
                        
                                                                while (my2 >= this.height) {
                                                                    my2 -= this.height
                                                                }
                        
                                                                gid = tl.tiles[mx2 + my2 * tl.width] - 1
                        
                                                                if (gid >= 0) {
                                                                    if (modx < 0) {
                                                                        modx += this.tilewidth
                                                                    }
                                                                    if (mody < 0) {
                                                                        mody += this.tileheight
                                                                    }
                                                                    this.rx = x - modx - this.bx
                                                                    this.ry = y - mody - this.by
                        
                        
                                                                    //time for collision detection?
                                                                    //limit to specific tilemap layer?
                                                                    //collision depending on bounds and direction (xspeed/yspeed)?
                                                                    //include some layer functionality here and render some sprites between map layers?
                                                                    if (this.elements.length > 0 && this.layertocheck == l) {
                                                                        for (var o = 0, l = this.elements.length; o < l; o++) {
                                                                            if (this.checkMapCollision(this.elements[0], this.rx, this.ry)) {
                                                                                this.callback(this.elements[o], this.tileproperties[gid])
                                                                            }
                                                                        }
                                                                    }
                        
                        
                                                                    //margin/spacing?
                                                                    this.cx = (gid % (this.atlaswidth / this.tilewidth)) * this.tilewidth
                                                                    this.cy = Math.floor(this.tilewidth * gid / this.atlaswidth) * this.tileheight
                        
                                                                    Game.renderer.draw(this)
                                                                }
                        
                                                            }
                                                            x = x + this.tilewidth
                                                            mx += 1
                                                        }
                                                        y = y + this.tileheight
                                                        my += 1
                                                    }
                                                }
                                                // MAP ISOMETRIC
                                                else if (this.orientation == 'isometric') {
                                                    var t = tl.width + tl.height
                                                    for (var y = 0; y < t; y++) {
                                                        var ry = y,
                                                            rx = 0
                                                        while (ry >= tl.height) {
                                                            ry -= 1
                                                            rx += 1
                                                        }
                        
                        
                                                        while (ry >= 0 && rx < tl.width) {
                                                            var gid = tl.tiles[rx + ry * tl.width]
                                                            this.rx = (rx - ry - 1) * this.tilewidth / 2 - bx
                                                            this.ry = (rx + ry + 1) * this.tileheight / 2 - by
                                                            if (this.rx > -this.tileset.tilewidth && this.rx < bw && this.ry > -this.tileset.tileheight && this.ry < bh) {
                                                                if (gid > 0) {
                                                                    this.cx = ((gid - 1) % (this.atlaswidth / this.tilewidth)) * this.tilewidth
                                                                    this.cy = Math.floor(this.tilewidth * (gid - 1) / this.atlaswidth) * this.tileset.tileheight
                        
                                                                    Game.renderer.draw(this)
                        
                                                                }
                                                            }
                                                            ry -= 1
                                                            rx += 1
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            },
                        
                            /**
                             * @description
                             *
                             * Update all areas and points elements.
                             *
                             * @method updatePointsAndAreas
                             */
                            updatePointsAndAreas: function () {
                                this.points.forEach(function (point, index) {
                                    point.update(this.mapOffset)
                                }, this)
                                this.areas.forEach(function (area, index) {
                                    area.update(this.mapOffset)
                                }, this)
                            },
                        
                        
                            /**
                             * @description
                             *
                             * Get all point(s) with the given name in the points
                             *
                             * @method getPointsByName
                             *
                             * @param name {string} name of the points to return
                             * @return {false/array} returns false or an array with point(s)
                             */
                            getPointsByName: function (name) {
                                points = []
                                for (var i = 0, l = this.points.length; i < l; i++) {
                                    if (this.points[i].name === name) {
                                        points.push(this.points[i])
                                    }
                                }
                                if (points.length > 0) {
                                    return points
                                }
                                return false
                            },
                        
                            /**
                             * @description
                             *
                             * Get all areas with the given name
                             *
                             * @method getAreasByName
                             *
                             * @param name {string} name of the area(s) to return
                             * @return {false/array} returns false or an array with area(s)
                             */
                            getAreasByName: function (name) {
                                areas = []
                                for (var i = 0, l = this.areas.length; i < l; i++) {
                                    if (this.areas[i].name === name) {
                                        areas.push(this.areas[i])
                                    }
                                }
                                if (areas.length > 0) {
                                    return areas
                                }
                                return false
                            },
                        
                        
                            /**
                             * @description
                             *
                             * Defines layer drawing, See property options
                             *
                             * @method setLayerToRender
                             *
                             * @param mixed {mixed} mixed define the map layer(s) to render 'all' (string) for all layers, array index (integer) for layer to render or 'name' (string) of layer to render'
                             */
                            setLayerToRender: function (mixed) {
                                this.renderlayer = mixed
                                return this
                            },
                        
                            /**
                             * @description
                             *
                             * The update method is not complete yet and only experimental.
                             * At the final stage the methods updateAnimation and updatePointsAndAreas have to be called from here!
                             * Then also a map class can be added to a layer as an element for auto update/draw from Game.director!
                             *
                             * @method update
                             */
                            update: function () {
                                ////TODO automatic movement of map or other stuff?
                                //this.bx += this.xspeed
                                //this.by += this.yspeed
                                //if (this.getBounds().width - Game.bound.width < this.mapOffset.x) {
                                //    this.xspeed = this.xspeed * -1
                                //}
                                //if (this.mapOffset.x < 0) {
                                //    this.xspeed = this.xspeed * -1
                                //}
                                //if (this.getBounds().height - Game.bound.height < this.mapOffset.y) {
                                //    this.yspeed = this.yspeed * -1
                                //}
                                //if (this.mapOffset.y < 0) {
                                //    this.yspeed = this.yspeed * -1
                                //}
                                //return this
                            },
                        
                            // just calls drawMap ;o)
                            draw: function () {
                                this.drawMap(this.position.x, this.position.y, this.mapOffset.x, this.mapOffset.y, this.width, this.height, this.callback)
                                return this
                            },
                        
                            /**
                             * @description
                             *
                             * Get the bounds of the map
                             *
                             * @method getBounds
                             */
                            getBounds: function () {
                                return {
                                    width: this.width * this.tilewidth,
                                    height: this.height * this.tileheight
                                }
                            },
                        
                            /**
                             * @description
                             *
                             * Updates all tilemap properties of the map.
                             *
                             * Supported custom tiled map properties for now are (see also tilemap examples):
                             * anim_delay       => time to used to display an switch to next tile
                             * anim_direction   => direction for next tile 1 = jump forward, -1 = jump back
                             * anim_next        => defines the offset
                             *
                             * With this tile properties it is possible to define tilemap animations.
                             * These must be defined in the tilemap property window with key/value pairs
                             *
                             * @method updateAnimation
                             */
                            updateAnimation: function () {
                                if (this.layers.length > 0) {
                                    for (var layer = 0, l = this.layers.length; layer < l; layer++) {
                                        var newtime = new Date().getTime()
                                        for (var t = 0, tl = this.layers[layer].tiles.length; t < tl; t++) {
                                            var tile = this.layers[layer].tiles[t]
                                            if (tile > 0) {
                                                var tprop = this.tileproperties[tile - 1]
                                                if (tprop) {
                                                    if (newtime > (tprop.delayTimer + (tprop.animDelay / this.animDelayFactor))) {
                                                        switch (tprop.animDirection) {
                                                            case 1:
                                                                this.layers[layer].tiles[t] += tprop.animNext
                                                                this.tileproperties[tile - 1 + tprop.animNext].delayTimer = newtime
                                                                break
                                                            case -1:
                                                                this.layers[layer].tiles[t] -= tprop.animNext
                                                                this.tileproperties[tile - 1 - tprop.animNext].delayTimer = newtime
                                                                break
                                                            default:
                                                                break
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            },
                        
                            /**
                             * @description
                             *
                             * Adds a object to the element array, used at the moment for collision detection to tilemap.
                             *
                             * @method addElement
                             *
                             * @param {obj} element to to add to elements array
                             */
                            addElement: function (element) {
                                this.elements.push(element)
                                return this
                            },
                        
                            /**
                             * @description
                             * Checks if the attached element collides with an tile of the tilemap
                             *
                             * @method checkMapCollision
                             *
                             * @param {obj} element to check for
                             * @param {Number} rx current rx of rendermap method
                             * @param {Number} ry current ry of rendermap method
                             *
                             * @return {boolean} returns true or false
                             */
                            checkMapCollision: function (element, rx, ry) {
                                //TODO return detailed collision object or offsets instead of true?
                                if (element.boundingradius > 0) {
                                    //circular collision
                                    var xr = element.boundingradius / 2 * element.xscale
                                    var yr = element.boundingradius / 2 * element.yscale
                                    if (element.position.x + xr >= rx && element.position.x - xr <= rx + this.tilewidth && element.position.y + yr >= ry && element.position.y - yr <= ry + this.tileheight) {
                                        return true
                                    }
                                } else {
                                    //bounding collision
                                    var xw = element.width / 2 * element.xscale
                                    var yh = element.height / 2 * element.yscale
                                    if (element.position.x + xw >= rx && element.position.x - xw <= rx + this.tilewidth && element.position.y + yh >= ry && element.position.y - yh <= ry + this.tileheight) {
                                        return true
                                    }
                                }
                                return false
                            },
                        
                            /**
                             * @description
                             * Checks if a external object(s) collides with the areas of the tiled map.
                             * This can be elements from an layer or the map itself.
                             *
                             * @method checkElementsToAreasCollision
                             *
                             * @param {Array} objarray to check for a areas collision
                             * @param {Callback} callback what should happen
                             */
                            checkElementsToAreasCollision: function (objarray, callback) {
                                for (var o = 0, ol = objarray.length; o < ol; o++) {
                        
                                    obj = objarray[o].checkCollision(this.areas, callback)
                                }
                                return this
                            },
                            /**
                             * @description removes the json data of the map object
                             * @method removeJsonData
                             */
                            removeJsonData: function () {
                                this.json = {}
                                return this
                            },
                            /**
                             * @description removes the xml data of the map object
                             * @method removeXmlData
                             */
                            removeXmlData: function () {
                                this.xml = ''
                                //this.parser = new DOMParser()
                                this.xmlDoc = ''
                                return this
                            }
                        })