AttributeError 'pygame.Surface' object has no attribute 'rect' - python

Here is a game from the book "Python Crash Course (author: Eric Matthes)"
I do exactly what the book told. But I found these problems, and why?
File "D:\pythoncode\l_one\venv\lib\site-packages\pygame\sprite.py", line 1586, in spritecollideany
spritecollide = sprite.rect.colliderect
AttributeError: 'pygame.Surface' object has no attribute 'rect'
Here are my codes: https://github.com/yushu-liu/Learn_Python/tree/master/Alien_Invasion
And part of my codes as follows(aline_invasion.py):
import sys
from settings import Settings
from ship import Ship
from pygame.sprite import Group
import game_functions as gf
from alien import Alien
from game_stats import GameStats
import pygame
def run_game():
# Initialize game and create a screen object.
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
# Set the background Color
bg_color = (230,230,230)
# Make a ship, a group of bullets, and a group of aliens.
ship = Ship(ai_settings, screen)
bullets = Group()
aliens = Group()
# Create the fleet of aliens
gf.create_fleet(ai_settings,screen,ship,aliens)
# Create an instance to store game statistics.
stats = GameStats(ai_settings)
# Start the main loop for the game
while True:
# Watch for keyboard and mouse events
gf.check_events(ai_settings,screen,ship,bullets)
if stats.game_active:
ship.update()
# Make the most recently drawn screen visible
gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
gf.update_aliens(ai_settings,stats,ship,screen,aliens,bullets)
gf.update_screen(ai_settings,screen,ship,aliens,bullets)
run_game()
And another part of my codes as follows(game_function.py):
import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleep
def check_keydown_events(event,ai_settings,screen,ship,bullets):
'''Respond to keypresses'''
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings,screen,ship,bullets)
elif event.key == pygame.K_q:
sys.exit()
def check_keyup_events(event,ship):
'''Respond to key releases.'''
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(ai_settings, screen, ship, bullets):
'''Respond to keypresses and mouse events'''
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ai_settings,screen,ship,bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
def fire_bullet(ai_settings,screen,ship,bullets):
'''Fire a bullet if limit not reached yet.'''
# Create a new bullet and add it to the bullets group
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings,screen,ship)
bullets.add(new_bullet)
def update_screen(ai_settings,screen,ship,aliens, bullets):
'''Update images screen during each pass through the loop'''
# Redraw the screen during each pass through the loop
screen.fill(ai_settings.bg_color)
# Redraw all bullets behind ship and aliens.
for bullet in bullets.sprites():
bullet.draw_bullet()
# Redraw the ship and the alien
ship.blitme()
# When calling draw, Pygame automatically draws each element in the group
# at the position defined by its rect
aliens.draw(screen)
# Make the most recently drawn screen visible
pygame.display.flip()
def update_bullets(ai_settings, screen, ship, aliens,bullets):
'''Update position of bullets and get rid of old bullets.'''
# Update the latest positions of bullets
bullets.update()
# Get rid of bullets that have disappeared.
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)
def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):
'''Respond to bullet-alien collisions.'''
# Remove any bullets and aliens that have collided
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
if len(aliens) == 0:
# If the entire fleet is destroyed, start a new level
bullets.empty()
create_fleet(ai_settings, screen, ship, aliens)
def get_number_aliens_x(ai_settings,alien_width):
'''Determine the number of aliens that fit in a row.'''
availabe_space_x = ai_settings.screen_width - 2 * alien_width
number_aliens_x = int(availabe_space_x/(2 * alien_width))
return number_aliens_x
def get_number_rows(ai_settings, ship_height, alien_height):
'''Determine the number of rows of aliens that fit on the screen,'''
available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)
number_rows = int(available_space_y / (2 * alien_height))
return number_rows
def create_alien(ai_settings,screen,aliens,alien_number,row_number):
'''Create an alien an place it in the row'''
alien = Alien(ai_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)
def create_fleet(ai_settings, screen, ship, aliens):
'''Create a full fleet of aliens.'''
# Create an alien and find the number of aliens in a row.
alien = Alien(ai_settings, screen)
number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
number_rows = get_number_rows(ai_settings, ship.rect.height, alien.rect.height)
# Create the fleet of aliens
for row_number in range(number_rows):
for alien_number in range(number_aliens_x):
create_alien(ai_settings, screen, aliens, alien_number,row_number)
def check_fleet_edges(ai_settings, aliens):
'''Respond appropirately if any aliens have reached and edge'''
for alien in aliens.sprites():
if alien.check_edges():
change_fleet_direction(ai_settings, aliens)
break
def change_fleet_direction(ai_settings,aliens):
'''Drop the entire fleet and change the fleet's direction.'''
for alien in aliens.sprites():
alien.rect.y += ai_settings.fleet_drop_speed
ai_settings.fleet_direction *= -1
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
'''Respond to ship being hit by alien.'''
if stats.ships_left > 0:
# Decrement ship_left
stats.ships_left -= 1
# Update scoreboard.
aliens.empty()
bullets.empty()
# Create a new fleet and center the ship.
create_fleet(ai_settings, screen, ship, aliens)
ship.center_ship()
# Pause
sleep(0.5)
else:
stats.game_active = False
pygame.mouse.set_visible(True)
def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):
'''Check if any aliens have reached the bottom of the screen'''
screen_rect = screen.get_rect()
for alien in aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
# Treat this the same as if the ship get hit
ship_hit(ai_settings,stats,screen,ship,aliens,bullets)
break
def update_aliens(ai_settings,stats,screen,ship,aliens,bullets):
'''
Check if the fleet is at an edge, and then update the positions of all
aliens in the fleet.
'''
check_fleet_edges(ai_settings,aliens)
aliens.update()
# Look for alien-ship collisions.
# Look for aliens hitting the bottom of the screen.
if pygame.sprite.spritecollideany(ship,aliens):
ship_hit(ai_settings,stats, screen, ship,aliens, bullets)
# Look for aliens hitting the bottom of the screen.
check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)
alien.py as follow:
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
'''A class to represent a single alien in the fleet'''
def __init__(self,ai_settings,screen):
'''Initialize the alien an set its starting position.'''
super(Alien,self).__init__()
self.screen = screen
self.ai_settings = ai_settings
# Load the alien image an sets its rect attribute.
self.image = pygame.image.load('images/alien.bmp')
self.rect = self.image.get_rect()
# Start each new alien near the top left of the screen.
self.rect.x = self.rect.width
self.rect.y = self.rect.height
# Store the alien's exact position.
self.x = float(self.rect.x)
def blitme(self):
'''Draw the alien at its current location.'''
self.screen.blit(self.image,self.rect)
def check_edges(self):
'''Return True if alien is at edge of screen.'''
screen_rect = self.screen.get_rect() # 注意get_rect
if self.rect.right >= screen_rect.right:
return True
elif self.rect.left <= 0:
return True
def update(self):
'''Move the alien right.'''
self.x += (self.ai_settings.alien_speed_factor * self.ai_settings.fleet_direction)
self.rect.x = self.x
ship.py as fllow:
import pygame
class Ship():
def __init__(self,ai_settings,screen):
'''Initialize the ship and set its starting position'''
self.screen = screen
self.ai_settings = ai_settings
# Load the ship image and get its rect.
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# Start each new ship at the bottom center of the screen.
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# Store a decimal value for the ship's center.
self.center = float(self.rect.centerx)
# Movement flags
self.moving_right = False
self.moving_left = False
def center_ship(self):
'''Make sure the ship in the center of screen.'''
self.center = self.screen_rect.centerx
def update(self):
'''Update the ship's position based on the movement flags.'''
# Update the ship's center value,not the rect
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor
# Update rect object from self.center.
self.rect.centerx = self.center
def blitme(self):
'''Draw the ship at its current location.'''
self.screen.blit(self.image,self.rect)
game_stats.py as follow:
class GameStats():
'''Track statistics for Alien Invasion'''
def __init__(self,ai_settings):
'''Start Alien Invasion in an active state'''
self.ai_settings = ai_settings
self.reset_stats()
# Start Alien Invasion in an active state
self.game_active = True
def reset_stats(self):
'''Initialize statistics than can change during the game'''
self.ships_left = self.ai_settings.ship_limit

