Can't display more than 1 sprites - PyGame - python

Problem
My problem is that I have a game that generates 8 obstacles at the start of the game. The issue is that when I loop through the obstacles list, and update the sprites group, it only generates 1 sprite.
What I Want To Happen
When the game loads, I want 8 squares to fly down from the top of the window at random speeds, and starting at random positions.
What Is Currently Happening
Currently, when the game loads, only one square is falling from the screen.
PYthon Code
OBSTICLES_AMOUNT = 8
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((30, 30))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(0, WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.velY = 6
def animate(self):
self.rect.y += self.velY
class Game(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
pygame.init()
pygame.mixer.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
self.running = True
self.clock = pygame.time.Clock()
self.obstaclesList = []
self.allSprites = pygame.sprite.Group()
self.obstacles = pygame.sprite.Group()
def new(self):
# create a new game
# add obstacles to list
for i in range(OBSTICLES_AMOUNT):
self.obstacle = Obstacle()
self.obstaclesList.append(self.obstacle)
# make new sprite using list
for i in self.obstaclesList:
self.allSprites.add(i)
self.obstacles.add(i)
self.gameLoop()
def gameLoop(self):
# main game loop
while self.running:
self.draw()
def draw(self):
self.screen.fill(WHITE)
self.allSprites.draw(self.screen)
for sprites in self.obstaclesList:
sprites.update()
self.allSprites.update()

Your code is fixed by
adding missing imports
adding missing constants
renaming animate to update in the Obstacle class
calling pygame.display.update after drawing
using a Clock to limit the framerate
adding event handling
adding code to create a Game instance
Some more improvements:
no need for obstaclesList if you already have obstacles
you can pass Groups directly to Sprite's __init__ function
remove a Sprite when it's no longer on the screen
Here's the code:
import pygame
import random
OBSTICLES_AMOUNT = 8
WIDTH, HEIGHT = 800,600
TITLE='some game of falling stuff'
BLUE = pygame.color.THECOLORS['blue']
WHITE = pygame.color.THECOLORS['white']
class Obstacle(pygame.sprite.Sprite):
def __init__(self, *args):
pygame.sprite.Sprite.__init__(self, *args)
self.image = pygame.Surface((30, 30))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(0, WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.velY = 6
def update(self):
self.rect.y += self.velY
if self.rect.y > HEIGHT:
self.kill()
class Game(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
pygame.init()
pygame.mixer.init()
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
self.running = True
self.clock = pygame.time.Clock()
self.allSprites = pygame.sprite.Group()
self.obstacles = pygame.sprite.Group()
def new(self):
# create a new game
# add obstacles to list
for i in range(OBSTICLES_AMOUNT):
Obstacle(self.allSprites, self.obstacles)
while self.running:
self.allSprites.update()
for e in pygame.event.get():
if e.type == pygame.QUIT:
self.running = False
self.draw()
self.clock.tick(60)
def draw(self):
self.screen.fill(WHITE)
self.allSprites.draw(self.screen)
for sprites in self.obstacles:
sprites.update()
pygame.display.update()
if __name__ == '__main__':
Game().new()

Related

How can I check collisions of 2 sprites groups? [duplicate]

This question already has answers here:
pygame.sprite.groupcollide() does not work when trying to implement collision in pygame [duplicate]
(1 answer)
Permanently delete sprite from memory Pygame
(1 answer)
Pygame - getting a sprite to cycle through images in a class, and assign a hitbox
(1 answer)
Closed 8 days ago.
How do I check the collisions between the bullet_grou and the enemy_group and if they collide I want them do disappear. I have looked at few simular questions but none of them helped me. Thenks for all the help.
This game is supposed to be a simular game to the asteroids. #I dont know what more to specify here bt it doesnt let me post this question if I dont write some more over her sorry
import pygame , sys
from random import randint
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50,50))
self.image.fill((255,255,255))
self.rect = self.image.get_rect(center = (screen_width/2,screen_height/2))
def update(self):
self.rect.center = pygame.mouse.get_pos()
def create_bullet(self):
return Bullet(pygame.mouse.get_pos()[0],pygame.mouse.get_pos()[1])
def create_enemy(self):
return Enemy(randint(50,screen_width-50),-200)
class Bullet(pygame.sprite.Sprite):
def __init__(self,pos_x,pos_y):
super().__init__()
self.image = pygame.Surface((5,25))
self.image.fill((255,0,0))
self.rect = self.image.get_rect(center = (pos_x,pos_y))
def update(self):
self.rect.y -= 5
if self.rect.y <= -200:
self.kill()
class Enemy(pygame.sprite.Sprite):
def __init__(self,pos_x,pos_y):
super().__init__()
self.image = pygame.Surface((50,50))
self.image.fill((255,140,0))
self.rect = self.image.get_rect(center = (pos_x,pos_y))
## def __init__(self):
## super().__init__()
## self.image = pygame.Surface((50,50))
## self.image.fill((255,128,128))
## self.rect = self.image.get_rect(center = (randint(0,screen_width),-200))
##
def update(self):
self.rect.y += 5
if self.rect.y >= screen_height + 200:
self.kill()
pygame.init()
clock = pygame.time.Clock()
screen_width, screen_height = 800, 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.mouse.set_visible(False)
obstacle_timer = pygame.USEREVENT + 1
pygame.time.set_timer(obstacle_timer,150)
player = Player()
player_group = pygame.sprite.Group()
player_group.add(player)
bullet_group = pygame.sprite.Group()
enemy_group = pygame.sprite.Group()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
# enemy_group.add(player.create_enemy())
bullet_group.add(player.create_bullet())
if event.type == obstacle_timer:
if randint(0,2):
enemy_group.add(player.create_enemy())
## if Enemy.rect.coliderect(Bullet.rect):
## print('colision')
screen.fill((30,30,30))
bullet_group.draw(screen)
bullet_group.update()
# collide_enemy_bullet = pygame.sprite.spritecollide(bullet_group, Enemy , False) #HERE IS THE PROBLEM
collide_player_enemy = pygame.sprite.spritecollide(player, enemy_group, False)
for s in collide_player_enemy:
pygame.draw.rect(screen, (255, 255, 255), s.rect, 5, 1)
print('collide_player_enemy')
## for x in collide_enemy_bullet:
## pygame.draw.rect(screen, (255, 255, 255), x.rect, 5, 1)#HERE ALSO
## print('collide_enemy_bullet')
player_group.draw(screen)
player_group.update()
enemy_group.draw(screen)
enemy_group.update()
pygame.display.flip()
clock.tick(240)
pygame.sprite.groupcollide() should do the trick. You pass in the first group and the second group, and whether you want each group to disappear on collision.
# True means you want them to disappear on collision
pygame.sprite.groupcollide(bullet_group, enemy_group, True, True)
Pygame docs: https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.groupcollide

Why does anything with key input not update? [duplicate]

My collide_rect function isn't working properly. It always returns True, when it's not suppose to. I have tried looking on the internet but nothing is working for me. I think the collide rect somehow did not use the actual coordinates for the two sprites. Can anyone help with this?
import pygame
import pygame.sprite
import sys
gameDisplay = pygame.display.set_mode((800,600))
pygame.display.set_caption("test_collision")
clock = pygame.time.Clock()
crashed = False
class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("ball.png")
self.rect = self.image.get_rect()
self.x = 280
self.y = 475
self.col = False
def update(self):
gameDisplay.blit(self.image, (self.x,self.y))
self.rect = self.image.get_rect()
def test_collisions(self,sprite):
self.col = pygame.sprite.collide_rect(self,sprite)
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.x = 1000
self.y = 483
self.image = pygame.image.load("obstacle.png")
self.time = pygame.time.get_ticks()
self.rect = self.image.get_rect()
def change_x(self):
self.time = pygame.time.get_ticks()
self.x = -(self.time/5) + 800
def update(self):
self.rect = self.image.get_rect()
gameDisplay.blit(self.image,(self.x,self.y))
obstacle = Obstacle()
ball = Ball()
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
gameDisplay.fill((255,255,255))
ball.update()
obstacle.change_x()
obstacle.update()
ball.test_collisions(obstacle)
if ball.col:
print("colided")
pygame.display.flip()
clock.tick(1000)
pygame.quit()
sys.exit()
P.S This is my first post :)
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, but it returns a rectangle that always starts at (0, 0) since a Surface object has no position.
The Surface is placed at a position on the display with the blit function.
You've to set the location of the rectangle, either by a keyword argument, e.g:
self.rect = self.image.get_rect(topleft = (self.x, self.y))
or an assignment to a virtual attribute (see pygame.Rect), e.g:
self.rect = self.image.get_rect()
self.rect.topleft = (self.x, self.y)
It is absolutely unnecessary to add some extra attributes self.x and self.y. Use the location of the rectangle instead. e.g:
class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("ball.png")
self.rect = self.image.get_rect(topleft = (280, 475))
self.col = False
def update(self):
gameDisplay.blit(self.image, self.rect)
def test_collisions(self,sprite):
self.col = pygame.sprite.collide_rect(self,sprite)
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("obstacle.png")
self.time = pygame.time.get_ticks()
self.rect = self.image.get_rect(topleft = (1000, 483))
def change_x(self):
self.time = pygame.time.get_ticks()
self.rect.x = -(self.time/5) + 800
def update(self):
gameDisplay.blit(self.image, self.rect)
Further note, that you can get rid of the methods Ball.update() respectively Obstacle.update() (you can delete them), if you use a pygame.sprite.Group and call .draw(), which uses the .image and .rect properties of the contained sprites, to draw them. e.g.:
obstacle = Obstacle()
ball = Ball()
all_sprites = pygame.sprite.Group([obstacle, ball])
while not crashed:
# [...]
gameDisplay.fill((255,255,255))
all_sprites.draw(gameDisplay)
pygame.display.flip()
clock.tick(1000)

sprite rectangles in pygame [duplicate]

My collide_rect function isn't working properly. It always returns True, when it's not suppose to. I have tried looking on the internet but nothing is working for me. I think the collide rect somehow did not use the actual coordinates for the two sprites. Can anyone help with this?
import pygame
import pygame.sprite
import sys
gameDisplay = pygame.display.set_mode((800,600))
pygame.display.set_caption("test_collision")
clock = pygame.time.Clock()
crashed = False
class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("ball.png")
self.rect = self.image.get_rect()
self.x = 280
self.y = 475
self.col = False
def update(self):
gameDisplay.blit(self.image, (self.x,self.y))
self.rect = self.image.get_rect()
def test_collisions(self,sprite):
self.col = pygame.sprite.collide_rect(self,sprite)
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.x = 1000
self.y = 483
self.image = pygame.image.load("obstacle.png")
self.time = pygame.time.get_ticks()
self.rect = self.image.get_rect()
def change_x(self):
self.time = pygame.time.get_ticks()
self.x = -(self.time/5) + 800
def update(self):
self.rect = self.image.get_rect()
gameDisplay.blit(self.image,(self.x,self.y))
obstacle = Obstacle()
ball = Ball()
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
gameDisplay.fill((255,255,255))
ball.update()
obstacle.change_x()
obstacle.update()
ball.test_collisions(obstacle)
if ball.col:
print("colided")
pygame.display.flip()
clock.tick(1000)
pygame.quit()
sys.exit()
P.S This is my first post :)
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, but it returns a rectangle that always starts at (0, 0) since a Surface object has no position.
The Surface is placed at a position on the display with the blit function.
You've to set the location of the rectangle, either by a keyword argument, e.g:
self.rect = self.image.get_rect(topleft = (self.x, self.y))
or an assignment to a virtual attribute (see pygame.Rect), e.g:
self.rect = self.image.get_rect()
self.rect.topleft = (self.x, self.y)
It is absolutely unnecessary to add some extra attributes self.x and self.y. Use the location of the rectangle instead. e.g:
class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("ball.png")
self.rect = self.image.get_rect(topleft = (280, 475))
self.col = False
def update(self):
gameDisplay.blit(self.image, self.rect)
def test_collisions(self,sprite):
self.col = pygame.sprite.collide_rect(self,sprite)
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("obstacle.png")
self.time = pygame.time.get_ticks()
self.rect = self.image.get_rect(topleft = (1000, 483))
def change_x(self):
self.time = pygame.time.get_ticks()
self.rect.x = -(self.time/5) + 800
def update(self):
gameDisplay.blit(self.image, self.rect)
Further note, that you can get rid of the methods Ball.update() respectively Obstacle.update() (you can delete them), if you use a pygame.sprite.Group and call .draw(), which uses the .image and .rect properties of the contained sprites, to draw them. e.g.:
obstacle = Obstacle()
ball = Ball()
all_sprites = pygame.sprite.Group([obstacle, ball])
while not crashed:
# [...]
gameDisplay.fill((255,255,255))
all_sprites.draw(gameDisplay)
pygame.display.flip()
clock.tick(1000)

