Анимация Pygame Lightning с использованием pygame.timer.set_timer () - PullRequest
0 голосов
/ 03 июля 2018

В настоящее время я пытаюсь создать анимацию молнии, используя pygame. Я планировал запуск анимации молнии каждые 3 секунды с помощью модуля pygame.timer.set_timer (), поскольку у меня будут происходить другие анимации, независимые от анимации молнии.

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

Однако lightning_event, похоже, не запускается каждый раз внутри цикла while, и задержка не происходит.

Я посмотрел на пример invaders с использованием pygame.timer.set_timer (), хотя он не использует координаты xy. Я попытался настроить код invaders так, чтобы он использовал координаты xy, но он тоже не работал.

Другой вопрос, который у меня возникает, заключается в том, что если одновременно происходит много событий, лучше ли использовать многопоточность или многопроцессорность, чем использование pygame.timer.set_timer ()? Если да, то как можно использовать многопоточность или многопроцессорность с модулем pygame? Особенно из-за GIL питона?

Вот мой код для анимации освещения:

import pygame
pygame.init()

BLACK = (0,0,0)
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
YELLOW = (200,240,70)

size = (700,500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Multithreading Project")

done = False

delay1 = 3000 
clock = pygame.time.Clock()

def lightning(y_coord,y_coord_incr):
    pygame.draw.polygon(screen,YELLOW,[[200,200],[100,y_coord],[300,y_coord]])

lightning_event = pygame.USEREVENT + 1
pygame.time.set_timer(lightning_event, delay1)

while not done:
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            done = True
        elif event.type == lightning_event:
            if y_coord > 500:
                y_coord = 200
    screen.fill(WHITE)
    lightning(y_coord,y_coord_incr)
    y_coord = y_coord + y_coord_incr
    pygame.display.flip()
    clock.tick(60)
pygame.quit()

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Вы можете добавить логическую переменную (я назвал ее lightning_anim_playing) и установить ее на True, чтобы запустить анимацию.

Во время воспроизведения анимации увеличьте y_coord и нарисуйте молнию.

Когда y_coord больше 500, запустите таймер для следующей молнии (pygame.time.set_timer(lightning_event, delay1)) и установите логическую переменную на False, чтобы остановить анимацию.

Когда таймер завершит работу, остановите его (pygame.time.set_timer(lightning_event, 0)), сбросьте y_coord и установите логическую переменную на True снова, чтобы начать следующую анимацию.

import pygame


WHITE = (255,255,255)
YELLOW = (200,240,70)

pygame.init()
screen = pygame.display.set_mode((700, 500))
clock = pygame.time.Clock()

delay1 = 3000
lightning_event = pygame.USEREVENT + 1
pygame.time.set_timer(lightning_event, delay1)
y_coord = 200
y_coord_incr = 3
lightning_anim_playing = False

done = False
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == lightning_event:
            pygame.time.set_timer(lightning_event, 0)  # Stop the timer.
            lightning_anim_playing = True  # Start the animation.
            y_coord = 200  # Reset the y_coord.

    if lightning_anim_playing:
        # Update the y_coord.
        y_coord += y_coord_incr
        if y_coord > 500:
            # Stop the animation.
            lightning_anim_playing = False
            # Start the timer for the next lightning.
            pygame.time.set_timer(lightning_event, delay1)

    screen.fill(WHITE)
    # Draw the lightning if the animation is playing.
    if lightning_anim_playing:
        pygame.draw.polygon(screen,YELLOW,[[200,200],[100,y_coord],[300,y_coord]])

    pygame.display.flip()
    clock.tick(60)

pygame.quit()
0 голосов
/ 04 июля 2018

Вы очень редко хотите использовать многопроцессорность или многопоточность. Для любого графически связанного кода его следует запускать в основном потоке. Многопроцессорная обработка / многопоточность возможны только в том случае, если вы пытаетесь загрузить или обработать большие объемы данных, сохраняя при этом окно отзывчивым. Если вы используете другие библиотеки, например, для работы в сети (витой реактор), которые имеют собственную mainloop, вы можете захватить их mainloop, так как pygame не имеет встроенной mainloop.

Pygame также имеет более последовательный API для обработки событий, и вы обрабатываете все последние события перед рисованием на экране, поэтому, когда события происходят в одно и то же время, вы обрабатываете их последовательно, но любые визуальные различия видны после обновления экрана. Процедура извлечения любых недавних событий, их обработки с последующим обновлением экрана каждый кадр - это практическое правило при создании приложения Pygame. Внедрение многопоточности / многопроцессорности обычно снижает производительность вашей программы или не влияет на нее, в то же время существенно усложняя ее программирование и сборку. Для анимации вы также можете использовать временные метки, используя import time ; time.time(), что позволяет вам не ограничиваться часами пигмеев. Пока код, интенсивно загружающий ЦП, сводится к минимуму между циклами извлечения событий и отрисовки, нет причин слишком усложнять ваш код. Вы всегда можете протестировать свою программу во время выполнения программы на наличие ошибок FPS, а затем выборочно оптимизировать свой код.

В качестве примечания: Pygame не следует использовать для создания сложных игр, а скорее как инструмент обучения для развития своих навыков, поскольку Pygame является несколько ограниченным и устаревшим пакетом. Например, наличие нескольких дисплеев утомительно и обычно выполняется с помощью многопроцессорной обработки, обработчик событий Pygame часто не выдает столько информации, сколько необходимо (количество перемещений колеса прокрутки). Хорошей альтернативой является Pyglet, но поначалу довольно сложно использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...