how to prevent button spamming in pygame

1.3k Views Asked by At

basically, at the moment, in my game the user can shoot as many times as they wish... this defeats the objective of the game (it makes it too easy) as they can just spam bullets. I have a 'Shop' type function which enables the user to purchase upgrades, therefore the spamming defeats the purpose of the shop.

elif event.key == K_SPACE:
                    newBullet = {'rect': pygame.Rect(bulletX, bulletY, 10, 3), 'surface': bullet}
                    pistolSound.play()
                    bullets.append(newBullet)

This is the code, what can I add to it in order prevent the button mashing spam. I'm bad with the pygame time function, but I have a feeling that could be used.

Additionally, i would like to my zombies to spawn consistently instead of at the moment where it is quite random...

timer = clock.tick()
    if waveNumber <= 2:
                timer += 1
                if timer == 2:
                    newZombie = {'rect':pygame.Rect(zombieX, zombieY, 75, 75), 'surface': zombie}
                    zombieSound.play()
                    zombies.append(newZombie)
                    timer = 0 

How would I go about doing this? I think I'm using the time function wrong.

Many thanks, Will.

2

There are 2 best solutions below

3
On

Limit the number of bullets to some small number:

elif event.key == K_SPACE:
    if len(bullets) < 3:
        newBullet = {'rect': pygame.Rect(bulletX, bulletY, 10, 3), 'surface': bullet}
        pistolSound.play()
        bullets.append(newBullet)
1
On

You should break your simulation and event handling into brief "turns" and allow the player to shoot only one bullet per turn (or even less).

The closest to your code example would be setting a "shot button pressed this turn" flag when the appropriate kind of event is processed, then after all events have been processed shooting at most once:

#each event
if event.key == K_SPACE:
    playerShooting=True 

...

#each turn
if playerShooting:
    newBullet = {'rect': pygame.Rect(bulletX, bulletY, 10, 3), 'surface': bullet}            
    pistolSound.play()
    bullets.append(newBullet)
playerShooting=False#clear to prepare for next turn

Zombies have a similar problem: you cannot predict the value of clock.tick(). Instead, spawn zombies at most once per turn (likely on a schedule, e.g. every fifth turn). The clock should be used to decide whether the main loop should proceed to game state update instead of waiting for further inputs, and to decide when to render frames.

For reference, a bad example and a good but incomplete example of PyGame main loops.