pixijs / layers

Separate the z-hierarchy of your scene tree from its canonical structure.
https://pixijs.io/layers/docs/
MIT License
220 stars 57 forks source link

Pixi-display - worth using for simple depth sorting? #24

Open Pandan opened 6 years ago

Pandan commented 6 years ago

Is pixi-display recommended to use for basic z-index management? In my case I have a simple tile-engine where I need to handle z-index for the game character. Similar to this http://labs.phaser.io/view.html?src=src\depth%20sorting\Depth%20Sorting.js The charater is only one image (no shadows etc).

I understand that pixi-display has a lot of clever features for handling z-index. But I am wondering if it worth using for more simple depth sorting as the one above.

My own idea was just to keep all displayobjects in a array and sort them on yPos and then re-add them to the displaylist on each update.

ivanpopelyshev commented 6 years ago

If you dont need to sort through the tree, you can code it on your own: https://github.com/pixijs/pixi-display/wiki#how-to-not-use-pixi-display

As you see, I favor gradual approach.

Pandan commented 6 years ago

Ahh, thanks I missed the wiki. Then I go for just sorting on each update and re-adding them to the list.

ivanpopelyshev commented 6 years ago

I'm sure you will figure out the best sorting algorithm for your game. When you actually need to sort through the tree, give me your cirrent algorithm and i'll tell you how to embed it into pixi-display.

Pandan commented 6 years ago

In my case the displaylist is really shallow. I just have one object (this.display) where I keep everything. Below my render method, in the end I have added the sorting stuff (not tested yet). Don't know if .sort is bad for performance.

render() {
  const startCol = Math.floor(this.cameraX / MapConfig.tileSize.width);
  const startRow = Math.floor(this.cameraY / MapConfig.tileSize.height);
  const endCol = Math.ceil(startCol + (this.cameraWidth / MapConfig.tileSize.width));
  const endRow = Math.ceil(startRow + (this.cameraHeight / MapConfig.tileSize.height));
  const offsetX = -this.cameraX + startCol * MapConfig.tileSize.width;
  const offsetY = -this.cameraY + startRow * MapConfig.tileSize.height;
  // Mark previously moved items.
  for (let i = this.activeItems.length - 1; i >= 0; i--) {
    this.activeItems[i].remove = true;
  }
  // Compensate for none tiled layers.
  this.playerContainer.x = -Math.abs(this.cameraX);
  this.playerContainer.y = -Math.abs(this.cameraY);
  // Move items that are visible
  for (let c = startCol; c <= endCol; c++) {
    for (let r = startRow; r <= endRow; r++) {
      const x = (c - startCol) * MapConfig.tileSize.width + offsetX;
      const y = (r - startRow) * MapConfig.tileSize.height + offsetY;
      // If item has been moved previously
      const item = this.itemList[`${c}_${r}`];
      if (item) {
        item.x = x;
        item.y = y;
        item.remove = false;
      } else {
        this.addItem(c, r, { x, y }, MapConfig.tileSize);
      }
    }
  }
  // Remove items that has not moved
  for (let i = this.activeItems.length - 1; i >= 0; i--) {
    if (this.activeItems[i].remove) {
      this.removeItem(i);
    }
  }
  // Depth sorting
  this.activeItems.sort((obj1, obj2) => obj1.display.y - obj2.display.y);
  for (let i = this.activeItems.length - 1; i >= 0; i--) {
    this.display.addChild(this.activeItems[i].display);
  }
}
ivanpopelyshev commented 6 years ago

That page was updated. I suggest to look at new version, it has faster sorting.