2

I've been attempting to make a Space Invaders clone in pygame. I decided to write it so that the bullet shot from the player's ship can only be fired again when it leaves the screen but I've not been capable of doing so. How do I do it?

import pygame

pygame.init()

screen_size = (500, 500)
ship_size = (50, 50)
x, y = 250, 450
x_rect, y_rect = x + 15, y - 20
height_rect, width_rect = 20, 20
vel = 50
shoot = False

"""Loads screen and set gives it a title."""
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("Space Invaders")

"""Initializes images for the game and resizes them."""
space_ship = pygame.image.load("Space Invaders Ship.jpg")
space_ship = pygame.transform.scale(space_ship, ship_size)
space = pygame.image.load("Space.jpg")
space = pygame.transform.scale(space, screen_size)

clock = pygame.time.Clock()

run = True
while run:
    """Controls the fps."""
    clock.tick(60)

    """Registers keyboard's input."""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT and x > 0:
                x -= vel
            elif event.key == pygame.K_RIGHT and x + 50 < 500:
                x += vel
            elif event.key == pygame.K_SPACE:
                x_rect, y_rect = x + 15, y - 20
                shoot = True

    """Constantly draws on the screen."""
    screen.fill((0, 0, 0))
    screen.blit(space, (0, 0))
    screen.blit(space_ship, [x, y])

    """Shoots a bullet from where the ship currently is."""
    if shoot:
        pygame.draw.rect(screen, (250, 250, 0),
                        [x_rect, y_rect, height_rect, width_rect])
        y_rect -= 5
    elif y_rect + width_rect > 0:
        shoot = False
        y_rect = y - 20

    pygame.display.flip()
  • Should `elif y_rect + width_rect > 0:` be `elif y_rect + width_rect < 0:` as the y_rect value is decreasing by 5 while `shoot` is `True`? – Anton Jan 17 '21 at 11:22
  • Please search for similar questions before asking a question. Don't ask almost identical questions over and over again. I am very sure that this question has been asked more than 10 times. – Rabbid76 Jan 17 '21 at 11:26

1 Answers1

1

You have to create a list of bullets:

bullet_list = []

Add a new bullet position to the list when SPACE is pressed:

elif event.key == pygame.K_SPACE:
    bullet_list.append([x + 15, y - 20])

Move and draw the bullets in the list in a loop:

for bullet in bullet_list:
    pygame.draw.rect(screen, (250, 250, 0),
                        [*bullet, height_rect, width_rect])
    bullet[1] -= 5

Delete a bullet from the list if the y-coordinate is less than 0:

for bullet in bullet_list[:]:
    if bullet[1] < 0:
        bullet_list.remove(bullet)

Complete example:

import pygame

pygame.init()

screen_size = (500, 500)
ship_size = (50, 50)
x, y = 250, 450
x_rect, y_rect = x + 15, y - 20
height_rect, width_rect = 20, 20
vel = 50
bullet_list = []

"""Loads screen and set gives it a title."""
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("Space Invaders")

"""Initializes images for the game and resizes them."""
space_ship = pygame.image.load("Space Invaders Ship.jpg")
space_ship = pygame.transform.scale(space_ship, ship_size)
space = pygame.image.load("Space.jpg")
space = pygame.transform.scale(space, screen_size)

clock = pygame.time.Clock()
run = True
while run:
    """Controls the fps."""
    clock.tick(60)

    """Registers keyboard's input."""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT and x > 0:
                x -= vel
            elif event.key == pygame.K_RIGHT and x + 50 < 500:
                x += vel
            elif event.key == pygame.K_SPACE:
                bullet_list.append([x + 15, y - 20])

    """Constantly draws on the screen."""
    screen.fill((0, 0, 0))
    screen.blit(space, (0, 0))
    screen.blit(space_ship, [x, y])

    """Shoots a bullet from where the ship currently is."""
    for bullet in bullet_list:
        pygame.draw.rect(screen, (250, 250, 0),
                        [*bullet, height_rect, width_rect])
        bullet[1] -= 5

    for bullet in bullet_list[:]:
        if bullet[1] < 0:
            bullet_list.remove(bullet)
    
    pygame.display.flip()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174