Customizing TileLayer Drawing

Was working on a game using TileMaps. I sub classed TilemapLayer so that I could have the layer hold a list of Piece class objects (the Piece classes holds properties for what the tile represents, like a monster or item etc). Now I would like to alter the drawing of the tile layer, would like it to draw each one of the Pieces in the list, right now I just set the tile index to the top Piece in the list so I only see the top Piece drawn. I am not enough of a Javascript expert to figure if and how to replace the drawing code for the TileLayer. I see there is a file in the source code TilemapLayerCanvasRender.js (and one for WebGL) that sees to do the drawing job and it is hooked into the TilemapLayer via a list Mixins but I have no idea how to override that in my TilemapLayer subclass. Below is the TilemapLayer sub class code, not sure if the is useful but what is a post without code (I am doing Typescript because it was something new to learn)! Thanks for any thoughts.

export class TileLayerPieces extends Phaser.Tilemaps.TilemapLayer {
  constructor(
    scene: Phaser.Scene,
    tilemap: Phaser.Tilemaps.Tilemap,
    layerName: string,
    tileset: string
  ) {
    var layerData = new Phaser.Tilemaps.LayerData({
      name: layerName,
      tileWidth: tilemap.tileWidth,
      tileHeight: tilemap.tileHeight,
      width: tilemap.width,
      height: tilemap.height,
    });
    tilemap.layers.push(layerData);
    super(scene, tilemap, tilemap.getLayerIndexByName(layerName), tileset);
    var row;
    for (var tileY = 0; tileY < tilemap.height; tileY++) {
      row = [];
      for (var tileX = 0; tileX < tilemap.width; tileX++) {
        row.push(
          new Pieces(
            layerData,
            tileX,
            tileY,
            tilemap.tileWidth,
            tilemap.tileHeight,
            tilemap.tileWidth,
            tilemap.tileHeight
          )
        );
      }
      layerData.data.push(row);
    }
    scene.sys.displayList.add(this);
  }

  public addPieceAt(piece: Piece, x: number, y: number) {
    let pieces = this.layer.data[y][x] as Pieces;
    pieces.pieces.push(piece);
    pieces.index = piece.index;
    piece.pieces = pieces;
  }

  public removePieceAt(piece: Piece, x: number, y: number) {
    let pieces = this.layer.data[y][x] as Pieces;
    let index = pieces.pieces.indexOf(piece);
    if (index != -1) pieces.pieces.splice(index, 1);
    pieces.index = -1;
    if (pieces.pieces.length > 0) pieces.index = pieces.pieces[0].index;
  }

  public getPiecesAt(x: number, y: number): Pieces {
    return this.layer.data[y][x] as Pieces;
  }

  public getTopPieceAt(x: number, y: number): Piece | undefined {
    let pieces = this.layer.data[y][x] as Pieces;
    if (pieces.pieces.length) return pieces.pieces[pieces.pieces.length - 1];
    return undefined;
  }
}

Was looking at the documentation and see a TilemapLayer has a culled tile list. Was thinking during the scene update I could go to each layers culled tile list and then loop through each and draw the stack of tile images. I would probably need to do something with depth to make sure the draw order was right. I will investigate this option, though there has to be a better way to hook into the rendering to do this!

:wave:

You would override the private methods renderCanvas() and renderWebGL().

You might be able to use Tile#properties instead of the Piece class.

Thanks I will take a look at both suggestions and let you and the thread know!

Here is alot of detail in hopes might help others in the future. So I added a renderWebGL and renderCanvas function to my TileLayer class and sure enough that gave me a blank screen then looking at the TileLayer source it was apparent that somehow with the Mixins list that TilemapLayerRender gets pulled in to the class (though I don’t know how given my limited Javascript knowledge). Looking at that file that pulls in either a WebGL or Canvas render function, aligned with what the game is using (this is set in the game config can be one or the other or auto. I took the one function in the file TilemapLayerWebGLRenderer = function (renderer, src, camera) and pasted the whole thing into my renderWebGL function. And sure enough it renders the layers. Now I just need to edit this to customize the rendering. I had looked at the source and had seen this stuff when I was trying to figure this out but did not connect enough of the dots to understand what to do. The mixins list is still a mystery to me (Seems to add all those elements in to the class). Thanks for the help.