Reputation: 77
I am making a game and when the sprite goes under 100 on the x axis it is supposed to be deleted. The sprites are all located in a class. When the first sprite reaches the end, it deletes the final sprite of the group instead of the first.
Enemy Class
class Enemy(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('Enemy.gif').convert()
self.rect = self.image.get_rect(x=x, y=y)
def update(self):
self.rect.x -= 4
def die(self):
for enemy in EnemyList:
if enemy.rect.x<100:
EnemyList.remove(enemy)
def draw(self, DISPLAY):
DISPLAY.blit(self.image, self.rect)
Main Loop (Part for enemy)
time = 0
while not Gameover: #Loop of the gameplay
if time in (0,50,100,150,200):
enemy = Enemy(DIS_HEIGHT,random.randrange(0,DIS_HEIGHT)
enemy.add(EnemyList)
EnemyList.update()
EnemyList.draw(DISPLAY)
enemy.die()
time +=1
I have a background and everything else works fine, I just cannot delete the correct sprite from the enemy group.
Upvotes: 5
Views: 23859
Reputation: 9766
An easier way would be to use the Sprite method kill()
which removes a sprite from all pygame.sprite.Group
´s it's currently in.
def die(self):
if self.rect.x < 100:
self.kill()
Calling die()
in your update()
will allow you to check whether to kill your sprite every game loop, but given the amount of code in die()
you could simply just move the code inside the update()
. And based on your current code, your EnemyList
is already a pygame.sprite.Group
object, so no change is needed there.
Your current die()
method is quite hard for me to comprehend. You're creating an enemy which checks whether all enemies (itself and the other in the list) should die. So in your game loop you call the method from a single enemy in order to control all enemies. In other words, you're creating identical objects with different responsibilities. As a rule of thumb: an object's methods should change only its own states.
Lastly, the draw()
method is unnecessary since the superclass defines the method exactly in the way you have. So removing yours would instead call draw()
of pygame.sprite.Sprite
.
Upvotes: 10
Reputation: 5031
You cannot remove items from a list while iterating over it:
def die(self):
for enemy in EnemyList:
if enemy.rect.x<100:
EnemyList.remove(enemy)
You could instead write something like this:
def die(self):
global EnemyList
EnemyList = [enemy for enemy in EnemyList if enemy.rect.x>=100]
The global
statement is needed so that the function can modify the EnemyList
, which is outside its scope in this case.
Or store the enemies that you want to delete to another list, and then delete them afterwards.
Upvotes: 4