Есть ли способ ускорить Python и Pygame? - PullRequest
12 голосов
/ 18 июня 2011

Я пишу простой нисходящий RPG в Pygame, и я обнаружил, что он довольно медленный .... Хотя я не ожидаю, что python или pygame будут соответствовать FPS игр, созданных на скомпилированных языках, таких как C / C ++ илиБайт скомпилированные, такие как Java, но все же текущий FPS у pygame примерно 15. Я пытался рендерить 16-битные растровые изображения вместо PNG или 24 битовых, что немного увеличивало скорость, затем в отчаянии я переключил все на черно-белый монохромныйрастровые изображения и это заставило FPS перейти на 35. Но не более.Теперь, согласно большинству книг по разработке игр, которые я читал, чтобы пользователь был полностью удовлетворен игровой графикой, FPS 2d-игры должен быть не менее 40, так есть ли ЛЮБОЙ способ повысить скорость игры в пигме?

Ответы [ 6 ]

17 голосов
/ 18 июня 2011

Используйте Psyco, для python2:

import psyco
psyco.full()

Также включите двойной буфер.Например:

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

Вы также можете отключить альфа, если вам это не нужно:

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-платформера.

3 голосов
/ 16 января 2017

Все это отличные предложения и хорошо работают, но вы также должны иметь в виду две вещи:

1) Размытие поверхностей на поверхности происходит быстрее, чем рисование напрямую.Таким образом, предварительное рисование фиксированных изображений на поверхностях (вне основного игрового цикла), а затем перетаскивание поверхности на главный экран будет более эффективным.Например:

# 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.

3 голосов
/ 14 июня 2013

При загрузке изображений, если вам абсолютно необходима прозрачность или другие альфа-значения, используйте метод Surface.convert_alpha ().Я использовал его для игры, которую программировал, и это привело к огромному увеличению производительности.Например: в вашем конструкторе загрузите ваши изображения, используя:

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

Насколько я могу судить, любые преобразования, которые вы делаете с изображением, сохраняют производительность, которую вызывает этот метод.Например:

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

становится избыточным, если вы используете изображение, на котором было запущено convert_alpha().

3 голосов
/ 21 марта 2013

При использовании изображений важно конвертировать их с помощью функции convert () изображения.Я читал, что convert () отключает альфу, которая обычно довольно медленная.У меня также были проблемы со скоростью, пока я не использовал глубину цвета 16 бит и функцию преобразования для своих изображений.Теперь мой FPS составляет около 150, даже если я перетаскиваю большое изображение на экран.

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

Кроме того, для вычисления поворотов и масштабирования требуется много времени.Большое преобразованное изображение может быть сохранено в другом изображении, если оно является неизменным.

Таким образом, идея состоит в том, чтобы рассчитать один раз и повторно использовать результат несколько раз.

2 голосов
/ 31 марта 2013

Во-первых, всегда используйте 'convert ()', потому что он отключает альфа, что ускоряет блиттинг Затем обновляйте только те части экрана, которые необходимо обновить.

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

Примечание:

При перемещении спрайта вы должны включить в список прямоугольник с последней позиции.

1 голос
/ 18 июня 2011

Вы можете попробовать использовать Psyco (http://psyco.sourceforge.net/introduction.html). Часто это имеет большое значение.

...