Render tilemap when camera outside of world bounds, layer wrapping

Prior to this change, TilemapLayers always restricted themselves to
rendering strictly within the world bounds. If the camera was allowed
to go beyond the world bounds, then the tilemap would appear to stop
scrolling once the camera hit the world edge. This allows the tilemap
to continue scrolling, showing empty space beyond the edge of the map.

Additionally, when the new "wrap" parameter is true, the tilemap will
render its opposite edge in the empty space. This simulates the map as
if it was the surface of a toroid (donut) rather than a flat plane.
This commit is contained in:
John Watson 2014-05-27 14:51:44 -07:00
parent 0c76e9aada
commit 14e1f0fcc6

View file

@ -185,6 +185,12 @@ Phaser.TilemapLayer = function (game, tilemap, index, width, height) {
};
/**
* @property {boolean} wrap - Flag controlling whether the layer tiles wrap at the edges
* @default false
*/
this.wrap = false;
/**
* @property {array} _results - Local render loop var to help avoid gc spikes.
* @private
@ -496,19 +502,6 @@ Phaser.TilemapLayer.prototype.updateMax = function () {
this._mc.maxX = this.game.math.ceil(this.canvas.width / this.map.tileWidth) + 1;
this._mc.maxY = this.game.math.ceil(this.canvas.height / this.map.tileHeight) + 1;
if (this.layer)
{
if (this._mc.maxX > this.layer.width)
{
this._mc.maxX = this.layer.width;
}
if (this._mc.maxY > this.layer.height)
{
this._mc.maxY = this.layer.height;
}
}
this.dirty = true;
};
@ -553,15 +546,41 @@ Phaser.TilemapLayer.prototype.render = function () {
for (var y = this._mc.startY, lenY = this._mc.startY + this._mc.maxY; y < lenY; y++)
{
this._column = this.layer.data[y];
this._column = null;
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
if (y < 0 && this.wrap)
{
if (this._column[x])
{
tile = this._column[x];
this._column = this.layer.data[y + this.map.height];
}
else if (y >= this.map.height && this.wrap)
{
this._column = this.layer.data[y - this.map.height];
}
else if (this.layer.data[y])
{
this._column = this.layer.data[y];
}
if (tile.index > -1)
if (this._column)
{
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
{
var tile = null;
if (x < 0 && this.wrap)
{
tile = this._column[x + this.map.width];
}
else if (x >= this.map.width && this.wrap)
{
tile = this._column[x - this.map.width];
}
else if (this._column[x])
{
tile = this._column[x];
}
if (tile && tile.index > -1)
{
set = this.map.tilesets[this.map.tiles[tile.index][2]];
@ -578,9 +597,10 @@ Phaser.TilemapLayer.prototype.render = function () {
this.context.fillRect(Math.floor(this._mc.tx), Math.floor(this._mc.ty), this.map.tileWidth, this.map.tileHeight);
}
}
}
this._mc.tx += this.map.tileWidth;
this._mc.tx += this.map.tileWidth;
}
}
@ -623,52 +643,81 @@ Phaser.TilemapLayer.prototype.renderDebug = function () {
for (var y = this._mc.startY, lenY = this._mc.startY + this._mc.maxY; y < lenY; y++)
{
this._column = this.layer.data[y];
this._column = null;
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
if (y < 0 && this.wrap)
{
var tile = this._column[x];
this._column = this.layer.data[y + this.map.height];
}
else if (y >= this.map.height && this.wrap)
{
this._column = this.layer.data[y - this.map.height];
}
else if (this.layer.data[y])
{
this._column = this.layer.data[y];
}
if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight))
if (this._column)
{
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
{
this._mc.tx = Math.floor(this._mc.tx);
var tile = null;
if (this.debugFill)
if (x < 0 && this.wrap)
{
this.context.fillRect(this._mc.tx, this._mc.ty, this._mc.cw, this._mc.ch);
tile = this._column[x + this.map.width];
}
else if (x >= this.map.width && this.wrap)
{
tile = this._column[x - this.map.width];
}
else if (this._column[x])
{
tile = this._column[x];
}
this.context.beginPath();
if (tile.faceTop)
if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight))
{
this.context.moveTo(this._mc.tx, this._mc.ty);
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty);
this._mc.tx = Math.floor(this._mc.tx);
if (this.debugFill)
{
this.context.fillRect(this._mc.tx, this._mc.ty, this._mc.cw, this._mc.ch);
}
this.context.beginPath();
if (tile.faceTop)
{
this.context.moveTo(this._mc.tx, this._mc.ty);
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty);
}
if (tile.faceBottom)
{
this.context.moveTo(this._mc.tx, this._mc.ty + this._mc.ch);
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
}
if (tile.faceLeft)
{
this.context.moveTo(this._mc.tx, this._mc.ty);
this.context.lineTo(this._mc.tx, this._mc.ty + this._mc.ch);
}
if (tile.faceRight)
{
this.context.moveTo(this._mc.tx + this._mc.cw, this._mc.ty);
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
}
this.context.stroke();
}
if (tile.faceBottom)
{
this.context.moveTo(this._mc.tx, this._mc.ty + this._mc.ch);
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
}
this._mc.tx += this.map.tileWidth;
if (tile.faceLeft)
{
this.context.moveTo(this._mc.tx, this._mc.ty);
this.context.lineTo(this._mc.tx, this._mc.ty + this._mc.ch);
}
if (tile.faceRight)
{
this.context.moveTo(this._mc.tx + this._mc.cw, this._mc.ty);
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
}
this.context.stroke();
}
this._mc.tx += this.map.tileWidth;
}
this._mc.tx = this._mc.dx;
@ -690,27 +739,10 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", {
set: function (value) {
if (value !== this._mc.x && value >= 0 && this.layer.widthInPixels > this.width)
if (value !== this._mc.x)
{
this._mc.x = value;
if (this._mc.x > (this.layer.widthInPixels - this.width))
{
this._mc.x = this.layer.widthInPixels - this.width;
}
this._mc.startX = this.game.math.floor(this._mc.x / this.map.tileWidth);
if (this._mc.startX < 0)
{
this._mc.startX = 0;
}
if (this._mc.startX + this._mc.maxX > this.layer.width)
{
this._mc.startX = this.layer.width - this._mc.maxX;
}
this.dirty = true;
}
@ -730,27 +762,10 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", {
set: function (value) {
if (value !== this._mc.y && value >= 0 && this.layer.heightInPixels > this.height)
if (value !== this._mc.y)
{
this._mc.y = value;
if (this._mc.y > (this.layer.heightInPixels - this.height))
{
this._mc.y = this.layer.heightInPixels - this.height;
}
this._mc.startY = this.game.math.floor(this._mc.y / this.map.tileHeight);
if (this._mc.startY < 0)
{
this._mc.startY = 0;
}
if (this._mc.startY + this._mc.maxY > this.layer.height)
{
this._mc.startY = this.layer.height - this._mc.maxY;
}
this.dirty = true;
}