Почему pygame не справляется с рисованием 80 изображений одновременно? - PullRequest
2 голосов
/ 09 июля 2020

Я начал программировать «2D Minecraft» с помощью pygame просто для удовольствия.

Однако прямо сейчас, даже рисование около 70 изображений на экране приводит к падению количества кадров в секунду до 20.

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

Я опубликовал код на Github .

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Ваш код вызывает player.Physics() каждый кадр и проверяет конфликты с каждым блоком. Даже если игрок не движется, он все равно проверяет.

Кроме того: я не совсем понял причину некоторых кодов скорости здесь. Кажется, что скорость игрока меняется даже без ввода данных пользователем, и x уменьшается, y увеличивается, но нет проверок, которые можно было бы остановить, когда она равна нулю / почти нулю. Похоже, что код использует много ЦП для проверки коллизий, даже когда скорость становится практически нулевой. Обычный способ оптимизации такого рода вещей - сгруппировать ваши блоки в структуру данных quadtree . Это разбивает ваши блоки на кварталы в зависимости от их положения. Затем каждый квартал снова делится на четверти и т. Д.

Это означает, что вам нужно только один раз , чтобы исключить 75% несовпадающих блоков. Затем вы снова сталкиваетесь и удаляете еще 75% не сталкивающихся блоков. В конце концов вы перейдете к столкновениям, которые вам действительно нужно проверить. Решайте глубину квадродерева самостоятельно, но даже пара уровней избавит вас от множества ненужных проверок.

1 голос
/ 09 июля 2020
  1. Я предлагаю вам использовать .convert () для каждого загруженного изображения, чтобы удвоить FPS

    blockTextures = {block: transform.scale(image.load('blocks/' + block + '.png').convert(), (128, 128)) for block in allBlocks}
    breakTextures = [transform.scale(image.load('blocks/destroy_' + str(i) + '.png').convert(), (128, 128)) for i in range(10)]
    

https://www.pygame.org/docs/ref/surface.html#pygame .Surface.convert

Делайте меньше вычислений (физики) в каждом кадре. Запомните необходимый кадр для направления игрока

 class Player: # This class controls and draws the player
     def __init__(self):
         self.pos = [0, 0]
         self.velocity = [0, 0]

         self.imageRight = transform.scale(image.load('steve.png'), (57, 230))
         self.imageLeft = transform.flip(self.imageRight, True, False)
         self.AImage = self.imageLeft

     def draw(self, screen, size):
         screen.blit(self.AImage, (size[0] / 2 - 28, size[1] / 2 - 115))

     def physics(self, blocks): # The first part checks for input, the second part does the physics
         pressed = key.get_pressed()
         if pressed[K_LEFT]:
             self.velocity[0] -= 0.1
             self.AImage = self.imageLeft

         if pressed[K_RIGHT]:
             self.velocity[0] += 0.1
             self.AImage = self.imageRight

И ускорение на 10% больше FPS

Может быть, FPS может быть лучше, если вы вычисляете World один раз для одного большого изображения в начале игры и рисуете его часть на экране один раз за кадр. Я не уверен в этом.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...