1

I have the following code. I want to create a game, something like Space Invaders where you control a ship and should destroy all enemy ships. If enemy ships will come close to you, you will lose. I couldn't figure it up how can I create more objects using a for loop, at different x and y axis coordinates (like x_axis and y_axis lists) and make these enemy ships I've created to move from left to right and when these reaches the width of the screen, it should go down a certain amount of pixels and then move left again and so on.

Any help will be great. Thank you!

import pygame
from enemies import EnemyShips

pygame.mixer.init()

WIDTH, HEIGHT = 800, 600
SPACESHIP_WIDTH, SPACESHIP_HEIGHT = 55, 40
ENEMY_SPACESHIP_WIDTH, ENEMY_SPACESHIP_HEIGHT = 70, 50

FPS = 60
VEL = 3
BULLET_VEL = 5
MAX_BULLETS = 1

YELLOW = (255, 255, 0)
BACKGROUND_IMAGE = pygame.transform.scale(pygame.image.load("Assets/space.png"), (WIDTH, HEIGHT))

CHARACTER_IMAGE = pygame.image.load("Assets/spaceship_yellow.png")
CHARACTER = pygame.transform.rotate(pygame.transform.scale(CHARACTER_IMAGE, (SPACESHIP_WIDTH, SPACESHIP_HEIGHT)), 180)

ENEMY_IMAGE = pygame.image.load("Assets/enemy.png")
ENEMY_SPACESHIP = pygame.transform.scale(ENEMY_IMAGE, (ENEMY_SPACESHIP_WIDTH, ENEMY_SPACESHIP_HEIGHT))

ENEMY_HIT = pygame.USEREVENT + 1

BULLET_HIT_SOUND = pygame.mixer.Sound("Assets/hit.mp3")
BULLET_FIRE_SOUND = pygame.mixer.Sound("Assets/shoot.mp3")

window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Space Invaders")


def draw_window(player_ship, enemy_ship, bullets):
    window.blit(BACKGROUND_IMAGE, (0, 0))
    window.blit(CHARACTER, (player_ship.x, player_ship.y))

    for bullet in bullets:
        pygame.draw.rect(window, YELLOW, bullet)

    pygame.display.update()


def ship_movement(keys_pressed, player_ship):
    if keys_pressed[pygame.K_w] and player_ship.y > 0:
        player_ship.y -= VEL
    if keys_pressed[pygame.K_s] and player_ship.y - player_ship.height + VEL + 80 < HEIGHT:
        player_ship.y += VEL
    if keys_pressed[pygame.K_a] and player_ship.x > 0:
        player_ship.x -= VEL
    if keys_pressed[pygame.K_d] and player_ship.x + player_ship.width + VEL < WIDTH:
        player_ship.x += VEL


def handle_bullets(bullets, enemy_ship):
    for bullet in bullets:
        bullet.y -= BULLET_VEL
        if enemy_ship.colliderect(bullet):
            pygame.event.post(pygame.event.Event(ENEMY_HIT))
            bullets.remove(bullet)
        if bullet.y < 0:
            bullets.remove(bullet)


x_axis = [50, 100, 150, 200, 250]
y_axis = [50, 100, 200]


def main():
    player_ship = pygame.Rect(370, 530, SPACESHIP_WIDTH, SPACESHIP_HEIGHT)

    enemy_ships_group = pygame.sprite.Group()
    for ship_x in range(len(x_axis)):
        for ship_y in range(len(y_axis)):
            enemy_ship = EnemyShips(x_axis, y_axis, ENEMY_SPACESHIP_WIDTH, ENEMY_SPACESHIP_HEIGHT, "Assets/enemy.png")
            # window.blit(, (enemy_ship.x[ship_x], enemy_ship.y[ship_y]))
            enemy_ships_group.add(enemy_ship)

    bullets = []

    clock = pygame.time.Clock()

    game_on = True
    while game_on:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_on = False

            if event.type == pygame.KEYDOWN and len(bullets) < MAX_BULLETS:
                if event.key == pygame.K_SPACE:
                    bullet = pygame.Rect(player_ship.x + player_ship.width / 2 - 2.5, player_ship.y, 5, 10)
                    bullets.append(bullet)
                    BULLET_FIRE_SOUND.play()

            if event.type == ENEMY_HIT:
                BULLET_HIT_SOUND.play()

        keys_pressed = pygame.key.get_pressed()
        ship_movement(keys_pressed, player_ship)

        handle_bullets(bullets, enemy_ships_group)
        enemy_ships_group.draw(window)

        draw_window(player_ship, enemy_ships_group, bullets)


if __name__ == "__main__":
    main()

The Class:

import pygame


class EnemyShips(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height, img_path):
        super().__init__()
        self.img = pygame.image.load(img_path)
        self.rect = self.img.get_rect()
        self.x = x
        self.y = y
        self.width = width
        self.height = height
Marker
  • 13
  • 4
  • You need to define an *update()* function for your *EnemyShips* class to change the position of the sprite, similar to your *handle_bullets* function. Then, every game loop, you can call *enemy_ships_group.update()* which will call the update function for all sprites in the group ([doc](https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Group.update)). You could also change your bullets to sprites to take advantage of the built-in functions. – import random Sep 07 '21 at 15:25

0 Answers0