You have two issues.
Your first one is located at line #42 of your aline_invasion.py file:
gf.update_aliens(ai_settings,stats,ship,screen,aliens,bullets)
should be:
gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
If you look at the method declaration for update_aliens in the game_functions.py file you can see that your order was incorrect, which is important. You want to pass things into a method in the order they belong.
Your second issue is located at line #171 of game_functions.py
if pygame.sprite.spritecollideany(aliens, ship):
should be:
if pygame.sprite.spritecollideany(ship, aliens):
Per this post, and this documentation the method you are calling accepts a sprite first, then a group. You were passing the group in first, and then the sprite. Again, the order is important.

Related

Python Crash Couse - Alien Invasion - ship not moving properly

I'm working through the book, following it step by step. The screen comes up, the ship .bmp shows up where it's supposed to. The problem is it doesn't move left or right, most of the time. When it does move, it only moves right, never left. It flies to the bottom right corner and just stays there. Not sure what is wrong with the code. Thanks in advance.
alien_invasion.py
import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
#Initialize game and create a screeen object.
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((
ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
# Make a ship.
ship = Ship(ai_settings, screen)
#Start the main loop for the game.
while True:
gf.check_events(ship)
ship.update()
gf.update_screen(ai_settings, screen, ship)
#Redraw the screen during each pass through the loop.
screen.fill(ai_settings.bg_color)
ship.blitme()
# Watch for keyboard and mouse events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Make the most recently drawn screen visible.
pygame.display.flip()
run_game()
settings.py
class Settings():
"""A class to store all the settings for Alien Invasion."""
def __init__(self):
"""Initialize the game's settings."""
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (0,0, 90)
self.ship_speed_factor = 1.5
ship.py
import pygame
class Ship():
def __init__(self, ai_settings, screen):
"""Initialize the ship and set its starting position."""
self.screen = screen
# Load the ship image and get its rect.
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
self.ai_settings = ai_settings
# Start each new ship at the bottom center of the screen.
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# Store a decimal value for the ship's center.
self.center = float(self.rect.centerx)
# Movement flag
self.moving_right = False
self.moving_left = False
def update(self):
"""Update the ship's position based on movement flags."""
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left < 0:
self.center -= self.ai_settings.ship_speed_factor
# Update rect object from self.center.
self.rect.centerx = self.center
def blitme(self):
"""Draw the ship at its current location."""
self.screen.blit(self.image, self.rect)
game_functions.py
import sys
import pygame
def check_keydown_events(event, ship):
"""Respond to keypresses."""
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
def check_keyup_events(event, ship):
"""Respond to key releases."""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(ship):
"""Respond to keypresses and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ship)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)
def update_screen(ai_settings, screen, ship):
"""Update images on the screen and flip to the new screen."""
# Redraw the screen during each pass through the loop.
screen.fill(ai_settings.bg_color)
ship.blitme()
# Make the most recently drawn screen visible.
pygame.display.flip()
What I have found:
IndentationError: expected an indented block in (settings.py).
Wrong one (before):
class Settings():
"""A class to store all the settings for Alien Invasion."""
def __init__(self):
"""Initialize the game's settings."""
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (0,0, 90)
self.ship_speed_factor = 1.5
the right one (after)
class Settings():
#"""A class to store all the settings for Alien Invasion."""
def __init__(self):
# """Initialize the game's settings."""
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (0,0, 90)
self.ship_speed_factor = 1.5
In the update method of ship class, you wrote:
if self.moving_left and self.rect.left < 0:
self.center -= self.ai_settings.ship_speed_factor
It should be:
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor

pygame.Surface object has no attribute 'prep_ships'

Been trying to figure out what's wrong but I can't seem to find the answer.
Here is the game_functions where the error is located:
import sys
from time import sleep
import pygame
from bullet import Bullet
from alien import Alien
def check_keydown_events(event, ai_settings, screen, ship, bullets):
"""Respond to keypresses."""
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings, screen, ship, bullets)
elif event.key == pygame.K_q:
sys.exit()
def fire_bullet(ai_settings, screen, ship, bullets):
"""Fire a bullet if limit not reached yet."""
# Create a new bullet and add it to the bullets group.
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
def check_keyup_events(event, ai_settings, ship):
"""Respond to key releases."""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(ai_settings, screen, stats, sb, play_button, ship,
aliens, bullets):
"""Respond to keypresses and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ai_settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ai_settings, ship)
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
check_play_button(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y)
def check_play_button(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y):
"""Start a new game when the player clicks Play."""
button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
if button_clicked and not stats.game_active:
# Reset the game settings.
ai_settings.initialize_dynamic_settings()
# Hide the mouse cursor.
pygame.mouse.set_visible(False)
# Reset the game statistics.
stats.reset_stats()
stats.game_active = True
# Reset the scoreboard images.
sb.prep_score()
sb.prep_high_score()
sb.prep_level()
sb.prep_ships()
# Empty the list of aliens and bullets.
aliens.empty()
bullets.empty()
# Create a new fleet and center the ship.
create_fleet(ai_settings, screen, ship, aliens)
ship.center_ship()
def update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button):
"""Update images on the screenand flip to the new screen."""
# Redraw the screen during each pass through the loop.
screen.fill(ai_settings.bg_color)
# Redraw all bullets behind ship and aliens.
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
aliens.draw(screen)
# Draw the score information.
sb.show_score()
# Draw the play button if the game is inactive.
if not stats.game_active:
play_button.draw_button()
# Make the most recently drawn screen visible.
pygame.display.flip()
def update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets):
"""Update position of bullets and get rid of old bullets."""
# Update bullet positions.
bullets.update()
# Get rid of bullets that have dissapeared.
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship, aliens, bullets)
def check_bullet_alien_collisions(ai_settings, screen,stats, sb, ship, aliens, bullets):
"""Respond to bullet-alien collisions."""
# Remove any bullets and aliens that have collided
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
if collisions:
for aliens in collisions.values():
stats.score += ai_settings.alien_points * len(aliens)
sb.prep_score()
check_high_score(stats, sb)
if len(aliens) == 0:
# If the entire fleet is destroyed, start a new level.
bullets.empty()
ai_settings.increase_speed()
# Increase level.
stats.level += 1
sb.prep_level()
create_fleet(ai_settings, screen, ship, aliens)
def get_number_aliens_x(ai_settings, alien_width):
"""Determine the number of aliens that fit in a row."""
available_space_x = ai_settings.screen_width - 2 * alien_width
number_aliens_x = int(available_space_x / (2 * alien_width))
return number_aliens_x
def get_number_rows(ai_settings, ship_height, alien_height):
"""Determine the number of rows of aliens that fit on the screen."""
available_space_y = (ai_settings.screen_height -
(3 * alien_height) - ship_height)
number_rows = int(available_space_y / (2 * alien_height))
return number_rows
def create_alien(ai_settings, screen, aliens, alien_number, row_number):
"""Create an alien and place it in the row."""
alien = Alien(ai_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)
def create_fleet(ai_settings, screen, ship, aliens):
"""Create a full fleet of aliens."""
# Create an alien and find the number of aliens in a row.
alien = Alien(ai_settings, screen)
number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
number_rows = get_number_rows(ai_settings, ship.rect.height,
alien.rect.height)
# Create the fleet of aliens.
for row_number in range(number_rows):
for alien_number in range(number_aliens_x):
create_alien(ai_settings, screen, aliens, alien_number,
row_number)
def check_fleet_edges(ai_settings, aliens):
"""Respond appropriately if any aliens have reached an edge."""
for alien in aliens.sprites():
if alien.check_edges():
change_fleet_direction(ai_settings, aliens)
break
def change_fleet_direction(ai_settings, aliens):
"""Drop the entire fleet and change the fleet's direction."""
for alien in aliens.sprites():
alien.rect.y += ai_settings.fleet_drop_speed
ai_settings.fleet_direction *= -1
def update_aliens(ai_settings, stats, screen, sb, ship, aliens, bullets):
"""
Check if the fleet is at an edge,
and then update the positions of all aliens in the fleet.
"""
check_fleet_edges(ai_settings, aliens)
aliens.update()
# Look for alien-ship collisions.
if pygame.sprite.spritecollideany(ship, aliens):
ship_hit(ai_settings, stats, sb, screen, ship, aliens, bullets)
# Look for aliens hitting the bottom of the screen.
check_aliens_bottom(ai_settings, stats, screen, sb, ship, aliens, bullets)
def ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets):
"""Respond to the ship being hit by an alien."""
if stats.ships_left > 0:
# Decrement ships_left.
stats.ships_left -= 1
# Update scoreboard.
# HERE IS THE ERROR.
sb.prep_ships()
# Empty the list of aliens and bullets.
aliens.empty()
bullets.empty()
# Create a new fleet and center the ship.
create_fleet(ai_settings, screen, ship, aliens)
ship.center_ship()
# Pause.
sleep(0.5)
else:
stats.game_active = False
pygame.mouse.set_visible(True)
def check_aliens_bottom(ai_settings, stats, screen, sb, ship, aliens, bullets):
"""Check if any aliens have reached the bottom of the screen."""
screen_rect = screen.get_rect()
for alien in aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
# Treat the same as if the ship got hit.
ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets)
break
def check_high_score(stats, sb):
"""Check to see if there's a new high score."""
if stats.score > stats.high_score:
stats.high_score = stats.score
sb.prep_high_score()
Here is scoreboard.py:
class Scoreboard():
"""A class to report scoring information."""
def __init__(self, ai_settings, screen, stats):
"""Initialize scorekeeping attributes."""
self.screen = screen
self.screen_rect = screen.get_rect()
self.ai_settings = ai_settings
self.stats = stats
# Font settings for scoring information.
self.text_color = (30, 30, 30)
self.font = pygame.font.SysFont(None, 48)
# Prepare the initial score images.
self.prep_score()
self.prep_high_score()
self.prep_level()
self.prep_ships()
def prep_score(self):
"""Turn the score into a rendered image."""
rounded_score = int(round(self.stats.score, -1))
score_str = "{:,}".format(rounded_score)
score_str = str(self.stats.score)
self.score_image = self.font.render(score_str, True, self.text_color, self.ai_settings.bg_color)
# Display the score at the top right of the screen.
self.score_rect = self.score_image.get_rect()
self.score_rect.right = self.screen_rect.right - 20
self.score_rect.top = 20
def prep_high_score(self):
"""Turn the high score into a rendered image."""
high_score = int(round(self.stats.high_score, -1))
high_score_str = "{:,}".format(high_score)
self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.ai_settings.bg_color)
# Center the high score at the top of the screen.
self.high_score_rect = self.high_score_image.get_rect()
self.high_score_rect.centerx = self.screen_rect.centerx
self.high_score_rect.top = self.score_rect.top
def prep_level(self):
"""Turn the level into a rendered image."""
self.level_image = self.font.render(str(self.stats.level), True, self.text_color, self.ai_settings.bg_color)
# Position the level below the score.
self.level_rect = self.level_image.get_rect()
self.level_rect.right = self.score_rect.right
self.level_rect.top = self.score_rect.bottom + 10
def prep_ships(self):
"""Show how many ships are left."""
self.ships = Group()
for ship_number in range(self.stats.ships_left):
ship = Ship(self.ai_settings, self.screen)
ship.rect.x = 10 + ship_number * ship.rect.width
ship.rect.y = 10
self.ships.add(ship)
def show_score(self):
"""Draw scores and ships to the screen."""
self.screen.blit(self.score_image, self.score_rect)
self.screen.blit(self.high_score_image, self.high_score_rect)
self.screen.blit(self.level_image, self.level_rect)
# Draw ships.
self.ships.draw(self.screen)
here is ship.py:
import pygame
from pygame.sprite import Sprite
class Ship(Sprite):
def __init__(self, ai_settings, screen):
"""Initialize the ship and set its starting position."""
super(Ship, self).__init__()
self.screen = screen
self.ai_settings = ai_settings
# Load the ship image and get its rect.
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# Start each new ship at the bottom center of the screen.
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# Store a decimal value for the ship's center.
self.center = float(self.rect.centerx)
# Movement flags
self.moving_right = False
self.moving_left = False
def update(self):
"""Update the ship's position based on movement flags."""
# Update the ship's center value, not the rect.
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor
# Update rect object from self.center.
self.rect.centerx = self.center
def blitme(self):
"""Draw the ship at its current location."""
self.screen.blit(self.image, self.rect)
def center_ship(self):
"""Center the ship on the screen."""
self.center = self.screen_rect.centerx
And here is alien_invasion.py, the code that i run:
import pygame
from pygame.sprite import Group
from settings import Settings
from game_stats import GameStats
from scoreboard import Scoreboard
from button import Button
from ship import Ship
import game_functions as gf
def run_game():
# Initialize pygame, settings, and screen object.
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
# Make the Play button.
play_button = Button(ai_settings, screen, "Play")
# Create an instance to store game statistics and create a scoreboard.
stats = GameStats(ai_settings)
sb = Scoreboard(ai_settings, screen, stats)
# Make a ship, a group of bullets, and a group of aliens.
ship = Ship(ai_settings, screen)
bullets = Group()
aliens = Group()
# Create the fleet of aliens.
gf.create_fleet(ai_settings, screen, ship, aliens)
# Start the main loop for the game.
while True:
gf.check_events(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets)
if stats.game_active:
ship.update()
gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets)
gf.update_aliens(ai_settings, stats, screen, sb, ship, aliens, bullets)
gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button)
run_game()
This is the error that i keep getting:
game_functions.py, line 182 in ship_hit
sb.prep_ships()
AttribueError: 'pygame.Surface' objecthas no attribute 'prep_ships'
I really can't figure out what's wrong. Not even the rubber duck can help me this time. So some help would be appreciated.
The issue is the line ship_hit(ai_settings, stats, sb, screen, ship, aliens, bullets) in the function update_aliens. In this line the arguments stats and sb are swapped. It has to be:
ship_hit(ai_settings, stats, sb, screen, ship, aliens, bullets)
ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets)

