Любой способ ускорить 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). Это часто имеет большое значение.