[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Drawing efficiency question



Drawing thousands of sprites is pretty quick with OpenGL, but much harder with Pygame. If you draw stationary sprites to a surface once, then draw that surface to the screen each frame you can avoid a lot of drawing calls.

If collision detection is slowing you down, you can use something like a SpatialHash to only check sprites that are near you.

The Arcade library has this stuff baked in, and as it is open source you could always look at it to get ideas.

Paul Vincent Craven


On Wed, Mar 2, 2022 at 4:47 AM rockachu2 <rockachu2@xxxxxxxxx> wrote:
Perhaps you should reconsider your decision not to use a simple
colliderect. It'd be much more efficient (as the general case is
certainly not a high number of entities on the edge of the screen) to
.colliderect() with the edges of the map, and process those specially.

Also beware drawing very large amounts that you do not need to.
Blit()ing onto a large surface, which you then display, will draw all
the pixels each frame even if they are not visible. blit() accepts a
rect argument to limit drawing, which you can take advantage of. You can
also get away with not drawing a very large amount of pixels each frame
by "erasing" underneath moving sprites.

I would also second the request for you to profile. Often, performance
bottlenecks in python are nonobvious. Lots of code that might look
expensive is fast because it operates in optimized C, and code that
looks innocent is actually slow because it is doing something behind the
scenes that you do not expect.

Wall collision code is often complicated and suspect.


On 3/1/22 15:02, Irv Kalb wrote:
> I am developing a game but I'm running into some cases where the game slows down too much.  A few details ...
>
> The game lives in a world whose size is much larger than what the user can see in the window.  (For now, the world is 3000 x 3000, but the window is 640 x 640 - I could decide to change these later).  There is a central player who is controlled by arrow keys.  When the user presses a key or keys to move in a direction, the player is an animation that looks like its walking, but always stays in the center of the screen - the view in the window scrolls in the opposite direction.  There are "enemies" that live in this world, new ones are generated all the time, and each moves semi-randomly in every frame.  There are also a number of additional elements that must be drawn every frame (e.g., walls in a maze and more).
>
> The game is complicated by the fact that the world wraps around both horizontally and vertically.  If you move off the top, you show up at the bottom, go off the left and you appear on the right, etc.  In my current version, in every frame I iterate through all drawable elements, and go through some coordinate checking code to determine if the element is visible within the window.  This code is more complicated than a simple "colliderect()" because I have to account for the potential wrapping in all directions.  If the element is within the viewable screen area, I draw it (blit), otherwise, I don't do the draw.  I thought this would be a great optimization.  But, I'm finding that as the number of enemies grows, the overall game slows down.  I'm sure this has to do with the fact that in every frame I check their movement (they cannot go through walls), move each to a new location, and then decide whether to draw them or not.
>
> I'm wondering if my code to check if an element is within the viewable area, is actually doing more work than not bothering to check at all.  My question is really about the efficiency of a call to blit in pygame when the thing being drawn is outside the viewable area.  I actually have done some minor tests, and the game seems to work a little better without doing the checking, but I want to get opinions from anyone who might really know.
>
> I will probably wind up limiting the number of enemies, but it would be good to know about how efficiently pygame deals with potentially drawing outside the window.
>
> Thanks in advance,
>
> Irv
>
>
>