Reputation: 278
I'm having some performance issues in pygame, so I'm trying to optimize the rendering.
Currently, I'm blitting the background image to the display buffer:
self.display.blit(self.bg, (0, 0))
Instead, I'm looking for a way to replace the buffer with a copy of the background surface, and draw over that. This way, I don't have to blit a large image every frame, saving me some time.
Is there any way to do so?
Upvotes: 1
Views: 439
Reputation: 3889
Without seeing your code it will be hard to really see where the bottleneck is. Sloth is correct on his points as a way to optimize. in my experience all images should be pre-processed outside of the main game loop by drawing them onto their own surfaces. Blitting surfaces to surfaces is much faster than blitting images to surfaces.
img_surface = pygame.Surface((img_rect.width, img_rect.height), pygame.SRCALPHA)
img_surface.fill((0, 0, 0, 0))
img_surface.blit(get_image("my_image.png"), img_rect)
This happens outside the game loop. In the game loop you blit the image surface to your surface. If you really want to evaluate you code, use cProfile. This will help you nail down exactly where the bottleneck is. Do as much pre-processing outside the main game loop as possible.
Python getting meaningful results from cProfile
This link really helped me understand cProfile. Sloth is also correct in that pygame is limited, so you are going to need to optimize everything as much as you can. That is where cProfile comes in.
...Also, make sure you are only drawing things that are visible to the user. That can really help improve performance.
Upvotes: 0
Reputation: 101072
It doesn't matter that much how often you blit something to the screen surface, since the display does only get updated once you call pygame.display.update
or pygame.display.flip
.
If you're sure that blitting the whole background image to the screen surface is a bottle neck in your game, you can try the following things:
a) Instead of blitting the whole background every frame, use the clear()
function to "erase" your sprites from the screen.
b) Instead of calling pygame.display.flip
or pygame.display.update
without an argument, call pygame.display.update
with the list of the areas on the screen that have been changed, which is returned by the draw()
function (maybe in combination with clear()
).
c) Create your display surface with the FULLSCREEN
, DOUBLEBUF
and HWSURFACE
flags.
But as I already said: make sure you know where your bottle neck is. Some common performance pitfalls are: loading images multiple times from disk, font rendering, using different pixel formats (e.g. not calling convert
/convert_alpha
on surfaces created from images) and generally the lack of caching.
(also note that python/pygame is generally not the first choice when creating graphically demanding games)
Upvotes: 1