Как мне постоянно запускать действие через определенные промежутки времени? Враг стреляет постоянным лучом вместо пуль в pygame

Попытка сделать врага в pygame, который стреляет пулями по прямой в pygame. Мне удалось заставить врага стрелять, но он стреляет постоянным пучком пуль, а не разносит их. Есть ли способ развести пули?

Это класс врага

class Boss(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((100, 70))
        self.image.fill(white)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.y = (WIDTH / 2) - 500
        self.speedy = 3

    def update(self):
        self.rect.y += self.speedy
        if self.rect.y >= 30:
            self.rect.y = 30

    def shoot(self):
        bossbullet = Bossbullet(self.rect.centerx, self.rect.bottom)
        all_sprites.add(bossbullet)
        bossbullets.add(bossbullet)


class Bossbullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 20))
        self.image.fill(white)
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.speedy = -10

    def update(self):
        self.rect.y -= self.speedy

        if self.rect.bottom < 0:
            self.kill()

all_sprites = pygame.sprite.Group()
boss = Boss()
all_sprites.add(boss)
bossbullets = pygame.sprite.Group()

это цикл, в котором идет игра и враг стреляет

running = True
while running:

    clock.tick(FPS)
    if boss.rect.y >= 30:
        boss.shoot()

person d'arby    schedule 03.10.2019    source источник


Ответы (1)


Рекомендую использовать таймер события. Используйте pygame.time.set_timer() для многократного создания _ 2_. например.:

milliseconds_delay = 500 # 0.5 seconds
bullet_event = pygame.USEREVENT + 1
pygame.time.set_timer(bullet_event, milliseconds_delay)

Обратите внимание: в pygame можно определять события клиента. Каждому событию нужен уникальный идентификатор. Идентификаторы пользовательских событий должны начинаться с pygame.USEREVENT. В этом случае pygame.USEREVENT+1 - это идентификатор события таймера, которое порождает пули.

Создайте новую пулю, когда событие происходит в цикле событий:

running = True
while running:

    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

         elif event.type == bullet_event:
             if boss.rect.y >= 30:
                 boss.shoot()

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

Событие таймера можно остановить, передав 0 параметру времени. например.:

delay_time = 500  # 0.5 seconds
pause_time = 3000 # 3 seconds
bullet_event = pygame.USEREVENT + 1
pygame.time.set_timer(bullet_event, delay_time)

no_shots = 0

running = True
while running:

    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

         elif event.type == bullet_event:
             if boss.rect.y >= 30:
                 boss.shoot()

                 # change the timer event time
                 if no_shots == 0:
                     pygame.time.set_timer(bullet_event, delay_time)
                 no_shots += 1
                 if no_shots == 5:
                     pygame.time.set_timer(bullet_event, pause_time)
                     no_shots = 0

    killed = # [...] set state when killed

    # stop timer
    if killed:
        pygame.time.set_timer(bullet_event, 0)
person Rabbid76    schedule 03.10.2019
comment
не могли бы вы объяснить, что происходит на линии bullet_event = pygame.USEREVENT + 1 , пожалуйста? - person d'arby; 03.10.2019
comment
@ d'arby Извините, ссылка была неправильной. В pygame вы можете определять свои собственные события. Каждому событию нужен уникальный идентификатор. Идентификаторы пользовательских событий должны начинаться с pygame.USEREVENT. pygame.USEREVENT+1 - это идентификатор события таймера, порождающего пули. - person Rabbid76; 03.10.2019
comment
что делает + 1? - person d'arby; 03.10.2019
comment
@ d'arby Добавляет 1 к числу, которое хранится в pygame.USEREVENT. Вы также можете использовать pygame.USEREVENT+4711. Используйте любое число ›= pygame.USEREVENT в качестве идентификатора мероприятия. - person Rabbid76; 03.10.2019
comment
АА, вижу. Повлияет ли что-нибудь в моем коде, если он изменится? - person d'arby; 03.10.2019
comment
Нет, это просто идентификатор (значение, представляющее имя). Внутреннее имя (значение) события - это номер pygame.USEREVENT+1 - person Rabbid76; 03.10.2019
comment
Ох, хорошо. Спасибо за помощь! - person d'arby; 03.10.2019
comment
есть ли способ сделать так, чтобы противник делал паузу на некоторое время после ... скажем, 5 выстрелов, а затем снова начинает стрелять после паузы. Это будет зацикливаться, пока враг не будет убит - person d'arby; 03.10.2019
comment
Я не понимал, что это можно использовать таким образом. Спасибо - person d'arby; 03.10.2019
comment
хорошо, это было давно, и я понял, что это старый пост. Но я пробовал сделать то, что вы отключаете таймер, передавая 0 для мс, но когда я запускаю программу и появляется босс, босс просто не стреляет вообще - person d'arby; 14.08.2020
comment
@ d'arby Конечно, передача 0 таймеру означает его остановку. В любом случае, если у вас возник новый вопрос, задайте общественный вопрос. - person Rabbid76; 14.08.2020
comment
надо было сформулировать это лучше. В основном я делал то же самое, что и вы: если он убит, таймер установлен на 0. Но затем, когда босс появляется на экране (когда он жив), босс просто не стреляет, даже если он не в убитом состоянии. - person d'arby; 15.08.2020