0

my first question here and begginer in python

i want to make simple shooter game(Chicken Invaders type). List of rectangles(enemies) and smaller rectangles(ammo) who should 'kill' enemies on collision. I created list of rectangles on random positions on screen.

enemies = []
for i in range(ENEMYCOUNT):
        enemySize = random.randint(ENEMYMINSIZE, ENEMYMAXSIZE)
        newEnemy = pygame.Rect(random.randint(0, WINDOWWIDTH - enemySize),
            random.randint(0, WINDOWWIDTH-200), enemySize, enemySize)
        enemies.append(newEnemy)

My 'ammo' are list of invisible rectangles who appear on mouse click and then they move up

ammo = []
for i in range(1, 5):
    ammo.append(pygame.Rect(0, 0, 0, 0))

I did for single enemy and single ammo and it is working as intended. Now i want to make for more enemies and check if any of enemy is hit by ammo

for e in enemies:
        for a in ammo:
            if e.colliderect(a):
                enemies.remove(e)

But i keep getting

if e.colliderect(a): AttributeError: 'NoneType' object has no attribute 'colliderect'

I am studying from 'inventwithpython' book and copying parts of code that i need but i could not solve this. I cant see the problem since both of my lists are made of Rect objects. Any help would be appreciated

furas
  • 134,197
  • 12
  • 106
  • 148
Andr
  • 17
  • 6
  • The problem is that `e` is of `NoneType` which literally means `e = None`. Since `e` is an element out of the list `enemies` where you appended the `newEnemy` objects (`pygame.Rect` in our case) to. So you should make sure that those `Rect` objects are initialized properly and are not of type `None` – albert Jan 30 '16 at 22:29
  • 1
    You might want to check [this](http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python) regarding your 3rd code snippet. – CristiFati Jan 30 '16 at 22:29
  • problem can be because you remove from list which you use in `for` statement. It is very popular problem. Solution: create new list with not-removed elements and later assign it to `enemies`. – furas Jan 30 '16 at 22:47
  • @albert I figured that out but i cant understand why is this since when i add 'print(type(e), type(a))' in my double for loop it prints ' ' EDIT: I found that after e = e.inflate(-1, -1) my e(Rect type) becomes NoneType so that is problem but why does this occur since in documentation says it returns rectangle http://www.pygame.org/docs/ref/rect.html#pygame.Rect.inflate_ip – Andr Jan 31 '16 at 09:20

1 Answers1

1

Problem can be because you remove from list which you use in for statement.

Solution: create new list with not-removed elements and later assign it to enemies

But Pygame has class Group to keep Sprites and

pygame.sprite.spritecollide(sprite, group, dokill, collided = None)

which:

Return a list containing all Sprites in a Group that intersect with another Sprite. Intersection is determined by comparing the Sprite.rect attribute of each Sprite.

The dokill argument is a bool. If set to True, all Sprites that collide will be removed from the Group.

Community
  • 1
  • 1
furas
  • 134,197
  • 12
  • 106
  • 148