Having trouble getting a button to render in Python Crash Course

So I'm learning python using Python Crash Course, and I think I have the correct code and yet its not yielding the desirable effect. The code is supposed to be freezing the game and displaying a "play button", but no play button is appearing.
Here is the "Alieninvasion.py" file:
import sys
from time import sleep
import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from bullet import Bullet
from alien import Alien
from button import Button
class AlienInvasion:
"""Overall class to manage game assets and behavior."""
def __init__(self):
"""Initialize the game, and create game resources."""
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
self.settings.screen_width = self.screen.get_rect().width
self.settings.screen_height = self.screen.get_rect().height
pygame.display.set_caption("Alien Invasion")
# Create an instance to store game statistics.
self.stats = GameStats(self)
self.ship = Ship(self)
self.bullets = pygame.sprite.Group()
self.aliens = pygame.sprite.Group()
self._create_fleet()
# Make the Play button.
self.play_button = Button(self, "Play")
# Set the background color.
self.bg_color = (230, 230, 230)
def run_game(self):
"""Start the main loop for the game."""
if self.stats.game_active:
self._check_events()
self.ship.update()
self._update_bullets()
self._update_aliens()
self._update_screen()
def _update_bullets(self):
"""Update position of bullets and get rid of old bullets."""
# Update bullet positions
self.bullets.update()
# Get rid of bullets that have disappeared.
for bullet in self.bullets.copy():
if bullet.rect.bottom <= 0:
self.bullets.remove(bullet)
self._check_bullet_alien_collisions()
def _check_bullet_alien_collisions(self):
"""Respond to bullet-alien collisions."""
# Remove any bullets and aliens that have collided.
collisions = pygame.sprite.groupcollide(
self.bullets, self.aliens, True, True)
if not self.aliens:
# Destroy existing bullets and create new fleet.
self.bullets.empty()
self._create_fleet()
def _ship_hit(self):
"""Respond to the ship being hit by an alien."""
if self.stats.ships_left > 0:
# Decrement ships_left.
self.stats.ships_left -=1
# Get rid of any remaining aliens and bullets.
self.aliens.empty()
self.ship.center_ship()
# Pause.
sleep(0.5)
else:
self.stats.game_active = True
def _create_fleet(self):
"""Create the fleet of aliens."""
# Create an alien and find the number of aliens in a row.
# Spacing between each alien is equal to one alien width.
alien = Alien(self)
alien_width, alien_height = alien.rect.size
available_space_x = self.settings.screen_width - (2 * alien_width)
number_aliens_x = available_space_x // (2 * alien_width)
# Determine the number of rows of aliens that fit on the screen.
ship_height = self.ship.rect.height
available_space_y = (self.settings.screen_height -
(3 * alien_height) - ship_height)
number_rows = available_space_y // (2 * alien_height)
# Create the full fleet of aliens.
for row_number in range(number_rows):
for alien_number in range(number_aliens_x):
self._create_alien(alien_number, row_number)
def _create_alien(self, alien_number, row_number):
"""Create an alien and place it in the row."""
alien = Alien(self)
alien_width, alien_height = alien.rect.size
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
self.aliens.add(alien)
def _check_events(self):
"""Respond to keypresses and mouse events."""
# Watch for keyboard and mouse events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
def _check_keydown_events(self, event):
"""Respond to keypresses."""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
elif event.key == pygame.K_q:
sys.exit()
elif event.key == pygame.K_SPACE:
self._fire_bullet()
def _check_keyup_events(self, event):
"""Respond to key releases."""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
def _fire_bullet(self):
"""Create a new bullet and add it to the bullets group."""
if len(self.bullets) < self.settings.bullets_allowed:
new_bullet = Bullet(self)
self.bullets.add(new_bullet)
def _update_aliens(self):
"""
Check if the fleet is at an edge,
then update the positions of all aliens in the fleet.
"""
self._check_fleet_edges()
self.aliens.update()
# Look for alien-ship collisions.
if pygame.sprite.spritecollideany(self.ship, self.aliens):
self._ship_hit()
# Look for aliens hitting the bottom of the screen.
self._check_aliens_bottom()
def _update_screen(self):
"""Update images on the screen, and flip to the new screen."""
# Redraw the screen during each pass through the loopp
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
for bullet in self.bullets.sprites():
bullet.draw_bullet()
self.aliens.draw(self.screen)
# Draw the play button if the game is inactive.
if not self.stats.game_active:
self.play_button.draw_button()
# Draw the play button if the game is inactive.
if not self.stats.game_active:
self.play_button.draw_button()
pygame.display.flip()
def _check_fleet_edges(self):
"""Respond appropriately if any aliens have reached an edge."""
for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break
def _change_fleet_direction(self):
"""Drop the entire fleet and change the fleet's direction."""
for alien in self.aliens.sprites():
alien.rect.y += self.settings.fleet_drop_speed
self.settings.fleet_direction *= -1
def _check_aliens_bottom(self):
"""Check if any aliens have reached the bottom of the screen."""
screen_rect = self.screen.get_rect()
for alien in self.aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
# Treat this the same as if the ship got hit.
self._ship_hit()
break
if __name__ == '__main__':
# Make a game instance, and run the game.
ai = AlienInvasion()
ai.run_game()
and here is the button and game stats codes:
gamestats.py
class GameStats:
"""Track statistics for Alien Invasion."""
def __init__(self, ai_game):
"""Initialize statistics."""
self.settings = ai_game.settings
self.reset_stats()
# Start Alien Invasion in an inactive state.
self.game_active = True
def reset_stats(self):
"""Initialize statistics that can change during the game."""
self.ships_left = self.settings.ship_limit
and
button.py
import pygame.font
class Button:
def __init__(self, ai_game, msg):
"""Initialize button attributes."""
self.screen = ai_game.screen
self.screen_rect = self.screen.get_rect()
# Set the dimensions and properties of the button.
self.width, self.height = 200, 50
self.button_color = (0, 255, 0)
self.text_color = (255, 255, 255)
self.font = pygame.font.SysFont(None, 48)
# Build the button's rect object and center it.
self.rect = pygame.Rect(0, 0, self.width, self.height)
self.rect.center = self.screen_rect.center
# The button message needs to be prepped only once.
self._prep_msg(msg)
def _prep_msg(self, msg):
"""Turn msg into a rendered image and center text on the button."""
self.msg_image = self.font.render(msg, True, self.text_color,
self.button_color)
self.msg_image_rect = self.msg_image.get_rect()
self.msg_image_rect.center = self.rect.center
def draw_button(self):
# Draw blank button and then draw message.
self.screen.fill(self.button_color, self.rect)
self.screen.blit(self.msg_image, self.msg_image_rect)
Thanks in advance!
self.game_active = True
this line in game_stats should be set to False to start the game...since it's set to True, this condition is never met in alien_invasion update_screen:
if not self.stats.game_active:
self.play_button.draw_button()
Hope you already caught that, came across this looking for another issue with that book. Also, you have the above comment/line/line duplicated in your code...not that it makes any difference.

