caymanbruce Posted January 17, 2017 Share Posted January 17, 2017 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? Quote Link to comment Share on other sites More sharing options...
themoonrat Posted January 17, 2017 Share Posted January 17, 2017 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. Quote Link to comment Share on other sites More sharing options...
caymanbruce Posted January 18, 2017 Author Share Posted January 18, 2017 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? Quote Link to comment Share on other sites More sharing options...
xerver Posted January 18, 2017 Share Posted January 18, 2017 Adding/removing every frame can be expensive. However, so can having a huge list of sprites you never render. It is always best to measure, try both and profile which works best for your scenario. Quote Link to comment Share on other sites More sharing options...
themoonrat Posted January 18, 2017 Share Posted January 18, 2017 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! Quote Link to comment Share on other sites More sharing options...
caymanbruce Posted April 24, 2017 Author Share Posted April 24, 2017 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. Quote Link to comment Share on other sites More sharing options...
Jammy Posted April 30, 2017 Share Posted April 30, 2017 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? Quote Link to comment Share on other sites More sharing options...
caymanbruce Posted May 1, 2017 Author Share Posted May 1, 2017 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.