1
\$\begingroup\$

I am trying to make a vertical shoot em up using Python and Pygame. In order to handle timing, such as when certain enemies come out and other stage events, I've been using pygame.time.set_timer().

For example, to start spawning simple enemies, I would do the following:

First setup a USEREVENT:

SPWNGRUNT = pygame.USEREVENT + 0

Then in the main loop, check for events:

for event in pygame.event.get():
    if event.type == self.SPWNGRUNT:
        spawnGrunt()

Then at some point, trigger the event on a timer:

pygame.time.set_timer(SPWNGRUNT, 600)

However, I have quickly ran out of these USEREVENTS. I eventually get the below error:

ValueError: Event id must be between NOEVENT(0) and NUMEVENTS(32)

My questions are this. Is there a way around this? Also, is there maybe a better way of managing timing and events that I am not seeing?

\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

You can also use the time (delta time dt) that clock.tick(fps) returns to increase or decrease a timer variable.

import random
import pygame as pg


class Block(pg.sprite.Sprite):

    def __init__(self, pos):
        super().__init__()
        self.image = pg.Surface((40, 40))
        self.image.fill(pg.Color('sienna1'))
        self.rect = self.image.get_rect(topleft=pos)


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    font = pg.font.Font(None, 30)
    all_sprites = pg.sprite.Group()
    # Delta time is the time that has passed since clock.tick
    # was called the last time.
    dt = 0
    # We'll subtract dt (delta time) from this timer variable.
    timer = 1  # 1 means one second.

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True

        # Decrease timer to get a countdown.
        timer -= dt
        # When the timer is below or equal to 0, we spawn
        # a new block.
        if timer <= 0:
            all_sprites.add(Block((random.randrange(600),
                                  random.randrange(440))))
            # Reset the countdown timer to one second.
            timer = 1
        all_sprites.update()
        screen.fill(pg.Color('gray15'))
        all_sprites.draw(screen)
        timer_surface = font.render(str(round(timer, 3)), True, pg.Color('yellow'))
        screen.blit(timer_surface, (20, 20))

        pg.display.flip()
        # dt = time in seconds that passed since last tick.
        # Divide by 1000 to convert milliseconds to seconds.
        dt = clock.tick(60) / 1000


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()

Another alternative would be to use pygame.time.get_ticks() to calculate the passed time.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .