mechanicarts
mechanicarts

Reputation: 171

"for" loop in python-pygame does not break under an "if" statement

I am trying to make a "space invaders" game in pygame...I have much of the game already running, but I ran into an annoying problem I cannot solve myself (it is the first programming course I have taken). Here is the code in question:

for enemy in enemies:
   if hero.sprite.rect.colliderect(enemy.sprite.rect) or enemy.posy>400:
      hero.health-=1
      initgame()
      break
   else:
      enemy.moveBy(enemyPos, ENEMYVERT)
      enemy.draw()

So what this should supposedly do is:

  1. check for every item in a list named "enemies" (where I have appended all my enemy instances)
  2. if it collides with the hero sprite or if they have reached the bottom of the screen
  3. then remove one life from the player, initialise the game (remake the enemy list, reset positions)
  4. and break the "for" loop.
  5. Else, move the enemies and blit them as usual.

However, what this does is actually remove ALL lives from the player on touch. Shouldn't it stop calculating since I used break? I think it keeps calculating if any in enemies has reached 400px thus keeps removing lives from my player.

This is my initgame function

def initgame():
    enemies=[]
    createEnemies("1.png", 50, 250)
    createEnemies("2.png", 50, 190)
    createEnemies("3.png", 50, 130)
    createEnemies("4.png", 50, 70)
    createEnemies("5.png", 50, 10)
    enemyPos=0
    enemyDir=-1
    hero.score=0
    restartFlag=False
    for enemy in enemies:
        enemy.draw()

Upvotes: 0

Views: 574

Answers (3)

Gurgeh
Gurgeh

Reputation: 2168

Try putting

global enemies

at the row before enemies=[] in initgame()

You are not clearing your global enemies variable otherwise. In general it is better to put everything in a class and use self.enemies to share data between functions, than to rely on global variables.

You put your functions in a class, like this:

class SpaceInvaders:
  def __init__(self):
    self.initgame()

  def initgame(self):
    self.enemies = []
    ...#createEnemies
    self.enemyPos = 0
    self.enemyDir = -1
    #etc

  def run(self):
    #your while loop here

All variables that should be shared between functions will now be referred to as self.. This distinguish them from local variables (like "enemy" in your for loop) that are only used inside the function.

You use this class by making an object an calling run.

game = SpaceInvaders()
game.run()

Upvotes: 1

Aaron Dufour
Aaron Dufour

Reputation: 17505

It looks like you aren't emptying enemies, so the old ones plus the new ones are there after initgame(). The problem is that the line enemies=[] is creating and setting a local variable. In order to do what you want, try:

def initgame():
    global enemies
    enemies=[]

Upvotes: 1

Andre Blum
Andre Blum

Reputation: 391

Your break statement should work as anticipated. There must be another reason for health dropping all the way back (other than looping too much). Probably this reason can be found in initgame().

Upvotes: 0

Related Questions