Sign in to follow this  
caymanbruce

Is it costly to use addChild and removeChild frequently in Containers during game loop?

Recommended Posts

I am recently building a container / map with thousands of sprites in canvas. My player will be moving around among those sprites on a large map. But I find my game becomes very slow after I add too many (-about 5000+) units on the container. 

I think it may perform better if I only display units that are within the camera of my player as my player moves around on the map. But by doing this I will need to perform addChild / removeChild operation of pixi.Container many times during the game loop, because as my player moves new sprites come into sight and some sprites are out of sight. I am not sure if this is a good or bad decision. Maybe it’s too costly to do these operations in the ticker? But how can I draw as little in-sight sprites  as possible otherwise?

 

Share this post


Link to post
Share on other sites
6 hours ago, themoonrat said:

Is there a reason you couldn't just set


yourSprite.visible = false;

On the ones you don't want to render anymore? That would be preferable and stops rendering or calculating transforms on those sprites.

Thanks whoever designs this is brilliant! But that only addresses the "remove sprite" problem. What if I need to add new sprites on the container? I say "new" because they are not on the container before rendering. I want to add them sometime later when the player is moving around. Or am I better off to have a fix number of sprites on the container but a very big number?

Share this post


Link to post
Share on other sites

True

There are two paths you can take here

1. adding and removing sprites onto the container. Advantage, the renderer is only iterating through an array of children it actually needs to render, which will be quicker. Disadvantage, addChild and removeChild are manipulating arrays, which can be slow and janky.

2. create a pool of sprites you can use up front, and reuse them by changing changing visibility. Advantage, no touching arrays; a visible on/off switch is very simple and speedy. Disadvantage, you could be iterating through tons of sprites every frame that aren't ever going to be rendered, which is a waste of time

As xerver says, you will have to profile your game to see which works out best in your circumstances. My instinct is 2, just to avoid dealing with constant array resizing, but i may be wrong!.

Please let us know what performed better... I'd love to know the answer!

 

Share this post


Link to post
Share on other sites

Thanks for advice by @xerver and @themoonrat I don't have time for detail profiling at the moment. But I have come up a mixed approach for this situation. I think I will first make the sprite invisible when it's off screen, then after a certain amount of time in the animation update loop I will perform a removeChild for every invisible sprite in the Container. The interval will be at least 1 second so it's not performed every frame.

Share this post


Link to post
Share on other sites

cayman very nice solution and very similar to what I do. This is what i do:

when an object is to be deleted, put it in a pool of objects to be deleted, and set it invisible, then on every frame check the pool and just delete one from the bottom of the pool, you could also set a maxsize for how many can be deleted in one frame if you have a lot of objects to delete, and you could even set an offset variable so that it only runs this delete command every X frames. If the pool gets too big then you must really be drawing a lot and could just let one frame deal with the entire emptying so it only occurs every few minutes.

a 64x64 tileset at 2k resolution would yield 40 blocks at the top, left, bottom, and right edge of the screen so assuming it takes 1 second to move 1 block forward, thats 40 objects added to the delete queue every second which doesnt sound like that much but if you're a racing game this could be like 10ms to travel one block forward, which could add like 400 objects to be destroyed in one second, in which case third option fails.

I use that method here on the visuals which appear and disappear a lot (cash, speech bubbles, animated hands) https://www.youtube.com/watch?v=KpaNvZ1FD_E&feature=youtu.be

 

I would be interested to see how many items you're deleting in one loop in your code maybe provide some debug feedback just out of interest as a fellow dev?

 

Share this post


Link to post
Share on other sites
5 hours ago, Jammy said:

cayman very nice solution and very similar to what I do. This is what i do:

when an object is to be deleted, put it in a pool of objects to be deleted, and set it invisible, then on every frame check the pool and just delete one from the bottom of the pool, you could also set a maxsize for how many can be deleted in one frame if you have a lot of objects to delete, and you could even set an offset variable so that it only runs this delete command every X frames. If the pool gets too big then you must really be drawing a lot and could just let one frame deal with the entire emptying so it only occurs every few minutes.

a 64x64 tileset at 2k resolution would yield 40 blocks at the top, left, bottom, and right edge of the screen so assuming it takes 1 second to move 1 block forward, thats 40 objects added to the delete queue every second which doesnt sound like that much but if you're a racing game this could be like 10ms to travel one block forward, which could add like 400 objects to be destroyed in one second, in which case third option fails.

I use that method here on the visuals which appear and disappear a lot (cash, speech bubbles, animated hands) https://www.youtube.com/watch?v=KpaNvZ1FD_E&feature=youtu.be

 

I would be interested to see how many items you're deleting in one loop in your code maybe provide some debug feedback just out of interest as a fellow dev?

 

Thanks for your input @Jammy. Your game is very interesting to watch. At the moment my game is still immature so I have only a few sprites to be destroyed in one second. But I expect to delete at least 50 - 60 sprites a second when my game is finished. My game is not tile-based maybe this makes it a bit easier to handle.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.