Skip to content

Commit 14e1f0f

Browse files
committed
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.
1 parent 0c76e9a commit 14e1f0f

1 file changed

Lines changed: 100 additions & 85 deletions

File tree

src/tilemap/TilemapLayer.js

Lines changed: 100 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ Phaser.TilemapLayer = function (game, tilemap, index, width, height) {
185185

186186
};
187187

188+
/**
189+
* @property {boolean} wrap - Flag controlling whether the layer tiles wrap at the edges
190+
* @default false
191+
*/
192+
this.wrap = false;
193+
188194
/**
189195
* @property {array} _results - Local render loop var to help avoid gc spikes.
190196
* @private
@@ -496,19 +502,6 @@ Phaser.TilemapLayer.prototype.updateMax = function () {
496502
this._mc.maxX = this.game.math.ceil(this.canvas.width / this.map.tileWidth) + 1;
497503
this._mc.maxY = this.game.math.ceil(this.canvas.height / this.map.tileHeight) + 1;
498504

499-
if (this.layer)
500-
{
501-
if (this._mc.maxX > this.layer.width)
502-
{
503-
this._mc.maxX = this.layer.width;
504-
}
505-
506-
if (this._mc.maxY > this.layer.height)
507-
{
508-
this._mc.maxY = this.layer.height;
509-
}
510-
}
511-
512505
this.dirty = true;
513506

514507
};
@@ -553,15 +546,41 @@ Phaser.TilemapLayer.prototype.render = function () {
553546

554547
for (var y = this._mc.startY, lenY = this._mc.startY + this._mc.maxY; y < lenY; y++)
555548
{
556-
this._column = this.layer.data[y];
549+
this._column = null;
557550

558-
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
551+
if (y < 0 && this.wrap)
559552
{
560-
if (this._column[x])
553+
this._column = this.layer.data[y + this.map.height];
554+
}
555+
else if (y >= this.map.height && this.wrap)
556+
{
557+
this._column = this.layer.data[y - this.map.height];
558+
}
559+
else if (this.layer.data[y])
560+
{
561+
this._column = this.layer.data[y];
562+
}
563+
564+
if (this._column)
565+
{
566+
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
561567
{
562-
tile = this._column[x];
568+
var tile = null;
569+
570+
if (x < 0 && this.wrap)
571+
{
572+
tile = this._column[x + this.map.width];
573+
}
574+
else if (x >= this.map.width && this.wrap)
575+
{
576+
tile = this._column[x - this.map.width];
577+
}
578+
else if (this._column[x])
579+
{
580+
tile = this._column[x];
581+
}
563582

564-
if (tile.index > -1)
583+
if (tile && tile.index > -1)
565584
{
566585
set = this.map.tilesets[this.map.tiles[tile.index][2]];
567586

@@ -578,9 +597,10 @@ Phaser.TilemapLayer.prototype.render = function () {
578597
this.context.fillRect(Math.floor(this._mc.tx), Math.floor(this._mc.ty), this.map.tileWidth, this.map.tileHeight);
579598
}
580599
}
581-
}
582600

583-
this._mc.tx += this.map.tileWidth;
601+
this._mc.tx += this.map.tileWidth;
602+
603+
}
584604

585605
}
586606

@@ -623,52 +643,81 @@ Phaser.TilemapLayer.prototype.renderDebug = function () {
623643

624644
for (var y = this._mc.startY, lenY = this._mc.startY + this._mc.maxY; y < lenY; y++)
625645
{
626-
this._column = this.layer.data[y];
646+
this._column = null;
627647

628-
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
648+
if (y < 0 && this.wrap)
649+
{
650+
this._column = this.layer.data[y + this.map.height];
651+
}
652+
else if (y >= this.map.height && this.wrap)
653+
{
654+
this._column = this.layer.data[y - this.map.height];
655+
}
656+
else if (this.layer.data[y])
629657
{
630-
var tile = this._column[x];
658+
this._column = this.layer.data[y];
659+
}
631660

632-
if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight))
661+
if (this._column)
662+
{
663+
for (var x = this._mc.startX, lenX = this._mc.startX + this._mc.maxX; x < lenX; x++)
633664
{
634-
this._mc.tx = Math.floor(this._mc.tx);
665+
var tile = null;
635666

636-
if (this.debugFill)
667+
if (x < 0 && this.wrap)
637668
{
638-
this.context.fillRect(this._mc.tx, this._mc.ty, this._mc.cw, this._mc.ch);
669+
tile = this._column[x + this.map.width];
639670
}
640-
641-
this.context.beginPath();
642-
643-
if (tile.faceTop)
671+
else if (x >= this.map.width && this.wrap)
644672
{
645-
this.context.moveTo(this._mc.tx, this._mc.ty);
646-
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty);
673+
tile = this._column[x - this.map.width];
647674
}
648-
649-
if (tile.faceBottom)
675+
else if (this._column[x])
650676
{
651-
this.context.moveTo(this._mc.tx, this._mc.ty + this._mc.ch);
652-
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
677+
tile = this._column[x];
653678
}
654679

655-
if (tile.faceLeft)
680+
if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight))
656681
{
657-
this.context.moveTo(this._mc.tx, this._mc.ty);
658-
this.context.lineTo(this._mc.tx, this._mc.ty + this._mc.ch);
659-
}
682+
this._mc.tx = Math.floor(this._mc.tx);
660683

661-
if (tile.faceRight)
662-
{
663-
this.context.moveTo(this._mc.tx + this._mc.cw, this._mc.ty);
664-
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
665-
}
684+
if (this.debugFill)
685+
{
686+
this.context.fillRect(this._mc.tx, this._mc.ty, this._mc.cw, this._mc.ch);
687+
}
666688

667-
this.context.stroke();
668-
}
689+
this.context.beginPath();
690+
691+
if (tile.faceTop)
692+
{
693+
this.context.moveTo(this._mc.tx, this._mc.ty);
694+
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty);
695+
}
696+
697+
if (tile.faceBottom)
698+
{
699+
this.context.moveTo(this._mc.tx, this._mc.ty + this._mc.ch);
700+
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
701+
}
702+
703+
if (tile.faceLeft)
704+
{
705+
this.context.moveTo(this._mc.tx, this._mc.ty);
706+
this.context.lineTo(this._mc.tx, this._mc.ty + this._mc.ch);
707+
}
708+
709+
if (tile.faceRight)
710+
{
711+
this.context.moveTo(this._mc.tx + this._mc.cw, this._mc.ty);
712+
this.context.lineTo(this._mc.tx + this._mc.cw, this._mc.ty + this._mc.ch);
713+
}
714+
715+
this.context.stroke();
716+
}
669717

670-
this._mc.tx += this.map.tileWidth;
718+
this._mc.tx += this.map.tileWidth;
671719

720+
}
672721
}
673722

674723
this._mc.tx = this._mc.dx;
@@ -690,27 +739,10 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", {
690739

691740
set: function (value) {
692741

693-
if (value !== this._mc.x && value >= 0 && this.layer.widthInPixels > this.width)
742+
if (value !== this._mc.x)
694743
{
695744
this._mc.x = value;
696-
697-
if (this._mc.x > (this.layer.widthInPixels - this.width))
698-
{
699-
this._mc.x = this.layer.widthInPixels - this.width;
700-
}
701-
702745
this._mc.startX = this.game.math.floor(this._mc.x / this.map.tileWidth);
703-
704-
if (this._mc.startX < 0)
705-
{
706-
this._mc.startX = 0;
707-
}
708-
709-
if (this._mc.startX + this._mc.maxX > this.layer.width)
710-
{
711-
this._mc.startX = this.layer.width - this._mc.maxX;
712-
}
713-
714746
this.dirty = true;
715747
}
716748

@@ -730,27 +762,10 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", {
730762

731763
set: function (value) {
732764

733-
if (value !== this._mc.y && value >= 0 && this.layer.heightInPixels > this.height)
765+
if (value !== this._mc.y)
734766
{
735767
this._mc.y = value;
736-
737-
if (this._mc.y > (this.layer.heightInPixels - this.height))
738-
{
739-
this._mc.y = this.layer.heightInPixels - this.height;
740-
}
741-
742768
this._mc.startY = this.game.math.floor(this._mc.y / this.map.tileHeight);
743-
744-
if (this._mc.startY < 0)
745-
{
746-
this._mc.startY = 0;
747-
}
748-
749-
if (this._mc.startY + this._mc.maxY > this.layer.height)
750-
{
751-
this._mc.startY = this.layer.height - this._mc.maxY;
752-
}
753-
754769
this.dirty = true;
755770
}
756771

0 commit comments

Comments
 (0)