¿Alguna forma de acelerar Python y Pygame?

Estoy escribiendo un simple juego de rol de arriba a abajo en Pygame, y he descubierto que es bastante lento … Aunque no espero que Python o Pygame coincidan con el FPS de juegos hechos con lenguajes comstackdos como C / C ++ o el evento Byte Compiled Java, pero aún el FPS actual de pygame es como 15. Intenté renderizar mapas de bits de 16 colores en lugar de PNG o 24 mapas de bits, lo que aumentó ligeramente la velocidad, luego, desesperado, cambié todo a mapas de bits en blanco y negro y eso Hizo que los FPS fueran a 35. Pero no más. Ahora, de acuerdo con la mayoría de los libros de Desarrollo de juegos que he leído, para que un usuario esté completamente satisfecho con los gráficos del juego, el FPS de un juego 2d debería tener al menos 40, así que ¿hay alguna forma de boost la velocidad de pygame?

Utilice Psyco, para python2:

import psyco psyco.full() 

Además, habilitar doble búfer. Por ejemplo:

 from pygame.locals import * flags = FULLSCREEN | DOUBLEBUF screen = pygame.display.set_mode(resolution, flags, bpp) 

También puedes apagar el alfa si no lo necesitas:

 screen.set_alpha(None) 

En lugar de voltear toda la pantalla cada vez, manténgase al tanto de las áreas cambiadas y solo actualícelas. Por ejemplo, algo parecido a esto (bucle principal):

 events = pygame.events.get() for event in events: # deal with events pygame.event.pump() my_sprites.do_stuff_every_loop() rects = my_sprites.draw() activerects = rects + oldrects activerects = filter(bool, activerects) pygame.display.update(activerects) oldrects = rects[:] for rect in rects: screen.blit(bgimg, rect, rect) 

La mayoría de las funciones de dibujo (¿todas?) Devuelven un rect.

También puede establecer solo algunos eventos permitidos, para un manejo más rápido de eventos:

 pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP]) 

Además, no me molestaría en crear un búfer manualmente y no usaría el indicador HWACCEL, ya que he experimentado problemas con él en algunas configuraciones.

Usando esto, he logrado un FPS y una suavidad razonablemente buenos para un pequeño juego de plataformas 2d.

Al cargar imágenes, si necesita absolutamente transparencia u otros valores alfa, use el método Surface.convert_alpha (). Lo he estado usando para un juego que he estado progtwigndo, y ha habido un gran aumento en el rendimiento. EG: En tu constructor, carga tus imágenes usando:

 self.srcimage = pygame.image.load(imagepath).convert_alpha() 

Por lo que sé, cualquier transformación que realice en la imagen conserva el rendimiento que este método requiere. P.EJ:

 self.rotatedimage = pygame.transform.rotate(self.srcimage, angle).convert_alpha() 

se vuelve redundante si está utilizando una imagen en la que se haya convert_alpha() .

Todas estas son excelentes sugerencias y funcionan bien, pero también debes tener en cuenta dos cosas:

1) Blitear superficies sobre superficies es más rápido que dibujar directamente. Por lo tanto, antes de dibujar imágenes fijas en las superficies (fuera del bucle principal del juego), será más eficiente hacer un blit de la superficie a la pantalla principal. Por ejemplo:

 # pre-draw image outside of main game loop image_rect = get_image("filename").get_rect() image_surface = pygame.Surface((image_rect.width, image_rect.height)) image_surface.blit(get_image("filename"), image_rect) ...... # inside main game loop - blit surface to surface (the main screen) screen.blit(image_surface, image_rect) 

2) Asegúrate de no desperdiciar recursos dibujando cosas que el usuario no puede ver. por ejemplo:

 if point.x >= 0 and point.x <= SCREEN_WIDTH and point.y >= 0 and point.y <= SCREEN_HEIGHT: # then draw your item 

Estos son algunos conceptos generales que me ayudan a mantener alto el FPS.

Primero, siempre use ‘convert ()’ porque deshabilita el alfa, lo que hace que la fusión sea más rápida. Luego solo actualice las partes de la pantalla que necesitan ser actualizadas.

 global rects rects = [] rects.append(pygame.draw.line(screen, (0, 0, 0), (20, 20), (100, 400), 1)) pygame.display.update(rects) # pygame will only update those rects 

Nota:

Cuando muevas un sprite tienes que incluir en la lista el rectángulo desde su última posición.

Cuando se usan imágenes, es importante convertirlas con la función convert () de la imagen. He leído que convert () desactiva el alfa, que normalmente es bastante lento. También tuve problemas de velocidad hasta que utilicé una profundidad de color de 16 bits y la función de conversión para mis imágenes. Ahora mis FPS están alrededor de 150, incluso si borro una imagen grande en la pantalla.

 image = image.convert()#video system has to be initialed 

También las rotaciones y el escalamiento toman mucho tiempo para calcular. Una imagen grande y transformada se puede guardar en otra imagen si es inmutable.

Así que la idea es calcular una vez y reutilizar el resultado varias veces.

Puede intentar usar Psyco (http://psyco.sourceforge.net/introduction.html). A menudo hace un poco de diferencia.