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

[pygame] Slow rendering speed - sprites



Hello,

I'm considering a game framework for next more serious project. As I'm
Python/Ruby language agnostic, I did rewrote simple sprite benchmark
from Gosu to latest Pygame to do a performance comparison. You may
find the code bellow.

I was very surprised Pygame version performs much more worse. To get
an idea, it was tested on the same machine, in the same environment,
linked against same SDL 1.2.15, run with Python 2.7.5. It starts
significantly drop framerate when sprites count gets over 20, whereas
Gosu version with Ruby 2.2.0 smoothly renders 200 sprites at 60 fps !
At about 100 sprites on the screen it becomes just a very slow slideshow.

I don't know if something important performance-wise was missed.
Simple background is a static surface, display is also initialized
with native resolution 1376x768 in fullscreen,
LayeredDirty group with DirtySprites for better performance (Gosu
version also handles z-order of each sprite).

Any idea what am I doing wrong ?


_______________________________________ snip
____________________________________________________
import pygame, pygame.gfxdraw
from pygame import *
from random import randint

def main():
    pygame.init()

    video_info = pygame.display.Info()
    if video_info.current_w != -1 and video_info.current_h != -1:
        screen_width, screen_height = video_info.current_w, video_info.current_h
    else:
        screen_width, screen_height = 800, 600

    screen  = pygame.display.set_mode((screen_width, screen_height),
            FULLSCREEN | DOUBLEBUF | HWSURFACE)
    pygame.display.set_caption(__name__.upper())

    background  = pygame.Surface(screen.get_size()).convert()
    background.fill((0, 0, 0))
    pygame.gfxdraw.filled_trigon(background,
            screen_width/10, screen_height/10,
            screen_width*9/10, screen_height*9/10,
            screen_width/2, screen_height*9/10,
            (210, 200, 77))
    sprites     = pygame.sprite.LayeredDirty()
    image       = pygame.image.load('my_sprite.png')
    for _ in xrange(30): XSprite(image, sprites)
    del image

    # main game loop
    while True:
        for event in pygame.event.get():
            if event.type   == QUIT: return
            elif event.type == KEYDOWN and event.key == K_ESCAPE: return

        screen.blit(background, (0, 0))
        sprites.update(screen)
        sprites.draw(screen)
        pygame.display.flip()

class XSprite(pygame.sprite.DirtySprite):
    def __init__(self, image, *groups):
        super(XSprite, self).__init__(*groups)
        self.image  = image
        self.rect   = self.image.get_rect()
        self.rect.x = randint(0, 60)
        self.rect.y = randint(0, 40)
        self.dx, self.dy = randint(1, 16), randint(1, 16)

    def update(self, screen, *args):
        screen_w, screen_h = screen.get_size()
        self.rect.x += self.dx
        self.rect.y += self.dy
        if (self.rect.x + self.dx  + self.rect.w > screen_w) or \
                (self.rect.x + self.dx < 0):
            self.dx = -self.dx
        if (self.rect.y + self.dy + self.rect.h > screen_h) or \
                (self.rect.y + self.dy < 0):
            self.dy = -self.dy
        self.rect.move_ip(self.dx, self.dy)

if __name__ == '__main__':
    main()

# vim: set ft=python ts=8 sts=4 sw=4 tw=79 fdm=indent:
_______________________________________ snip
____________________________________________________