2
\$\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
\$\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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.