rishi
rishi

Reputation: 640

Trying to delay a specific function for spawning enemy after a certain amount of time

I am making a mole shooter game using pygame. I want my mole to spawn at a random position after every 1 second. I have tried using time.sleep(1.0) but that delays my whole code and thus the game doesn't function properly because of delayed responses. I am moving an aim using the mouse(which also gets affected because of time.sleep) to which i will be adding a click to shoot. I need help with delaying and spawning my mole. I would also like some opinions on how to organize my code to provide various levels of difficulty and a main menu later on.

import pygame
import random
import time
from threading import Timer

pygame.font.init()



win_width = 1000
win_height = 710

FPS = 60


screen = pygame.display.set_mode((win_width, win_height))

pygame.display.set_caption("Mole Shooter")



white = (255,255,255)
red = (255, 0, 0)



counter, text = 30, 'Time Left: 30'.rjust(3)
pygame.time.set_timer(pygame.USEREVENT, 1000)

font = pygame.font.Font('freesansbold.ttf', 32)



run = True
clock = pygame.time.Clock()
background = pygame.transform.scale(pygame.image.load('back_land.png'), (win_width, win_height))

aim = pygame.image.load("aim.png")
mole = pygame.image.load("mole.png")


def mole_spawn_easy():

    molex = random.randint(50, 950)
    moley = random.randint(450, 682)

    screen.blit(mole, (molex, moley))


while run:
    screen.blit(background, [0,0])
    ax, ay = pygame.mouse.get_pos()

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

        if event.type == pygame.USEREVENT:
            counter -= 1
            text = ("Time Left: " + str(counter)).rjust(3)
            if counter > 0:
                time.sleep(1.0);mole_spawn_easy()

            else:
                print("game over")
                break



    screen.blit(aim, ((ax - 32 ),(ay - 32)))



    screen.blit(font.render(text, True, (0, 0, 0)), (32, 48))

    clock.tick(FPS)

    pygame.display.flip()

Upvotes: 3

Views: 815

Answers (1)

Rabbid76
Rabbid76

Reputation: 210890

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:

pygame.time.set_timer(pygame.USEREVENT, 1000) # 1 second

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 the value of pygame.USEREVENT is the event id for the timer event.

Receive the event in the event loop:

running = True
while run:

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

         elif event.type == pygame.USEREVENT:
             # [...]

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

See also Spawning multiple instances of the same object concurrently in python.


Create a list of moles and add a random position to the list in mole_spawn_easy:

moles = []

def mole_spawn_easy():
    molex = random.randint(50, 950)
    moley = random.randint(450, 682)
    moles.append((molex, moley))

Draw the moles in the main application loop:

while run:
    # [...]

    for pos in moles:
        screen.blit(mole, pos)

See the example:

moles = []

def mole_spawn_easy():
    molex = random.randint(50, 950)
    moley = random.randint(450, 682)
    moles.append((molex, moley))

pygame.time.set_timer(pygame.USEREVENT, 1000)

while run:
    
    ax, ay = pygame.mouse.get_pos()
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

        if event.type == pygame.USEREVENT:
            counter -= 1
            text = ("Time Left: " + str(counter)).rjust(3)
            if counter > 0:
                mole_spawn_easy()
            else:
                print("game over")

    screen.blit(background, [0,0])
    
    for pos in moles:
        screen.blit(mole, pos)
    screen.blit(aim, ((ax - 32 ),(ay - 32)))
    screen.blit(font.render(text, True, (0, 0, 0)), (32, 48))
    
    pygame.display.flip()
    clock.tick(FPS)

Upvotes: 4

Related Questions