Pygame Error: self.spritedict[spr] = surface_blit(spr.image, spr.rect)

I'm making a game with pygame using python 3. I can't get the image of a alien to display on the "screen" surface.
I've looked for hours and reviewed the book its based on but I can't find the source of the problem. I have also looked at other questions on here. Thanks
Heres's the trackback:
Traceback (most recent call last):
File "alien_invasion.py", line 35, in <module>
run_game()
File "alien_invasion.py", line 33, in run_game
g_funcs.update_screen(ai_settings, ai_screen, a_ship, aliens_g, bullets)
File ...
aliens_g.draw(ai_screen)
File...
self.spritedict[spr] = surface_blit(spr.image, spr.rect)
AttributeError: 'Alien' object has no attribute 'image'
Here's my game module:
import pygame
from pygame.sprite import Group
from settings import Settings
from ship import Ship
import game_function as g_funcs
def run_game():
"""Games definition with control while loop"""
#Initialize pygame, settings and screen surface
pygame.init()
ai_settings = Settings()
ai_screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_length))
pygame.display.set_caption("Alien Invasion")
#make a ship, group of bullets, group of aliens
a_ship = Ship(ai_settings, ai_screen)
bullets = Group()
aliens_g = Group()
#Create FLEET of aliens
g_funcs.create_fleet(ai_settings, ai_screen, aliens_g)
#start the main loop for the game
while True:
g_funcs.check_events(ai_settings, ai_screen, a_ship, bullets)
a_ship.update_location()
g_funcs.update_bullet(bullets)
g_funcs.update_screen(ai_settings, ai_screen, a_ship, aliens_g, bullets)
run_game()
Here's all the functions:
import sys
import pygame
from bullet import Bullet
from alien import Alien
def check_events(ai_settings, ai_screen, a_ship, bullets):
"""Respond to keypresses and mouse events."""
#watch for keyboard and mouse events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_event(event, ai_settings, ai_screen, a_ship, bullets)
elif event.type == pygame.KEYUP:
check_keyup_event(event, a_ship)
def check_keydown_event(event, ai_settings, ai_screen, a_ship, bullets):
"""ONLY callable by check_events function when keydown."""
if event.key == pygame.K_RIGHT:
a_ship.moving_right = True
elif event.key == pygame.K_LEFT:
a_ship.moving_left = True
elif event.key == pygame.K_UP:
a_ship.moving_up = True
elif event.key == pygame.K_DOWN:
a_ship.moving_down = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings, ai_screen, a_ship, bullets)
elif event.key == pygame.K_q:
sys.exit()
def fire_bullet(ai_settings, ai_screen, a_ship, bullets):
"""Fire bullets if bullets limit is not met"""
#CREATE a new bullet INSTANCE and add it to the bullets GROUP
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, ai_screen, a_ship)
bullets.add(new_bullet)
def check_keyup_event(event, a_ship):
"""ONLY callable by check_events function when keyup."""
if event.key == pygame.K_RIGHT:
a_ship.moving_right = False
if event.key == pygame.K_LEFT:
a_ship.moving_left = False
if event.key == pygame.K_UP:
a_ship.moving_up = False
if event.key == pygame.K_DOWN:
a_ship.moving_down = False
def update_screen(ai_settings, ai_screen, a_ship, aliens_g, bullets):
"""Update image on the screen and flip to the new screen."""
#Redraw the screen during each pass through the loop
ai_screen.fill(ai_settings.bg_color)
#REDRAW all bullets behind ship and aliens
for bullet in bullets.sprites():
bullet.draw_bullet()
a_ship.blitme()
aliens_g.draw(ai_screen)
#Make the most recently drawn screen visible
pygame.display.flip()
def update_bullet(bullets):
"""Update positions of bullets and delete old ones."""
#Update bullet positions
bullets.update()
#get rid of the old bullets that go off screen
for bullet in bullets.copy():
if bullet.bullet_rect.bottom <= 0:
bullets.remove(bullet)
def create_fleet(ai_settings, ai_screen, aliens_g):
"""Create a full fleet of aliens"""
alien = Alien(ai_settings, ai_screen)
alien_amount_x = get_number_aliens_x(ai_settings, alien.alien_rect.width)
#Create the first row of aliens
for one in range(alien_amount_x):
create_alien(ai_settings, ai_screen, aliens_g, one)
def get_number_aliens_x(ai_settings, alien_width):
"""Determine the amount of alien that fits in a row"""
#Calulations:
availabe_space_x = ai_settings.screen_width - 2 * alien_width
alien_amount_x = int(availabe_space_x / (2 * alien_width))
return alien_amount_x
def create_alien(ai_settings, ai_screen, aliens_g, one):
"""Create an alien and place it in the row."""
alien = Alien(ai_settings, ai_screen)
alien_width = alien.alien_rect.width
alien.x = alien_width + 2 * alien_width * one
alien.alien_rect.x = alien.x
aliens_g.add(alien)
And... heres my alien module:
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
"""A CLASS that MANAGES a single alienn in the fleet."""
def __init__(self, ai_settings, ai_screen):
"""Initialize the alien and start position"""
super().__init__()
self.ai_settings = ai_settings
self.screen = ai_screen
#Load the alien image and SET RECT attribute
self.alien_image = pygame.image.load('images/alien.bmp')
self.alien_rect = self.alien_image.get_rect()
#Set starting point of alien at the top left corner of screen
#settings the space(top and left) to the width and height of image_rect
self.alien_rect.x = self.alien_rect.width
self.alien_rect.y = self.alien_rect.height
self.x_float = float(self.alien_rect.x)
def blit_a(self):
"""Draw alien at its current location"""
self.screen.blit(self.alien_image, self.alien_rect)
Pygame sprites must have a self.image and a self.rect attribute, otherwise the sprite group won't be able to blit the image and an AttributeError gets raised.
If you take a look at the draw method of the sprite groups, you'll see that it iterates over the contained sprites and blits the spr.image at the spr.rect.
Use name self.image instead of self.alien_image and self.rect instead of self.alien_rect
naming conventions are important in pygame.sprites, so there's an another method to solve this
instead of group.draw(surface) you can use a for loop to print individual alien on screen
for alien in aliens_g.sprites():
alien.blit_a()

