Любой способ ускорить Python и Pygame?
Я пишу простой сверху вниз rpg в Pygame, и я обнаружил, что это довольно медленно.... Хотя я не ожидаю, что python или pygame будут соответствовать FPS игр, сделанных с скомпилированными языками, такими как C/C++ или event Byte, такие как Java, но все же текущий FPS pygame похож на 15. Я попробовал рендеринг 16-цветных растровых изображений вместо PNGs или 24 растровых изображений, что немного увеличило скорость, а затем в отчаянии я переключил все на черно-белые монохромные растровые изображения, и это сделало FPS перейти к 35. Но не больше. Теперь, согласно большинству книг по разработке игр, которые я прочитал, для того, чтобы пользователь был полностью удовлетворен игровой графикой, FPS 2d-игры должен быть не менее 40, так что есть ли способ повысить скорость pygame?
6 ответов
используйте Psyco, для python2:
import psyco
psyco.full()
кроме того, включите doublebuffering. Например:
from pygame.locals import *
flags = FULLSCREEN | DOUBLEBUF
screen = pygame.display.set_mode(resolution, flags, bpp)
вы также можете отключить alpha, если вам это не нужно:
screen.set_alpha(None)
вместо того, чтобы листать весь экран каждый раз, отслеживать изменения и обновлять только те. Например, примерно так (основной цикл):
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)
большинство (все?) функции рисования возвращают прямую кишку.
вы также можете установить только некоторым разрешено событий, для более быстрой обработки событий:
pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP])
кроме того, я бы не стал создавать буфер вручную и не использовал флаг HWACCEL, так как у меня возникли проблемы с ним в некоторых настройках.
используя это, я достиг достаточно хорошего FPS и гладкости для небольшого 2d-платформера.
при загрузке изображений, Если вам абсолютно необходима прозрачность или другие альфа-значения, используйте поверхность.convert_alpha() метод. Я использовал его для игры, которую я программировал, и это было огромное увеличение производительности. Например: в конструкторе загрузите изображения с помощью:
self.srcimage = pygame.image.load(imagepath).convert_alpha()
насколько я могу судить, любые преобразования, которые вы делаете с изображением, сохраняют производительность, вызываемую этим методом. Например:
self.rotatedimage = pygame.transform.rotate(self.srcimage, angle).convert_alpha()
становится излишним, если вы используете изображение, которое имел convert_alpha()
побежал на него.
все это отличные предложения и хорошо работают, но вы также должны иметь в виду две вещи:
1) Blitting поверхности на поверхности более быстры чем чертеж сразу. Таким образом, предварительное рисование фиксированных изображений на поверхности (вне основного игрового цикла), а затем blitting поверхности на главный экран будет более эффективным. Для примера:
# 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) Убедитесь, что вы не тратите ресурсы, рисуя вещи, которые пользователь не может видеть. например:
if point.x >= 0 and point.x <= SCREEN_WIDTH and point.y >= 0 and point.y <= SCREEN_HEIGHT:
# then draw your item
эти есть некоторые общие концепции, которые помогают мне держать FPS высоким.
во-первых, всегда используйте 'convert ()', потому что он отключает alpha, что делает bliting быстрее. Затем обновите только те части экрана, которые необходимо обновить.
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
Примечание:
при перемещении спрайта, вы должны включить в список прямоугольник из своей последней позиции.
при использовании изображений важно преобразовать их с помощью функции convert () - изображения. Я читал, что convert () отключает alpha, которая обычно довольно медленная. У меня также были проблемы со скоростью, пока я не использовал глубину цвета 16 бит и функцию преобразования для моих изображений. Теперь мой FPS вокруг 150, даже если я Блит большое изображение на экран.
image = image.convert()#video system has to be initialed
также повороты и масштабирование занимает много времени для расчета. Большое, преобразованное изображение можно сохранить в другом изображении, если оно неизменный.
поэтому идея состоит в том, чтобы вычислить один раз и повторно использовать результат несколько раз.
вы можете попробовать использовать Psyco (http://psyco.sourceforge.net/introduction.html). Это часто имеет большое значение.