3

Thank you in advance for your time.

If I fire a bullet with space key, a stream of bullets are created. If I would set a delay with time.sleep() inside 'if keys[pygame.K_SPACE]:' it would also freeze the loop for the set amount of seconds. How could I make it so only 1 bullet fires at a time? This is the copy of my game loop, please tell me if more of the code is needed:

def game_loop():
    global pause
    x = (display_width * 0.2)
    y = (display_height * 0.2)

    x_change = 0
    y_change = 0

    blob_speed = 3

    velocity = [2, 2]

    pos_x = display_width/1.2
    pos_y = display_height/1.2

    gameExit = False
    while not gameExit:
        for event in pygame.event.get():#monitors hardware movement/ clicks
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        pos_x += velocity[0]
        pos_y += velocity[1]

        if pos_x + blob_width > display_width or pos_x < 601:
            velocity[0] = -velocity[0]

        if pos_y + blob_height > display_height or pos_y < 0:
            velocity[1] = -velocity[1]

# Checks to see if any keys are held down and remembers them with the variable keys.
        keys = pygame.key.get_pressed()

        for b in range(len(bullets)):
            bullets[b][0] += 6

        for bullet in bullets:
            if bullet[0] > 1005:
                bullets.remove(bullet)

        if keys[pygame.K_SPACE]:
            bullets.append([x+25, y+24])

# If the player is holding down one key or the other the blob moves in that direction
        if x < 0:
            x = 0
        if keys[pygame.K_a]:
            x_change = -blob_speed
        if x > 401 - blob_width:
            x = 401 - blob_width
        if keys[pygame.K_d]:
            x_change = blob_speed
        if keys[pygame.K_p]:
            pause = True
            paused()


# If the player is holding down both or neither of the keys the blob stops
        if keys[pygame.K_a] and keys[pygame.K_d]:
            x_change = 0
        if not keys[pygame.K_a] and not keys[pygame.K_d]:
            x_change = 0

        if y < 0:
            y = 0
        if keys[pygame.K_w]:
            y_change = -blob_speed
        if y > display_height - blob_height:
            y = display_height - blob_height
        if keys[pygame.K_s]:
            y_change = blob_speed


        if keys[pygame.K_w] and keys[pygame.K_s]:
            y_change = 0
        if not keys[pygame.K_w] and not keys[pygame.K_s]:
            y_change = 0


        #print(event)
        # Reset x and y to new position
        x += x_change
        y += y_change

        gameDisplay.fill(blue)  #changes background surface
        pygame.draw.line(gameDisplay, black, (601, display_height), (601, 0), 3)
        pygame.draw.line(gameDisplay, black, (401, display_height), (401, 0), 3)
        blob(pos_x, pos_y)
        blob(x, y)

        for bullet in bullets:
            gameDisplay.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0))

        pygame.display.update() #update screen
        clock.tick(120)#moves frame on (fps in parameters)
Rokas98765
  • 119
  • 1
  • 9
  • Possible duplicate of [pygame: player fire delay](https://stackoverflow.com/questions/24042420/pygame-player-fire-delay) – skrx Jan 20 '18 at 13:30
  • That answer actually looks like it won't work (needs to be changed a little bit). Better take a look at [my answer here](https://stackoverflow.com/a/45791683/6220679). – skrx Jan 20 '18 at 13:34
  • Thank you for the reply, is there any way to do it without using classes? Would have to edit a considerable amount of code as well as having to learn how to use classes (which I will do in the future but am currently under a time limit to complete this). – Rokas98765 Jan 20 '18 at 13:42
  • 1
    Sure, the point is that you just need some kind of [timer](https://stackoverflow.com/questions/30720665/countdown-timer-in-pygame), check if the time is up (we're ready to fire) and then create a new bullet and append it to your list. – skrx Jan 20 '18 at 13:47

1 Answers1

6

Here's an answer without classes. You just have to store the previous time when a bullet was fired, subtract it from the current time and check if it's above some time limit (500 ms in this example) to see if we're ready to fire.

import pygame


def game_loop():
    pygame.init()
    gameDisplay = pygame.display.set_mode((640, 480))
    clock = pygame.time.Clock()
    bulletpicture = pygame.Surface((10, 5))
    bulletpicture.fill(pygame.Color('sienna1'))
    bullets = []
    x = 50
    y = 240
    previous_time = pygame.time.get_ticks()

    gameExit = False
    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True

        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE]:
            current_time = pygame.time.get_ticks()
            # We're ready to fire when 500 ms have passed.
            if current_time - previous_time > 500:
                previous_time = current_time
                bullets.append([x+25, y+24])

        remaining_bullets = []
        for bullet in bullets:
            bullet[0] += 6  # Move the bullet.
            if bullet[0] < 500:  # Filter out the bullets.
                remaining_bullets.append(bullet)
        bullets = remaining_bullets

        gameDisplay.fill((30, 30, 30))

        for bullet in bullets:
            gameDisplay.blit(bulletpicture, pygame.Rect(bullet[0], bullet[1], 0, 0))

        pygame.display.update()
        clock.tick(120)

game_loop()
pygame.quit()
skrx
  • 19,980
  • 5
  • 34
  • 48