0
votes

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

1
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
You might want to check this regarding your 3rd code snippet. - CristiFati
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
@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 '<class 'pygame.Rect'> <class 'pygame.Rect'>' 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 pygame.org/docs/ref/rect.html#pygame.Rect.inflate_ip - Andr

1 Answers

1
votes

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.