Я работаю над 2-й боковой скроллер в PyGame. Для каждой карты мы используем одну текстуру (это фактический размер текстуры):
Затем мы загружаем изображение с этим кодом:
sprite = pygame.image.load("Maps/MapTesting.png")
sprite.convert()
sprite = pygame.transform.scale(sprite,
(sprite.get_width()*6, sprite.get_height()*6))
Как видите, текстура взорвалась 6 раз, чтобы создать фактическую текстуру карты. В среднем эта текстура составляет около 4500x800. Эту текстуру нужно перетаскивать на экран каждый кадр , потому что весь экран загрязнен (благодаря боковой прокрутке). Мы делаем это с помощью этого кода:
screen.blit(sprite, (0, 0),
(cameraposx, cameraposy, windowheight, windowwidth))
И это работает. Проблема в том, что он довольно медленный: я получаю скудные 40 FPS на малоприличном ПК, и это без какого-либо реального AI / объектов, в то время как мы стремимся к 60 FPS. Как мы можем ускорить это?
Обратите внимание, что приведенный выше код очищен и вырван из контекста. Полный код можно найти здесь: https://github.com/nightcracker/PyGG2
И последнее, но не менее важное: хотя приведенное выше изображение может выглядеть как 8-битное, в игре есть элементы, требующие большей битовой глубины.
Ответы:
Позвольте мне перечислить некоторые общие сравниваемые оптимизации, связанные с блиттингом пикселей на поверхности (из моего опыта).
1) Обычно изображения палитры (индексированные изображения) при блицировании будут подвергаться одному дополнительному уровню перенаправления (для получения цвета). Поэтому они будут медленными при блицании по сравнению с изображениями с истинным цветом.
2) Пиксельные данные истинного цвета (предположим, без альфа-канала, скажем, 24-битных данных) могут быть быстро скопированы, поскольку мы можем сделать memcpy для каждой строки развертки изображения (если мы копируем часть изображения) в буфер кадра устройства .Если данные, которые будут скопированы, представляют собой полное изображение, то мы можем напрямую запомнить все данные, что намного быстрее!
3) Пиксельные данные альфа-пикселя будут самыми дорогими, поскольку они будут включать вычисление результирующего каждого компонента, и нам нужно снова упаковать его в данные RGB. Проще говоря, больше операций для каждого пикселя для получения окончательного цвета!
Я не работал над pyGame раньше. Но, беглый взгляд на его исходный код, заставил меня предположить, что он использует функции Blit 'sdl' под капотом. Обычно Sdl blit будет очень быстрым и оптимизированным, поэтому просто сделайте не из вышеупомянутых пунктов и профиль еще раз! Удачи!
* Обновление: * Установка цветового ключа похожа на добавление одной дополнительной проверки при перетаскивании каждого пикселя на поверхность. Что-то вроде этого -
Итак, здесь, если вы видите, мы ограничены в использовании memcpy, поскольку нам нужно проверить правильность цвета каждого пикселя!
источник
set_colorkey
проскользнул на текстуру карты, дав ей (дорогой) альфа-канал. Этоconvert
исправлено, и теперь я использую 150 FPS стабильно на этом дерьмовом ПК. Спасибо!sprite.convert()
не делает то, что вы думаете, что делает.sprite = sprite.convert()
это то, что вам нужно.источник
sprite = sprite.convert()
в реальном коде, хотя :)sprite = pygame.image.load("Maps/MapTesting.png").convert()