UNPKG

lettuce

Version:

Lettuce JS, Mini Mobile Framework for Romantic with DSL.

317 lines (280 loc) 10.6 kB
/* * MelonJS Game Engine * Copyright (C) 2011 - 2013, Olivier BIOT * http://www.melonjs.org * * Tile QT 0.7.x format * http://www.mapeditor.org/ * */ (function () { /** * an Orthogonal Map Renderder * Tiled QT 0.7.x format * @memberOf me * @ignore * @constructor */ me.TMXOrthogonalRenderer = Object.extend({ // constructor init: function (cols, rows, tilewidth, tileheight) { this.cols = cols; this.rows = rows; this.tilewidth = tilewidth; this.tileheight = tileheight; }, /** * return true if the renderer can render the specified layer * @ignore */ canRender : function (layer) { return ((layer.orientation === "orthogonal") && (this.cols === layer.cols) && (this.rows === layer.rows) && (this.tilewidth === layer.tilewidth) && (this.tileheight === layer.tileheight)); }, /** * return the tile position corresponding to the specified pixel * @ignore */ pixelToTileCoords : function (x, y) { return new me.Vector2d(this.pixelToTileX(x), this.pixelToTileY(y)); }, /** * return the tile position corresponding for the given X coordinate * @ignore */ pixelToTileX : function (x) { return x / this.tilewidth; }, /** * return the tile position corresponding for the given Y coordinates * @ignore */ pixelToTileY : function (y) { return y / this.tileheight; }, /** * return the pixel position corresponding of the specified tile * @ignore */ tileToPixelCoords : function (x, y) { return new me.Vector2d(x * this.tilewidth, y * this.tileheight); }, /** * fix the position of Objects to match * the way Tiled places them * @ignore */ adjustPosition: function (obj) { // only adjust position if obj.gid is defined if (typeof(obj.gid) === "number") { // Tiled objects origin point is "bottom-left" in Tiled, // "top-left" in melonJS) obj.y -= obj.height; } }, /** * draw the tile map * @ignore */ drawTile : function (renderer, x, y, tmxTile, tileset) { // draw the tile tileset.drawTile(renderer, tileset.tileoffset.x + x * this.tilewidth, tileset.tileoffset.y + (y + 1) * this.tileheight - tileset.tileheight, tmxTile); }, /** * draw the tile map * @ignore */ drawTileLayer : function (renderer, layer, rect) { // get top-left and bottom-right tile position var start = this.pixelToTileCoords(rect.pos.x, rect.pos.y).floorSelf(); var end = this.pixelToTileCoords(rect.pos.x + rect.width + this.tilewidth, rect.pos.y + rect.height + this.tileheight).ceilSelf(); //ensure we are in the valid tile range end.x = end.x > this.cols ? this.cols : end.x; end.y = end.y > this.rows ? this.rows : end.y; // main drawing loop for (var y = start.y; y < end.y; y++) { for (var x = start.x; x < end.x; x++) { var tmxTile = layer.layerData[x][y]; if (tmxTile) { this.drawTile(renderer, x, y, tmxTile, tmxTile.tileset); } } } } }); /** * an Isometric Map Renderder * Tiled QT 0.7.x format * @memberOf me * @ignore * @constructor */ me.TMXIsometricRenderer = Object.extend({ // constructor init: function (cols, rows, tilewidth, tileheight) { this.cols = cols; this.rows = rows; this.tilewidth = tilewidth; this.tileheight = tileheight; this.hTilewidth = tilewidth / 2; this.hTileheight = tileheight / 2; this.originX = this.rows * this.hTilewidth; }, /** * return true if the renderer can render the specified layer * @ignore */ canRender : function (layer) { return ( (layer.orientation === "isometric") && (this.cols === layer.cols) && (this.rows === layer.rows) && (this.tilewidth === layer.tilewidth) && (this.tileheight === layer.tileheight) ); }, /** * return the tile position corresponding to the specified pixel * @ignore */ pixelToTileCoords : function (x, y) { return new me.Vector2d(this.pixelToTileX(x, y), this.pixelToTileY(y, x)); }, /** * return the tile position corresponding for the given X coordinate * @ignore */ pixelToTileX : function (x, y) { return (y / this.tileheight) + ((x - this.originX) / this.tilewidth); }, /** * return the tile position corresponding for the given Y coordinates * @ignore */ pixelToTileY : function (y, x) { return (y / this.tileheight) - ((x - this.originX) / this.tilewidth); }, /** * return the pixel position corresponding of the specified tile * @ignore */ tileToPixelCoords : function (x, y) { return new me.Vector2d( (x - y) * this.hTilewidth + this.originX, (x + y) * this.hTileheight ); }, /** * fix the position of Objects to match * the way Tiled places them * @ignore */ adjustPosition: function (obj) { var tilex = obj.x / this.hTilewidth; var tiley = obj.y / this.tileheight; var isoPos = this.tileToPixelCoords(tilex, tiley); obj.x = isoPos.x; obj.y = isoPos.y; }, /** * draw the tile map * @ignore */ drawTile : function (renderer, x, y, tmxTile, tileset) { // draw the tile tileset.drawTile( renderer, ((this.cols - 1) * tileset.tilewidth + (x - y) * tileset.tilewidth >> 1), (-tileset.tilewidth + (x + y) * tileset.tileheight >> 2), tmxTile ); }, /** * draw the tile map * @ignore */ drawTileLayer : function (renderer, layer, rect) { // cache a couple of useful references var tileset = layer.tileset; var offset = tileset.tileoffset; // get top-left and bottom-right tile position var rowItr = this.pixelToTileCoords( rect.pos.x - tileset.tilewidth, rect.pos.y - tileset.tileheight ).floorSelf(); var TileEnd = this.pixelToTileCoords( rect.pos.x + rect.width + tileset.tilewidth, rect.pos.y + rect.height + tileset.tileheight ).ceilSelf(); var rectEnd = this.tileToPixelCoords(TileEnd.x, TileEnd.y); // Determine the tile and pixel coordinates to start at var startPos = this.tileToPixelCoords(rowItr.x, rowItr.y); startPos.x -= this.hTilewidth; startPos.y += this.tileheight; /* Determine in which half of the tile the top-left corner of the area we * need to draw is. If we're in the upper half, we need to start one row * up due to those tiles being visible as well. How we go up one row * depends on whether we're in the left or right half of the tile. */ var inUpperHalf = startPos.y - rect.pos.y > this.hTileheight; var inLeftHalf = rect.pos.x - startPos.x < this.hTilewidth; if (inUpperHalf) { if (inLeftHalf) { rowItr.x--; startPos.x -= this.hTilewidth; } else { rowItr.y--; startPos.x += this.hTilewidth; } startPos.y -= this.hTileheight; } // Determine whether the current row is shifted half a tile to the right var shifted = inUpperHalf ^ inLeftHalf; // initialize the columItr vector var columnItr = rowItr.clone(); // main drawing loop for (var y = startPos.y; y - this.tileheight < rectEnd.y; y += this.hTileheight) { columnItr.setV(rowItr); for (var x = startPos.x; x < rectEnd.x; x += this.tilewidth) { //check if it's valid tile, if so render if ((columnItr.x >= 0) && (columnItr.y >= 0) && (columnItr.x < this.cols) && (columnItr.y < this.rows)) { var tmxTile = layer.layerData[columnItr.x][columnItr.y]; if (tmxTile) { tileset = tmxTile.tileset; // offset could be different per tileset offset = tileset.tileoffset; // draw our tile tileset.drawTile(renderer, offset.x + x, offset.y + y - tileset.tileheight, tmxTile); } } // Advance to the next column columnItr.x++; columnItr.y--; } // Advance to the next row if (!shifted) { rowItr.x++; startPos.x += this.hTilewidth; shifted = true; } else { rowItr.y++; startPos.x -= this.hTilewidth; shifted = false; } } } }); })();