Search code examples
pythonpython-3.xpygameframe-rate

Pygame : a fast way to find what is on screen before displaying it with insane amount of objects


I workd on a pygame project where the program have saved a insane amount of Objects ( 100 000 + Objects ). The script is based on big distances between each groups of objects. To make it's simple the plan is a bordeless map with a camera that moving on it. There is not a big desity of object, I mean, I don't think this will pass 500 objects per 1920 x 1080.

( and seriously, 500 object is very large)

Even with 500 objects in displayed on my screen I can have a solid 150 FPS which is very well. Unfortunately, when I run the script with more objects but in a bigger zone with less density, problems comes.

So, I make a function that check for any element in the list if the program need to display it.

        for obj_x, obj_y , obj_size_x, obj_size_y in objects :                          # take value in a tuple in the list
            if (camera.x  - obj_size_x ) < obj_x < (camera.x + window.current_w ):      # if it not screen on x axis if continue else it's pass to the next objects
                if (camera.y - obj_size_y ) < obj_y < (camera.y + window.current_h):    #same but with y
                    pygame.draw.rect(window.screen, (0, 0, 0), (*(obj_x - camera.x, obj_y - camera.y),*(obj_size_x, obj_size_y)), 5) # the else is displayed

Right now, this function give me solid 350 FPS wihout any objects anywhere, a 60 FPS with 2500 elements displayed on camera ( and no others forms outsides ).

But if I got a total of 25 000 elements on the map, I got 60 FPS event if not object is displayed ! It's caused by the execution time of the the if which take too much time to check if a object is on the camera or not.

But with 100 000 element, when nothing on camera, run only 25 PFS...

Here is a better way to calculate what show faster ?


Solution

  • You could use a data structure like a Quadtree to partition the 2-Dimensional space. The big advantage here is that you would only have to iterate over and check those objects which have a chance of being visible. All objects which spatially do not intersect with the viewport / camera are automatically culled, by virtue of the fact that they can't possibly be visible.