Text not displaying - Python (PyGame)

Problem
So, i'm trying to render text that holds the player's score, but when I writ the code, it doesn't work.
Python Code
class Player(pygame.sprite.Sprite):
def __init__(self, x, color):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((10, 100))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.y = HEIGHT / 2 - self.rect.height / 2
self.rect.centerx = x
self.displacement = 8
self.score = 0
def update(self):
# update function
self.constrain(0, HEIGHT - self.rect.height)
def constrain(self, min, max):
# constrian player to walls
if self.rect.y > max:
self.rect.y = max
if self.rect.y < min:
self.rect.y = min
class Text():
def __init__(self, x, y, color, text, font):
self.x = x
self.y = y
self.color = color
self.text = text
self.font = font
def draw(self):
text = self.font.render(self.text, False, self.color)
text.blit(text, (self.x, self.y))
class Game(pygame.sprite.Sprite):
def __init__(self):
# get sprite object
pygame.sprite.Sprite.__init__(self)
# init pygame
pygame.init()
# init pygame modules
pygame.mixer.init()
pygame.font.init()
# set window
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
# set title
pygame.display.set_caption(TITLE)
# holds whether the game is running for not
self.running = True
# get timer function
self.clock = pygame.time.Clock()
# set fonts
self.scoreText = pygame.font.Font("assets/fonts/square.TTF", 25)
self.titleFontLight = pygame.font.Font("assets/fonts/square.TTF", 50)
# group for sprites
self.allSprites = pygame.sprite.Group()
def new(self):
# creates a new game
# make players
self.player1 = Player(20, RED)
self.player2 = Player(WIDTH - 30, BLUE)
self.ball = Ball()
self.p1Score = Text(100, 100, (RED), str(self.player1.score), self.scoreText)
self.p2Score = Text(WIDTH - 10, 10, (WHITE), str(self.player2.score), self.scoreText)
# put players inside groups
self.allSprites.add(self.player1)
self.allSprites.add(self.player2)
# run game loop
self.gameLoop()
def gameLoop(self):
# main game loop
while self.running:
self.allSprites.update()
self.update()
self.clock.tick(FPS)
def update(self):
# updates game
self.draw()
pygame.display.update()
def draw(self):
# draws to screen
# set background color
self.screen.fill(BLACK)
# draw to screen
self.ball.draw(self.screen)
self.p1Score.draw()
self.allSprites.draw(self.screen)
if __name__ == '__main__':
Game().new()
What I want to happen
I want text to display on the screen at the x and y coordinates that I put in my code.
What I Am Getting
Currently, the text is not being displayed, also there are no errors.
What I have tried
I have tried to put in the absolute path to the font, ex: C:/name/file/font.TTF
In your current code, this line is the problem:
text.blit(text, (self.x, self.y)). This code is drawing some text onto itself. You want to draw the text onto the screen. Replace that line with this line:
screen.blit(text, (self.x, self.y)).
This means that you need to have a screen argument for your Text's draw function. So def draw(self): should be def draw(self,screen):. Finally, you must pass the self.screen argument, so self.p1Score.draw() should be self.p1Score.draw(self.screen). The final code, with all changes made should be:
class Player(pygame.sprite.Sprite):
def __init__(self, x, color):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((10, 100))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.y = HEIGHT / 2 - self.rect.height / 2
self.rect.centerx = x
self.displacement = 8
self.score = 0
def update(self):
# update function
self.constrain(0, HEIGHT - self.rect.height)
def constrain(self, min, max):
# constrian player to walls
if self.rect.y > max:
self.rect.y = max
if self.rect.y < min:
self.rect.y = min
class Text():
def __init__(self, x, y, color, text, font):
self.x = x
self.y = y
self.color = color
self.text = text
self.font = font
def draw(self,screen):
text = self.font.render(self.text, False, self.color)
screen.blit(text, (self.x, self.y))
class Game(pygame.sprite.Sprite):
def __init__(self):
# get sprite object
pygame.sprite.Sprite.__init__(self)
# init pygame
pygame.init()
# init pygame modules
pygame.mixer.init()
pygame.font.init()
# set window
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
# set title
pygame.display.set_caption(TITLE)
# holds whether the game is running for not
self.running = True
# get timer function
self.clock = pygame.time.Clock()
# set fonts
self.scoreText = pygame.font.Font("assets/fonts/square.TTF", 25)
self.titleFontLight = pygame.font.Font("assets/fonts/square.TTF", 50)
# group for sprites
self.allSprites = pygame.sprite.Group()
def new(self):
# creates a new game
# make players
self.player1 = Player(20, RED)
self.player2 = Player(WIDTH - 30, BLUE)
self.ball = Ball()
self.p1Score = Text(100, 100, (RED), str(self.player1.score), self.scoreText)
self.p2Score = Text(WIDTH - 10, 10, (WHITE), str(self.player2.score), self.scoreText)
# put players inside groups
self.allSprites.add(self.player1)
self.allSprites.add(self.player2)
# run game loop
self.gameLoop()
def gameLoop(self):
# main game loop
while self.running:
self.allSprites.update()
self.update()
self.clock.tick(FPS)
def update(self):
# updates game
self.draw()
pygame.display.update()
def draw(self):
# draws to screen
# set background color
self.screen.fill(BLACK)
# draw to screen
self.ball.draw(self.screen)
self.p1Score.draw(self.screen)
self.allSprites.draw(self.screen)
if __name__ == '__main__':
Game().new()

