My game is essentially flappy bird but with enemies, ammo (goatee's), and also flies instead of flaps (That part isn't necessary). I'm trying to figure out how to spawn the pipes in, the goatee's (ammo for the player to collect), and also the enemies. I've just learned about pygame.time.set_timer()
today and I set it up with my pipes and it worked perfectly! That was until I created the goatee timer and then quickly found out that it won't set 2 separate timers. After looking over PyGames documentation I found this -
It is also worth mentioning that a particular event type can only be put on a timer once. In other words, there cannot be two timers for the same event type. Setting an event timer for a particular event discards the old one for that event type.
I've looked around and have not been able to find a way around this. Is there a way to create another event type? Is there a different way I should be using timers? Code listed below shows how I'm creating them:
Creating the timers:
SPAWNPIPE = pygame.USEREVENT
pygame.time.set_timer(SPAWNPIPE, 3000)
SPAWNGOATEE = pygame.USEREVENT
pygame.time.set_timer(SPAWNGOATEE, 6000)
Event handling inside the while loop:
#All game events
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and not time_started:
is_playing = True
time_started = True
start_time = time.time()
if event.type == SPAWNPIPE:
spawn_pipe = True
if event.type == SPAWNGOATEE:
spawn_goatee = True
Even though pipe timer is set to 3000 milliseconds, they spawn at 6000 milliseconds because USEREVENT can only be used for one timer so the second one created overrides the first
Some google searching on creating custom events led me to the following SO question, PyGame Custom Event, as well as the following pygame docs, https://pyga.me/docs/ref/event.html#pygame.event.Event and https://pyga.me/docs/ref/event.html#pygame.event.custom_type.
After writing a quick script to test this (copy/pasted below), it appears to work perfectly. Instead of using the same event type, create your own event type with pygame.event.custom_type()
import pygame
RED = (200, 100, 100)
GREEN = (100, 200, 100)
BLUE = (100, 100, 200)
screen = pygame.display.set_mode((600, 400))
screen.fill((255, 255, 255))
pygame.display.flip()
REDEVENT = pygame.event.custom_type()
GREENEVENT = pygame.event.custom_type()
BLUEEVENT = pygame.event.custom_type()
pygame.time.set_timer(REDEVENT, 1000)
pygame.time.set_timer(GREENEVENT, 1100)
pygame.time.set_timer(BLUEEVENT, 1200)
running = True
while running:
pygame.time.wait(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
if event.type == REDEVENT:
screen.fill(RED)
pygame.display.flip()
continue
if event.type == GREENEVENT:
screen.fill(GREEN)
pygame.display.flip()
continue
if event.type == BLUEEVENT:
screen.fill(BLUE)
pygame.display.flip()
continue
This would mean that, when creating your events, you should be using
SPAWNPIPE = pygame.event.custom_type()
pygame.time.set_timer(SPAWNPIPE, 3000)
SPAWNGOATEE = pygame.event.custom_type()
pygame.time.set_timer(SPAWNGOATEE, 6000)
Logically the issue can be seen from your event handling, where SPAWNPIPE
and SPAWNGOATEE
were originally the same, so when you tested the type of the event, either event would actually trigger both event type checks
CAVEAT:
As @luke-b pointed out, Pygame- way to create more USEREVENT type events? mentions some specifics on the caveats of creating arbitrary user events, going into more detail than the docs do.
Basically, you can only create a limited number of events (9 according to the SO answer) and pygame.event.custom_type()
will raise an error if you try to create too many