'NoneType' не имеет атрибута 'colliderect'

мой первый вопрос здесь и начинающий в python

Я хочу сделать простой шутер (типа Chicken Invaders). Список прямоугольников (враги) и меньших прямоугольников (боеприпасы), которые должны «убивать» врагов при столкновении. Я создал список прямоугольников в случайных местах на экране.

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)

Мои `` боеприпасы '' - это список невидимых прямоугольников, которые появляются при щелчке мыши, а затем перемещаются вверх.

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

Я сделал для одиночного врага и одиночных боеприпасов, и он работает как задумано. Теперь я хочу создать больше врагов и проверить, поражен ли какой-либо из врагов боеприпасами.

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

Но я продолжаю получать

if e.colliderect (a): AttributeError: объект 'NoneType' не имеет атрибута 'colliderect'

Я изучаю книгу «CreateWithpython» и копирую части кода, которые мне нужны, но я не мог решить эту проблему. Я не вижу проблемы, поскольку оба моих списка состоят из объектов Rect. Любая помощь будет оценена


person Andr    schedule 30.01.2016    source источник
comment
Проблема в том, что e принадлежит NoneType, что буквально означает e = None. Поскольку e - это элемент из списка enemies, к которому вы добавили объекты newEnemy (в нашем случае pygame.Rect). Поэтому вы должны убедиться, что эти Rect объекты инициализированы правильно и не относятся к типу None.   -  person albert    schedule 31.01.2016
comment
Возможно, вы захотите проверить это относительно своего третьего кода. фрагмент.   -  person CristiFati    schedule 31.01.2016
comment
проблема может быть из-за того, что вы удалили из списка, который используете в операторе for. Это очень популярная проблема. Решение: создать новый список с неотъемлемыми элементами и позже назначить его enemies.   -  person furas    schedule 31.01.2016
comment
@albert Я понял это, но не могу понять, почему это так, потому что, когда я добавляю 'print (type (e), type (a))' в свой цикл double for, он печатает '‹class' pygame.Rect '› ‹class' pygame.Rect '›' EDIT: я обнаружил, что после e = e.inflate (-1, -1) мой e (тип Rect) становится NoneType, так что это проблема, но почему это происходит, поскольку в документации говорится, что он возвращает прямоугольник pygame.org/docs/ref/rect.html#pygame.Rect. inflate_ip   -  person Andr    schedule 31.01.2016


Ответы (1)


Проблема может быть из-за того, что вы удалили из списка, который используете в заявлении for.

Решение: создать новый список с неотделенными элементами и позже назначить его enemies

Но у Pygame есть класс Group, чтобы сохранить Sprites и

pygame.sprite.spritecollide (спрайт, группа, dokill, collided = Нет)

который:

Вернуть список, содержащий все спрайты в группе, которые пересекаются с другим спрайтом. Пересечение определяется путем сравнения атрибута Sprite.rect каждого Sprite.

Аргумент dokill - булево. Если установлено значение True, все сталкивающиеся спрайты будут удалены из группы.

person furas    schedule 30.01.2016
comment
Вы также можете перебрать копию списка enemes. for e in enemies[:]: - person Håken Lid; 31.01.2016