Pygame Collision Not Working - pygame.sprite.collide_rect()

I'm working on a space shooter game and In that game, when an alien sprite collides with a player sprite, I want the game to end. When wrote the code for the collision, It didn't end the game. Can someone help me?
main.py
# IMPORTS
import pygame
from sprites import *
from config import *
# GAME
class Game():
def __init__(self):
# INIT PYGAME
pygame.init()
pygame.mixer.init()
pygame.display.set_caption(TITLE)
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
self.clock = pygame.time.Clock()
self.running = True
self.player = Player()
# NEW GAME
def new(self):
self.allSprites = pygame.sprite.Group()
self.allAliens = pygame.sprite.Group()
for amount in range(ALIEN_AMOUNT):
self.alien = Alien()
self.allAliens.add(self.alien)
self.allSprites.add(self.alien)
self.allSprites.add(self.player)
self.run()
# RUN GAME
def run(self):
self.playing = True
while self.playing:
self.clock.tick(FPS)
self.events()
self.update()
self.draw()
self.animate()
self.collision()
# DRAW
def draw(self):
self.screen.fill(BLACK)
self.allAliens.draw(self.screen)
self.allSprites.draw(self.screen)
pygame.display.update()
# ANIMATE
def animate(self):
pass
# DETECT COLLISION
def collision(self):
# player collition with alien
hits = pygame.sprite.collide_rect(self.alien, self.player)
if hits:
self.playing = False
self.running = False
# CHECK FOR EVENTS
def events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
if self.playing:
self.playing = False
self.running = False
# UPDATE GAME
def update(self):
self.allSprites.update()
# GAME OVER
def gameOver(self):
pass
# START SCREEN
def startScreen(self):
pass
# END SCREEN
def endScreen(self):
pass
game = Game()
game.startScreen()
while game.running:
game.new()
game.gameOver()
# QUIT
pygame.quit()
quit()
sprites.py
# IMPORTS
import pygame, random
from config import *
# PLAYER
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("assets/img/player.png").convert()
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.rect.x = WIDTH / 2
self.rect.y = HEIGHT - 50
self.velX = 0
def animate(self):
self.rect.x += self.velX
def control(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.velX = -5
elif keys[pygame.K_RIGHT]:
self.velX = 5
else:
self.velX = 0
def collision(self):
# collision with walls
if self.rect.left < 0:
self.rect.left = 0
elif self.rect.right > WIDTH:
self.rect.right = WIDTH
def update(self):
self.animate()
self.control()
self.collision()
# ALIEN
class Alien(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("assets/img/rsz_alien.png").convert()
self.image.set_colorkey(WHITE)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(10, WIDTH - self.rect.w - 10)
self.rect.y = random.randrange(-100, -10)
self.velY = random.randrange(2, 8)
def animate(self):
self.rect.y += self.velY
def collision(self):
if self.rect.y > HEIGHT:
self.reset()
def update(self):
self.animate()
self.collision()
def reset(self):
self.rect.x = random.randrange(0, WIDTH)
self.rect.y = random.randrange(-100, -10)
self.velY = random.randrange(2, 8)
There's a config.py file but I don't think its needed for this question
You're only testing for collision with a single alien (which will be the last one that you created and assigned to self.alien). You need to iterate over all the aliens and test for collisions between the player and each of them.
def collision(self):
# player collision with each alien
for alien in self.allAliens:
hits = pygame.sprite.collide_rect(alien, self.player)
if hits:
self.playing = False
self.running = False

Categories

Resources