pos - ¿Alguna forma de acelerar Python y Pygame?
python pygame documentation (6)
Estoy escribiendo un rpg simple de arriba hacia abajo en Pygame, y he descubierto que es bastante lento ... Aunque no estoy esperando que python o pygame coincidan con los FPS de juegos hechos con lenguajes compilados como C / C ++ o evento Byte compilado algunos como Java, pero 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 monocromáticos en blanco y negro y hizo que los FPS pasaran 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 debe ser al menos de 40, entonces ¿hay ALGUNA forma de aumentar la velocidad de pygame?
Podría intentar usar Psyco (http://psyco.sourceforge.net/introduction.html). A menudo hace una gran diferencia.
Use Psyco, para python2:
import psyco
psyco.full()
Además, habilite el doble buffer. Por ejemplo:
from pygame.locals import *
flags = FULLSCREEN | DOUBLEBUF
screen = pygame.display.set_mode(resolution, flags, bpp)
También puede desactivar alfa si no lo necesita:
screen.set_alpha(None)
En lugar de pasar la pantalla entera todo el tiempo, realice un seguimiento de las áreas modificadas y solo actualícelas. Por ejemplo, algo más o menos así (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 configurar 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 buffer manualmente y no usaría la bandera HWACCEL, ya que he tenido problemas con ella en algunas configuraciones.
Usando esto, he logrado FPS y suavidad razonablemente buenos para un pequeño juego de plataformas en 2d.
Primero, use siempre ''convert ()'' porque desactiva el alfa, lo que hace que el bliting sea más rápido. 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 mueva un sprite, debe incluir en la lista el rect desde su última posición.
Cuando cargue 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 programando, y ha sido un gran aumento en el rendimiento. EG: en tu constructor, carga tus imágenes usando:
self.srcimage = pygame.image.load(imagepath).convert_alpha()
Hasta donde puedo decir, cualquier transformación que hagas a la imagen conserva el rendimiento que este método llama. P.EJ:
self.rotatedimage = pygame.transform.rotate(self.srcimage, angle).convert_alpha()
se vuelve redundante si está utilizando una imagen que ha convert_alpha()
en ella.
Al usar imágenes, es importante convertirlas con la función convert () de la imagen. He leído que convert () deshabilita alfa, que normalmente es bastante lento. También tuve problemas de velocidad hasta que usé una profundidad de color de 16 bits y la función de conversión para mis imágenes. Ahora mis FPS son alrededor de 150, incluso si blight una imagen grande en la pantalla.
image = image.convert()#video system has to be initialed
También las rotaciones y escalas tardan mucho tiempo en calcular. Una gran imagen transformada se puede guardar en otra imagen si es inmutable.
Entonces, la idea es calcular una vez y reutilizar el resultado varias veces.
Todas estas son excelentes sugerencias y funcionan bien, pero también debes tener en cuenta dos cosas:
1) Blitting superficies en superficies es más rápido que dibujar directamente. Por lo tanto, pre-dibujar imágenes fijas en las superficies (fuera del bucle principal del juego), luego ajustar la superficie a la pantalla principal será más eficiente. 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 FPS alto.