Using pygame.sprite.spritecollideany Python

I am new to python programming, and I am practicing by making a Alien Invasion game. This is a classic game configuration, there are rows of aliens you have to shot down before they make it to the bottom and collide with your ship.
Here is my game_functions code:
import sys
import pygame
from bullet import Bullet
from alien import Alien
def check_keydown_events(event, ai_settings, screen, ship, bullets):
"""Respond to keypresses."""
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings, screen, ship, bullets)
elif event.key == pygame.K_q:
sys.exit()
def fire_bullet(ai_settings, screen, ship, bullets):
"""Fire a bullet if mimit not reached yet."""
#Create a new bullet and add it to the bullets group
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
def check_keyup_events(event, ship):
"""Respond to key releases."""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(ai_settings, screen, ship, bullets):
"""Respond to keypresses and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ai_settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)
def update_screen(ai_settings, screen, ship, aliens, bullets):
"""Update images on the screen and flip to the new screen."""
# Redraw the screen during each pass through the loop.
screen.fill(ai_settings.bg_color)
#Redraw bullets behind the ship and aliens
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
aliens.draw(screen)
# Make the most recently drawn screen visible.
pygame.display.flip()
def update_bullets(ai_settings, screen, bullets, aliens, ship):
"""Update position of bullets and get rid of olf bullets."""
#Update bullet position
bullets.update()
#Check for any bullets that hit an alien.
#if so, get rid of the bullet and alien
#Get rid of bullets that have disappeared
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
check_bullet_alien_collisons(ai_settings, screen, bullets, aliens, ship)
def check_bullet_alien_collisons(ai_settings, screen, bullets, aliens, ship):
"""Respond to bullet-alien collions."""
#Remove any bullets and aliens that collide.
collisons = pygame.sprite.groupcollide(bullets, aliens, True, True)
if len(aliens) == 0:
#Destroy existing bullets and create new fleet.
bullets.empty()
create_fleet(ai_settings, screen, aliens, ship)
def get_number_aliens_x(ai_settings, alien_width):
"""Determine the number of aliens that fit in a row."""
available_space_x = ai_settings.screen_width - 2 * alien_width
number_aliens_x = int(available_space_x / (2 * alien_width))
return number_aliens_x
def get_number_rows(ai_settings, ship_height, alien_height):
"""Find the number of rows for screen."""
available_space_y = (ai_settings.screen_height -
(3 * alien_height) - ship_height)
number_rows = int(available_space_y / (3 * alien_height))
return number_rows
def create_alien(ai_settings, screen, aliens, alien_number, row_number):
"""Create an alien and place it in the row."""
alien = Alien(ai_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)
def create_fleet(ai_settings, screen, ship, aliens):
"""Create a full fleet of aliens."""
#Create an alien and find the number of aliens in a row
alien = Alien(ai_settings, screen)
number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
number_rows = get_number_rows(ai_settings, ship.rect.height, alien.rect.height)
#Create the fleet of aliens
for row_number in range(number_rows):
for alien_number in range(number_aliens_x):
create_alien(ai_settings, screen, aliens, alien_number, row_number)
def check_fleet_edges(ai_settings, aliens):
"""Respond appropriately if any aliens reached an edge."""
for alien in aliens.sprites():
if alien.check_edges:
change_fleet_direction(ai_settings, aliens)
break
def change_fleet_direction(ai_settings, aliens):
"""Drop the entire fleet and change the fleet's direction."""
for alien in aliens.sprites():
alien.rect.y += ai_settings.fleet_drop_speed
ai_settings.fleet_direction *= -1
def update_aliens(ai_settings, aliens, ship):
"""Check for fleet on edge, then update positions of fleet."""
check_fleet_edges(ai_settings, aliens)
aliens.update()
#Look for alien-ship collisons.
if pygame.sprite.spritecollideany(aliens, ship):
print("Ship hit!")
And this is my game init code so I can run the functions and play the game
import pygame
from pygame.sprite import Group
from settings import Settings
from ship import Ship
from alien import Alien
import game_functions as gf
def run_game():
#Initialze game, settings, and screen object.
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion!")
#Make a ship, a group of aliens, and a group of bullets
ship = Ship(ai_settings, screen)
aliens = Group()
bullets = Group()
#Create a fleet of aliens
gf.create_fleet(ai_settings, screen, ship, aliens)
# Start the main loop for the game
while True:
gf.check_events(ai_settings, screen, ship, bullets)
ship.update()
gf.update_bullets(ai_settings, screen, bullets, aliens, ship)
gf.update_aliens(ai_settings, aliens, ship)
gf.update_screen(ai_settings, screen, ship, aliens, bullets)
run_game()
I have most of the game done, but when I add the pygame.sprite.spritecollideany() in the game_functions file, I get
"Attribute Error: the 'Group' has no attribute 'rect'"
I know there is probably something simple I am missing, but I cannot figure it out. Sorry of the code is not correctly typed as I copied and pasted to save time when posting my question.
I am also using Ubuntu 14.04 LTS, and running python-3.4.3.
Read Pygame doc: pygame.sprite.spritecollideany()
This function expects single sprite as first argument, and group as second argument but you use aliens which is group as first argument, and ship which is sprite as second argument.
You have to change order of arguments.
BTW: next time simply use print() - it is most popular method (if you don't know how to debug) to check what you have in variables and see what is wrong.

Categories

Resources