I'm creating a little space shooter game. I need to limit the amount of times a player can fire, I'm setting a 2 second limit. But whenever I try to implement that it just won't work. The bullets keep firing multiple times a second.

Here's my code, I'd be very grateful if something could help:

def main():
    pygame.init()
    screen = pygame.display.set_mode((1000,750))
    pygame.display.set_caption("Alien Invasion")
    pygame.mouse.set_visible(False)

    #load the bitmaps
    background = pygame.image.load("background.jpg").convert_alpha()
    space_ship = pygame.image.load("space_ship.tga").convert_alpha(background)

    #create the objects
    player = Space_Ship("space_ship.tga", screen)
    asteroid_small = Asteroid(screen, "small")
    asteroid_large = Asteroid(screen, "large")
    asteroid_medium = Asteroid(screen, "medium")

    #load the groups
    asteroid_group = pygame.sprite.Group()
    bullet_group = pygame.sprite.Group()
    asteroid_group.add(asteroid_small, asteroid_large, asteroid_medium)

    clock_start = 0

    #start the main game loop
    while True:
        clock_start = time.clock()
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()

        keys = pygame.key.get_pressed()
        if keys[K_SPACE]:
            if clock_start > 2:
                bullet = Space_Ship_Ammo(screen, player)
                bullet_group.add(bullet)
                clock_start = 0

        #draw the background
        screen.blit(background, (0,0))

        #update the sprites
        player.update()
        asteroid_small.update()
        asteroid_large.update()
        asteroid_medium.update()

        bullet_group.update()
        pygame.display.update()

main()

Dani AI

Generated

Quick, practical fix for that builds on the points from and : switch to an event-driven fire action and track a single cooldown timestamp in milliseconds. Only update that timestamp when a bullet is actually spawned. That prevents the timer from being reinitialized every frame and gives you a strict gap between shots.

Example (event-driven, one shot per press):

fire_delay = 2000           # milliseconds
last_fire_time = -fire_delay

for event in pygame.event.get():
    if event.type == QUIT:
        sys.exit()
    if event.type == KEYDOWN and event.key == K_SPACE:
        now = pygame.time.get_ticks()
        if now - last_fire_time >= fire_delay:
            bullet_group.add(Space_Ship_Ammo(screen, player))
            last_fire_time = now

If you prefer holding space to produce a steady stream, keep pygame.key.get_pressed() but gate creation with the same now - last_fire_time >= fire_delay check. Also use a pygame.time.Clock() and call clock.tick(60) at the end of the loop so timing stays predictable and CPU usage stays reasonable.

Troubleshooting hints: make sure last_fire_time is only set when you create a bullet (not every loop), verify bullets aren't also spawned inside an update() call, and add a short debug print of now - last_fire_time to see the real intervals. If KEYDOWN still seems to repeat on a single press, check OS/key-repeat behavior or explicitly disable pygame key repeat.

Recommended Answers

All 2 Replies

Maybe I'm missing something, but how are you keeping time? You set clock_start, but I don't see the math to determine how much time has elapsed. I would expect something like

clock_start = time.clock()

time_elapsed = time.clock() - clock_start

if time_elapsed > 2:
    ....(and so on)

time.clock() gives different outputs when we look at its implementation in linux vs the implementation in windows. thereby we need to first determine which OS are you making the game for.

Stating that, line 25 and 26 of the above snippet seems to indicate that you re-assign clock_start everytime in the loop. This might cause unwanted circumstances happening for you.

Maybe a better solution would be that you note down the time a certain bullet was fired.. Keep iterating and check

if current_time - last_fired > 2 : 
    // do something 
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.