George
George

Reputation: 19

How do I draw a list of class objects in pygame?

I am trying to create Space Invaders in pygame (I am a beginner and this is only my second game) and I have created a list of alien objects:

numOfAliens = 24
aliens = []

# An alien class containing an x, y, width, and height value
class alien:
    x, y = 0, 0
    width, height = 20, 20

# Loops 24 times and adds alien to the class
for i in range(numOfAliens):
    aliens.append(alien)

I have another bit of code that adds 5 and the width to each x value to space the aliens apart:

for i in aliens:
    i.x += 5 + i.width
    print(i.x, i.y, i.width, i.height)

The print tells me that these first 2 blocks of code work fine without any issues, the problem occurs when I try to draw it to the pygame window:

# Loops 24 times, drawing each alien to the window
for i in range(numOfAliens):
        pygame.draw.rect(win, GREEN, (aliens[i].x, aliens[i].y, aliens[i].width, aliens[i].height))

Surely aliens[i].x will get the x value of each object in the list, but it doesn't. If I add a print("hi") in this for loop it infinitely prints out "hi" when it should only loop 24 times, and nothing gets drawn on the window, is there any way to fix this?

Here is all the code if needed:

import pygame
pygame.init()

clock = pygame.time.Clock()

# Window
win_width, win_height = 500, 500

win = pygame.display.set_mode((win_width, win_height))
pygame.display.set_caption("Space Invaders")


# Colours
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (30, 224, 27)


# Player
player_width, player_height = 20, 20
player_x, player_y = int((win_width / 2) - (player_width / 2)), (win_height - 50)
player_vel = 10
isShooting = False
isAlive = True


# Bullet
bullet_width, bullet_height = 4, 16
bullet_x, bullet_y = player_x, player_y
bullet_vel = 5


# Aliens
numOfAliens = 24
aliens = []

class alien:
    x, y = 0, 0
    width, height = player_width, player_height

for i in range(numOfAliens):
    aliens.append(alien)

for i in aliens:
    i.x += 5 + i.width
    print(i.x, i.y, i.width, i.height)

# Draw Function
def draw():
    win.fill(BLACK)
    pygame.draw.rect(win, GREEN, (player_x, player_y, player_width, player_height))

    for i in aliens:
        pygame.draw.rect(win, GREEN, (i.x, i.y, i.width, i.height))

    if isShooting:
        pygame.draw.rect(win, WHITE, (bullet_x, bullet_y, bullet_width, bullet_height))

    pygame.display.update()

# Game Loop
run = True
while run:
    clock.tick(20)

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

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_vel

    if keys[pygame.K_RIGHT] and player_x < win_width - player_width:
        player_x += player_vel

    if keys[pygame.K_SPACE] and not(isShooting):
        bullet_y = player_y
        bullet_x = int(player_x + (player_width / 2))
        isShooting = True

    if bullet_y + bullet_height <= 0:
        isShooting = False

    if isShooting:
        bullet_y -= bullet_vel

    draw()

pygame.quit()

Upvotes: 1

Views: 2658

Answers (1)

Rabbid76
Rabbid76

Reputation: 210968

Actually you do not create any instance of alien. alien is just the class itself.

aliens.append(alien)

To create an instance of the class alien you have to add parentheses:
See Class Objects

aliens.append(alien())

Please note, that class names in python should start with capital letters.
See Style Guide for Python Code - Class Names

Add a constructor with a parameter for the x and y coordinate to the class Alien and create instance attributes for the position and size. Calculate the position of the alien dependent on the control variable i:

numOfAliens = 24
aliens = []

class Alien:
    def __init__(self, x, y):
        self.x, self.y = x, y
        self.width, self.height = player_width, player_height

for i in range(numOfAliens):
    aliens.append(Alien(i * (5+player_width), 0))

Upvotes: 1

Related Questions