I trying to make spaceship game from using pygame. Just simple game what warship shoot bullet and collide enemies. But when I play my game, after 6 or 7 collisions I get below error.
import pygame import random import time WIDTH, HEIGHT = (750, 600) WIN = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Space İnvader Game") BG_IMAGE = pygame.transform.scale(pygame.image.load("yeni_resim.jpg"), (WIDTH, HEIGHT)) CAPTION_IMAGE = pygame.image.load("spaceship.png") ENEMY_IMAGE = pygame.image.load("enemy.png") BULLET_IMAGE = pygame.image.load("bullet.png") PLAYER_IMAGE = pygame.image.load("warship.png")
creating bullet class
class Bullet: def __init__(self, x, y): self.x = x self.y = y self.img = BULLET_IMAGE self.mask = pygame.mask.from_surface(self.img) self.vel = 8 self.hitbox = (self.x, self.y, 32,32) def draw(self, window): window.blit(self.img, (self.x, self.y)) self.hitbox = (self.x, self.y, 32, 32) pygame.draw.rect(window,(0,0,255),self.hitbox,2) def get_width(self): return self.img.get_width() def get_height(self): return self.img.get_height() def collide(self, obj1, obj2): self.offset_x = obj2.x - obj1.x self.offset_y = obj2.y - obj1.y return obj1.mask.overlap(obj2.mask , (self.offset_x, self.offset_y)) != None class Ship: def __init__(self, x, y,width,height): self.x = x self.y = y self.width = width self.height = height self.ship_img = None def draw(self, window): window.blit(self.ship_img, (self.x, self.y)) def get_width(self): return self.ship_img.get_width() def get_height(self): return self.ship_img.get_height() class Player(Ship): def __init__(self, x, y,width,height): super().__init__(x, y,width,height) self.ship_img = PLAYER_IMAGE self.mask = pygame.mask.from_surface(self.ship_img) self.hitbox = (self.x, self.y, 64, 64) def draw(self, window): super().draw(window) self.hitbox = (self.x , self.y , 64, 64) pygame.draw.rect(window, (0, 0, 255), self.hitbox, 2)
creating enemy class and defining collide def
class Enemy(): def __init__(self, x, y): self.x = x self.y = y self.ship_img = ENEMY_IMAGE self.mask = pygame.mask.from_surface(self.ship_img) self.enemy_vel = 4 self.hitbox = (self.x, self.y, 64, 64) def draw(self, window): self.hitbox = (self.x, self.y, 64, 64) window.blit(self.ship_img,(self.x, self.y)) pygame.draw.rect(window, (255,0,0),self.hitbox,2) def move(self,x,y): self.x = x self.y = y self.x += self.enemy_vel if self.x >= 686 or self.x <= 0: self.enemy_vel *= -1 self.y += 5 def get_width(self): return self.ship_img.get_width() def get_height(self): return self.ship_img.get_height() def hit(self): print("Hit") def collide(self,obj1, obj2): self.offset_x = obj2.x - obj1.x self.offset_y = obj2.y - obj1.y return obj1.mask.overlap(obj2.mask , (self.offset_x, self.offset_y)) != None def main(): run = True FPS = 60 clock = pygame.time.Clock() bullets = [] enemies = [] player = Player(350, 500,64,64) player_vel = 8 enemy_vel = 3 def redraw_window(): WIN.blit(BG_IMAGE,(0,0)) player.draw(WIN) for bullet in bullets: bullet.draw(WIN) for enemy in enemies: enemy.draw(WIN) pygame.display.update()
calling collide definition in for enemy loop
while run: clock.tick(FPS) redraw_window() if len(enemies) < 8: enemies.append(Enemy(random.randint(0, 600), random.randint(0,200))) for enemy in enemies: enemy.move(enemy.x, enemy.y) for bullet in bullets: if bullet.collide(enemy,bullet): enemies.pop(enemies.index(enemy)) bullets.pop(bullets.index(bullet)) for bullet in bullets: if bullet.y < 600 and bullet.y > 0: bullet.y -= bullet.vel else: bullets.pop(bullets.index(bullet)) keys = pygame.key.get_pressed() if keys[pygame.K_RIGHT] and player.x + player_vel + player.get_width() < WIDTH: player.x += player_vel if keys[pygame.K_LEFT] and player.x - player_vel > 0: player.x -= player_vel if keys[pygame.K_SPACE]: if len(bullets) < 10: bullets.append(Bullet(round(player.x + 17),round(player.y))) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False main()
Then take this error after 6 or 7 time collision
C:Users191119AppDataLocalProgramsPythonPython38-32python.exe "C:/Users/191119/PycharmProjects/Pygame Projects2/AIGAMES.py" pygame 1.9.6 Hello from the pygame community. https://www.pygame.org/contribute.html Traceback (most recent call last): File "C:/Users/191119/PycharmProjects/Pygame Projects2/AIGAMES.py", line 180, in <module> main() File "C:/Users/191119/PycharmProjects/Pygame Projects2/AIGAMES.py", line 151, in main enemies.pop(enemies.index(enemy)) ValueError: <__main__.Enemy object at 0x07527868> is not in list
Advertisement
Answer
This is your problem:
for enemy in enemies: enemy.move(enemy.x, enemy.y) for bullet in bullets: if bullet.collide(enemy,bullet): enemies.pop(enemies.index(enemy)) bullets.pop(bullets.index(bullet))
You are iterating over the lists and deleting elements from the lists while you are still going through them. That is not something that you are allowed to do.
Try iterating through a copy of the lists and deleting from the originals. Something like this:
for enemy in enemies.copy(): enemy.move(enemy.x, enemy.y) for bullet in bullets.copy(): if bullet.collide(enemy,bullet): enemies.pop(enemies.index(enemy)) bullets.pop(bullets.index(bullet))
On a different note, it is not clear to me why you are doing this kind of operation:
bullets.pop(bullets.index(bullet))
instead of using remove()
like this:
bullets.remove(bullet)