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

Re: [pygame] Re: Sprite Surface very slow to draw



On Tue, Jul 20, 2010 at 10:39 AM, SurferIX <olivier.pons@xxxxxxxxx> wrote:
> If found the solution!
> The problem is that the documentation needs examples (or maybe I
> didn't find good ones):
You should look at the pygame reference doc:
http://www.pygame.org/docs/ref/index.html

> I was using:
>  40         self.image.convert_alpha()
> I should have done:
>  40         self.image.convert_alpha(self.image)
> (which I don't understand btw)
See the docs:
""""
Surface.convert_alpha

      change the pixel format of an image including per pixel alphas
      Surface.convert_alpha(Surface): return Surface
      Surface.convert_alpha(): return Surface

      Creates a new copy of the surface with the desired pixel format.
The new surface will be in a format suited for quick blitting to the
given format with per pixel alpha. If no surface is given, the new
surface will be optimized for blitting to the current display.
""""

I guess it's quicker to convert the existing surface than to create a new one.
But it's thing that's slows your code down.
The problem is in you event loop:

71     going = True
 72     while going:
 73         clock.tick(60)
First ask your self if you need a framerate of 60 per second.
Most of the time 30 p/s is enough, that alone will cut the stuff todo in half.
Now you do alll the below stuff 60 times per second

 74         for event in pygame.event.get():
 75             if event.type == QUIT:
 76                 going = False
 77             elif event.type == KEYDOWN:
 78                 if event.key == K_ESCAPE:
 79                     going = False
 80                 elif event.key == K_q:
 81                     going = False
 82                 elif event.key == K_RETURN:
 83                     going = False
 This doesn't take much time.
But the stuff below does.

 85         group_sprites.update()
 86         screen.blit(background, (0, 0))
You blit the complete screen 60 times per second !

The rest depends on how many sprites you have in your class.
 87         group_sprites.draw(screen)
 88         for sprite in group_sprites:
 89             if isinstance(sprite, Contour):
 90                 if sprite.done:
 91                     group_sprites.remove(sprite)
 92         pygame.display.flip()

Most of the times you have speed troubles the problem lies in to many
things in the mainloop.
You should for example only blit the rect on the screen that needs
erasing, not the complete screen.

From the docs:
""""
 Surface.blit

      draw one image onto another
      Surface.blit(source, dest, area=None, special_flags = 0): return Rect
       ....
      An optional area rectangle can be passed as well. This
represents a smaller portion of the source Surface
      to  draw.
      .....
""""
If you do:
dirty = [ ]
....
rect = sprite_to_erase.get_rect()
dirty.append(screen.blit(background, rect, rect))
....
Than instead of pygame.display.flip use:
pygame.display.update(dirty)

Taken from the docs:
""""
pygame.display.update

      update portions of the screen for software displays
      pygame.display.update(rectangle=None): return None
      pygame.display.update(rectangle_list): return None

      This function is like an optimized version of
pygame.display.flip - update the full display Surface to the
       screen
      for software displays. It allows only a portion of the screen to
updated, instead of the entire area.
""""
Your loop will be way faster.

Greetings,
Stas

-- 
Free-source educational programs for schools
http://www.schoolsplay.org ; and http://wiki.laptop.org/go/Schoolsplay
http://gvr.sf.net and http://wiki.laptop.org/go/Guido_van_Robot