Положение изображения не обновляется / обновляется медленнее при перемещении мыши

(пытается сыграть в игру «Ударь крота») Всякий раз, когда я двигаю мышью, положение изображения крота, кажется, перемещается в 3-5 раз медленнее, чем когда я не двигаю мышь, и я не уверен, что происходит. вызывая это, поскольку позиция должна обновляться в зависимости от того, сколько времени прошло.

Экран для игры 500x500 пикселей, изображения 50x50 пикселей, и есть массив 10x10, который действует как карта, чтобы решить, где разрешено появляться кротам.

Код:

  1. получить случайную позицию с карты 10x10

  2. обновлять положение изображения крота на один пиксель каждые 30 тиков

  3. получить положение мыши (один экран 500x500 пикселей)

  4. получить положение блока, который должен пройти крот (на карте 10x10)

  5. порядок, в котором изображения отображаются на экране:

    • карта

    • молоток во время движения

    • блок над кротом

    • родинка (увеличивается на 1 пиксель)

    • блок в исходном положении крота

    • молоток не двигается

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

    def moleGoUp(self):
        nbPixel = 0
        #returns a random position
        initialPos = self.returnRandPosition()
        while nbPixel < 50:
            tickCounter = pygame.time.get_ticks() % 30
            if tickCounter == 0:
                nbPixel += 1
            #gets position of mouse
            mousePos = pygame.mouse.get_pos()
            #blits the background block that the mole is supposed to go to
            blockAbovePos = [initialPos[1] * 50, initialPos[0] * 50 - 50]

            #blits the mole at position (goes up by one pixel every 20 ticks)
            newPos = [initialPos[1] * 50, (initialPos[0]*50 - nbPixel)]
            initPosToBlit = [initialPos[1] * 50, initialPos[0] * 50]
            for event in pygame.event.get():
                mousePos = pygame.mouse.get_pos()
                if event.type == pygame.QUIT:
                    sys.exit()
                #draws the map
                self.drawMap()
                # blits the hammer
                display_surf.blit(imagePlayer, tuple(mousePos))
                # counts how many ticks has passed
                tickCounter = pygame.time.get_ticks() % 30
                print("in event loop")

            display_surf.blit(imageWall, tuple(blockAbovePos))
            display_surf.blit(imageTarget, tuple(newPos))
            #blits the background at the original position of the mole
            display_surf.blit(imageWall,tuple(initPosToBlit))
            #blits the hammer
            display_surf.blit(imagePlayer, tuple(mousePos))
            print("out of event loop")

            #blits the background over the mole
            if nbPixel == 50:
                display_surf.blit(imageWall, (initialPos[1]*50, initialPos[0]*50 - nbPixel))
            pygame.display.update()

вывод из печати:

in event loop
out of event loop
in event loop
out of event loop
in event loop
out of event loop
in event loop
out of event loop
in event loop
out of event loop


person qwerty_99    schedule 08.09.2019    source источник
comment
Что делает drawMap()? Почему это нужно делать для каждого события? imagePlayer также рисуется для каждого события, а затем снова вне этого цикла. Вероятно, нужно только обновить mousePos внутри цикла (вообще не рисуя).   -  person Kingsley    schedule 09.09.2019
comment
Спасибо за ответ, я изменю код, чтобы посмотреть, что произойдет. Я использую drawMap() для рисования всех фоновых блоков, чтобы imagePlayer не оставлял за собой следов.   -  person qwerty_99    schedule 09.09.2019
comment
Таким образом, вам нужно вызвать drawMap() и нарисовать игрока только тогда, когда положение игрока действительно изменится. Событие мыши не может привести к изменению позиции.   -  person Kingsley    schedule 10.09.2019
comment
Ну, позиция игрока на самом деле является молотком, поэтому она в основном меняется при смене мыши. В итоге я нарисовал девять блоков вокруг мыши вместо всей карты, и это решило проблему.   -  person qwerty_99    schedule 10.09.2019


Ответы (1)


Падение производительности вызвано тем, что вы вызываете self.drawMap() в цикле событий. Цикл событий вызывается один раз для каждого события. В одном кадре может происходить несколько событий, особенно при перемещении мыши.
Я рекомендую создавать карту только при необходимости. Преобразуйте карту в объект pygame.Surface и blit карту Surface на дисплее в каждом кадре. После изменения карты заново создайте карту Surface.

Создайте метод рисования, который отображает целевую Surface, а не непосредственно отображаемую Surface:

def drawMap(self, traget_surf):
    # draw on traget_surf
    # [...]

Добавьте переменные map_surf и map_changed = True. Визуализируйте карту в цикле приложения, если установлено map_changed, и установите map_changed == False. blit map_surf Поверхность для отображения в каждом кадре. Всякий раз, когда карту необходимо изменить, достаточно установить map_changed = True:

map_surf = pygame.Surface(display_surf.get_size())
map_changed = True

while nbPixel < 50:

    # [...]

    if map_changed:
        self.drawMap(map_surf)
        map_changed = False


    # [...]

    display_surf.blit(map_surf, (0, 0))

    display_surf.blit(imageWall, tuple(blockAbovePos))
    display_surf.blit(imageTarget, tuple(newPos))
    display_surf.blit(imageWall,tuple(initPosToBlit))
    display_surf.blit(imagePlayer, tuple(mousePos))
person Rabbid76    schedule 08.01.2021