How to Continuously Trigger an Action at Certain Time Intervals? Enemy Shoots Constant Beam Instead of Bullets in Pygame

How do I continuously trigger an action at certain time intervals? Enemy shoots constant beam instead of bullets in pygame

I recommend to use a timer event. Use pygame.time.set_timer() to repeatedly create an USEREVENT. e.g.:

milliseconds_delay = 500 # 0.5 seconds
bullet_event = pygame.USEREVENT + 1
pygame.time.set_timer(bullet_event, milliseconds_delay)

Note, in pygame customer events can be defined. Each event needs a unique id. The ids for the user events have to start at pygame.USEREVENT. In this case pygame.USEREVENT+1 is the event id for the timer event, which spawns the bullets.

Create a new bullet when the event occurs in the event loop:

running = True
while running:

clock.tick(FPS)

for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

elif event.type == bullet_event:
if boss.rect.y >= 30:
boss.shoot()

is there any way to make it so the enemy pauses for a while after..let's say 5 shots, then starts shooting again after the pause

The timer event can be stopped by passing 0 to the time parameter. e.g.:

delay_time = 500  # 0.5 seconds
pause_time = 3000 # 3 seconds
bullet_event = pygame.USEREVENT + 1
pygame.time.set_timer(bullet_event, delay_time)

no_shots = 0

running = True
while running:

clock.tick(FPS)

for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

elif event.type == bullet_event:
if boss.rect.y >= 30:
boss.shoot()

# change the timer event time
if no_shots == 0:
pygame.time.set_timer(bullet_event, delay_time)
no_shots += 1
if no_shots == 5:
pygame.time.set_timer(bullet_event, pause_time)
no_shots = 0

killed = # [...] set state when killed

# stop timer
if killed:
pygame.time.set_timer(bullet_event, 0)

How do i add a cooldown to enemy attacks in pygame?

The way to do that using pygame, is to usee pygame.time.set_timer() to repeatedly create an USEREVENT. e.g.:

milliseconds_delay = 1000 # 1 seconds
timer_event = pygame.USEREVENT + 1
pygame.time.set_timer(timer_event, milliseconds_delay)

In pygame customer events can be defined. Each event needs a unique id. The ids for the user events have to be between pygame.USEREVENT (24) and pygame.NUMEVENTS (32). In this case pygame.USEREVENT+1 is the event id for the timer event, which drains the health.

Remove a heart when the event occurs in the event loop:

running = True
while running:

for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

elif event.type == timer_event:
del playerhealth[-1]

A timer event can be stopped by passing 0 to the time parameter (pygame.time.set_timer(timer_event, 0)).

How to make a bullet animation in pygame?

First of all remove pygame.display.flip() from player and fireball. That casuse flickering. A single pygame.display.update() at the end of the application loop is sufficient.

Note, the fireballs have to be blit at (x, y) rather than (fb_x, fb_y)

def player(x ,y):
screen.blit(playerImage, (x, y))

def fireball(x, y):
screen.blit(fireballImage, (x, y))
fireball_state = "ready"

Further more use pygame.time.Clock() / tick() to control the flops per second (FPS):

clock = pygame.time.Clock()

#mainloop
running = True
while running:
clock.tick(FPS)

Add a list for the fire balls:

fireballs = []

Spawn a new fireball when space is pressed:

if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fireballs.append([x, y, 0, -2])

Update and draw the fireballs in a loop:

for fb in fireballs:
fb[0] += fb[2]
fb[1] += fb[3]
for fb in fireballs:
fireball(fb[0],fb[1])

See the example:

fireballs = []

FPS = 60
clock = pygame.time.Clock()
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fireballs.append([x, y, 0, -2])

pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]:
y -= 2
if pressed[pygame.K_s]:
y += 2
if pressed[pygame.K_a]:
x -= 2
if pressed[pygame.K_d]:
x += 2

for i in range(len(fireballs)-1, -1, -1):
fb = fireballs[i]
fb[0] += fb[2]
fb[1] += fb[3]
if fb[1] < 0:
del fireballs[i]

screen.fill((255,255,255))
player(x,y)
for fb in fireballs:
fireball(fb[0],fb[1])
pygame.display.update()

Pygame new enemy every 10sec?

In pygame exists a timer event. Use pygame.time.set_timer() to repeatedly create a USEREVENT in the event queue. The time has to be set in milliseconds. e.g.:

timer_interval = 10000 # 10 seconds
timer_event = pygame.USEREVENT + 1
pygame.time.set_timer(timer_event, timer_interval)

Note, in pygame customer events can be defined. Each event needs a unique id. The ids for the user events have to be between pygame.USEREVENT (24) and pygame.NUMEVENTS (32). In this case pygame.USEREVENT+1 is the event id for the timer event.

Receive the event in the event loop:

run = True
while run:

for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False

elif event.type == timer_event:
# [...]

The timer event can be stopped by passing 0 to the time argument of pygame.time.set_timer.


Note, you have to use a list to manage the enemies. Add a new enemy position to a list when the event occurs. Iterate through the enemies in a loop. Move and draw the enemies in the loop:

timer_interval = 10000 # 10 seconds
timer_event = pygame.USEREVENT + 1
pygame.time.set_timer(timer_event, timer_interval)

enemy_list = []

run = True
while run:

for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

elif event.type == timer_event:
# [...]

enemy_list.append([enemyX, enemyY])

# [...]

for enemy_pos in enemy_list:
screen.blit(enemy, enemy_pos)

Is there a way to limit how many times a function can be called in PyGame?

A possibility is to limit the number of bullets. e.g:

if event.button == 1 and len(all_bullets) < 5:
dx = event.pos[0] - (player_sprite_x+ player_sprite_w//2)
dy = event.pos[1] - player_sprite_y
direction = pygame.math.Vector2(dx, dy).normalize()
bullet = {'x': player_sprite_x+42, 'y': player_sprite_y, 'direction': direction}
all_bullets.append(bullet)

An other option would be to ensure that a certain amount of time is passed between 2 clicks. Use pygame.time.get_ticks() to get the current time in milliseconds. When a new bullet has been spawned, then compute the time when the next bullet is allowed to be spawned.
Define the minimum time spawn between 2 bullets and init the time point for the 1st bullet by 0:

bullet_delay = 500 # 0.5 seconds
next_bullet_time = 0

Get the current time in the application loop:

current_time = pygame.time.get_ticks()

On click, verify of the current time is grater than next_bullet_time. If the condition is fulfilled, then spawn the bullet and compute the time point for the next bullet:

if event.button == 1 and current_time > next_bullet_time:
next_bullet_time = current_time + bullet_delay

e.g.:

bullet_delay = 500 # 0.5 seconds
next_bullet_time = 0

while exec:
current_time = pygame.time.get_ticks()

for event in pygame.event.get():
if event.type == pygame.QUIT:
exec = False

if event.type == pygame.MOUSEBUTTONDOWN:

if event.button == 1 and current_time > next_bullet_time:
next_bullet_time = current_time + bullet_delay

dx = event.pos[0] - (player_sprite_x+ player_sprite_w//2)
dy = event.pos[1] - player_sprite_y
direction = pygame.math.Vector2(dx, dy).normalize()
bullet = {'x': player_sprite_x+42, 'y': player_sprite_y, 'direction': direction}
all_bullets.append(bullet)


Related Topics



Leave a reply



Submit