Jump to content

stage.children display order


Blake
 Share

Recommended Posts

Hello!

 

First of all, as this is my first post and all, I would like to congratulate Mat and the team working on pixi.js. A few days ago I was looking for a nice and fast 2D game engine and I found yours here. I found it quite easy to understand and to implement, though at some times a bit daunting due to cross-version examples. However, I was able to start off a hobby project of mine quite fast.

 

Speaking of which, I started an isometric map editor, you may see a very alpha (and buggy) version of it here.

 

All is going well, but I am having a question regarding the following situation:

 

The editor is meant to construct an isometric map by adding/moving around tiles. Each tile would have two sets of coordinates:

- isometric x, y, z that would position each tile within the game's world-space.

- regular x, y to be used for view-port rendering that get translated from the isometric coordinates.

 

The problem I need to resolve now is the order of rendering the tiles. Obviously, tiles closer to the camera would obstruct the tiles further back, so I thought to set up a rendering order calculated from the isometric x, y coordinates, considering the farthest point as the x, y origin:

 

var orderID = isometric.x + isometric.y * width

 

iso.png

 

The ID's produced this way are exemplified by the attached image. In theory, if I would be able to render the children based on the order of those ID's, the problem would be solved, and that would elegantly also resolve the problem of rendering a moving character the correct way in order to realistically show up behind or in front of columns, trees or other elements.

 

A good solution for this would be the one proposed by tengotengo here. He suggests sorting the children array each time you make a modification to it.

 

This solution would work great in the editor, but I was wondering if the sorting is by any chance too taxing for a game-play? I expect at some moments to have at least 20 players in the same room + several moving NPC's. Sorting and re-sorting the whole array each time one of them makes a move seems like a bad idea. So, I was wondering, would there be a better way of only moving up/down in the array the "dynamic" children?

Link to comment
Share on other sites

That's on of subtasks of pixi-spine: it stores slotContainers - all slots , and it has drawOrder. So every time children = slotContainers[drawOrder];

Sorting is important because most of these objects have transparent parts, we cant just use Z-buffer :(

 

Let us make a summary of problem:

  1. We need one container per level: tiles, then shadows, then characters, then their nicknames
Both tile level and characters have unordered list of childrens ("kids"), that you use for game logic. list of children in each of this 4 containers is based on one of "kids" list, and sorted by Z-coord.

Tiles layer needs to be changed ONLY when you scroll and some new tiles are appearing. If you use particleContainer for it, it will be much faster. 

More optimizations: write your own shader for it , like I did it in https://github.com/pixijs/pixi-tilemap/blob/master/src/pixi-tilemap.js . You dont have to store sprite objects of tiles, just push all numbers into one big array. We can add IsometricTileContainer as a part of pixi-tilemap. You also use that js file without changes, just create a CompositeTileLayer, clear and addRect all your things after scrolling. I still dont have examples for it, but interface is really simple.

Link to comment
Share on other sites

I have a similar setup also: 4 height layers with order tiles, ground, items in world and foreground. Each time there is a change in the position of items on a chosen layer I just sort them based on their y-coordinate children.sort(function(a,B){return a.y-b.y;}). With that I get around 50fps on first gen ipad mini with around 500 objects in total (largest layer has around 300 items) and I'm pretty sure it could handle a lot more without worrying about sorting speed.

Biggest optimization would be same as what Ivan said, particlecontainer or own shader for tile rendering. Though the particleContainer only works if you can fit all your tiles into one spritesheet. I couldn't and the performance was a bit bad, added basic culling each time the camera moved and it improved the fps a lot more than what I could get by removing the sorting. I implemented it like this:
 

function update(viewport){  for(t in items)  {    var b = t.getBounds();    t.renderable = b.x + b.width > viewport.x && b.x < viewport.x+viewport.width &&                   b.y + b.height > viewport.y && b.y < viewport.y + viewport.height;  }}
Link to comment
Share on other sites

@Exca that's how culling supposed to work, yep :)

 

BTW, i just updated https://github.com/pixijs/pixi-tilemap/ , it has minimal demo now, and its very easy to grasp. You just clear() tilemap and fill it with tiles when they change in the screen, or viewport shows some new ones.

 

P.S. dont pass third parameter "true" to CompositeTileLayer if your stuff is not composed of squares

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...