I've been learning Python for a while and I'm following the Python Crash Course textbook, just in case you might be familiar with the exercises in that text.
The first project is a Space Invaders clone which has been running smoothly until now. When I'm drawing the aliens to the screen, I've got some code that checks the window dimensions and compares it with the dimensions of the aliens and the ship to calculate how many aliens should appear on each row and how many rows there can be. This is also, to my knowledge, working fine.
The error appears when I call my create_fleet function. Create fleet works with a couple of functions, one of which makes an instance of an alien and uses the add() function to add it to a group. Heres the code and the trace back.
def get_number_rows(settings, ship_height, alien_height):
available_space_y = (settings.screen_height - (3 * alien_height) - ship_height)
number_rows = int(available_space_y / (2 * alien_height))
return number_rows
def get_number_aliens_x(settings, alien_width):
available_space_x = settings.screen_width - (alien_width * 2)
number_aliens_x = int(available_space_x / (alien_width * 2))
return number_aliens_x
def create_alien(settings, screen, aliens, alien_number, row_number):
alien = Alien(settings, screen)
alien_width = alien.rect.width
alien.x = alien_width + 2 * alien_width * alien_number
alien.rect.x = alien.x
alien.rect.y = alien.rect.height + 2 * alien.rect.height + row_number
aliens.add(alien) <-- Error refrenced here
def create_fleet(settings, screen, ship, aliens):
alien = Alien(settings, screen)
number_aliens_x = get_number_aliens_x(settings, alien.rect.width)
number_rows = get_number_rows(settings, ship.rect.height, alien.rect.height)
for row_number in range(number_rows):
for alien_number in range(number_aliens_x):
alien = Alien(settings, screen)
create_alien(settings, screen, alien, alien_number, row_number) <-- In a loop
Traceback (most recent call last):
File "/Users/me/Desktop/Coding_Projects/Python_Space_Invaders/space_invaders.py", line 35, in <module>
run_game()
File "/Users/me/Desktop/Coding_Projects/Python_Space_Invaders/space_invaders.py", line 26, in run_game
gf.create_fleet(settings, screen, ship, aliens)
File "/Users/me/Desktop/Coding_Projects/Python_Space_Invaders/game_functions.py", line 90, in create_fleet
create_alien(settings, screen, alien, alien_number, row_number)
File "/Users/me/Desktop/Coding_Projects/Python_Space_Invaders/game_functions.py", line 81, in create_alien
aliens.add(alien)
File "/Users/me/Library/Python/3.7/lib/python/site-packages/pygame/sprite.py", line 142, in add
self.add(*group)
TypeError: add() argument after * must be an iterable, not Alien
Now, aliens is a group being declared in the file contain the main loop of the game (is declared the right word? There's a lot of terminology to remember)
import sys
#sys is used to exit the game when the player quits
import pygame
#pygame contains all the functionality to make a game
from pygame.sprite import Group
from settings import Settings
from ship import Ship
import game_functions as gf
from bullet import Bullet
from alien import Alien
def run_game():
pygame.init()
#Intialize pygame methods
pygame.display.set_caption("Space Invaders")
settings = Settings()
screen = pygame.display.set_mode(
(settings.screen_width, settings.screen_height))
#Creates a display window for the game
#The object screen is a surface. In pygame, a surface is a part of the -
#screen where a game element is displayed
ship = Ship(settings, screen)
bullets = Group()
aliens = Group() #<--------- Right there
#Background color
gf.create_fleet(settings, screen, ship, aliens)
while True:
#Main loop of the game
gf.check_events(settings, screen, ship, bullets)
gf.update_events(settings, screen, ship)
ship.update()
bullets.update()
gf.update_bullets(bullets)
gf.update_screen(settings, screen, ship, bullets, aliens)
run_game()
For the life of me, I can't figure what the issue is with adding a couple instances of my class Alien to my group aliens. The traceback says it needs to be iterable, but it is iterating in the double-for loop back in create_fleet(). So I have no clue.
You probably don't need all of this code to solve my problem, but I figured too much information is better then not enough. Oh, and heres the class Alien() just in case you need that too.
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
def __init__(self, settings, screen):
super(Alien, self).__init__()
self.settings = settings
self.screen = screen
self.image = pygame.image.load('Desktop/Coding_Projects/Python_Space_Invaders/alien.bmp')
self.rect = self.image.get_rect()
self.rect.x = self.rect.width
self.rect.y = self.rect.height
self.x = float(self.rect.x)
def blitme(self):
self.screen.blit(self.image, self.rect)
Thank you to anyone who took the time to even glance at this issue, I'm sure it's probably obvious to an experienced programmer.