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



Reply via email to