Pygame объект не вызывается при попытке создать более 1 врага

#python-3.x #pygame #collision-detection

#python-3.x #pygame #обнаружение столкновения

Вопрос:

Мне удалось создать способ доступа к каждому врагу в списке и определить, был ли он поражен… Я думаю… Помимо проблемы. Моя проблема в том, что каждый раз, когда я хочу создать более одного врага, я получаю сообщение об ошибке «Враг не является вызываемым объектом»

Я, честно говоря, не знаю, что здесь происходит не так. Я просмотрел другие сообщения, и в одном похожем сообщении говорится о том, что «убедитесь, что я не создаю свой объект = что-либо еще». Однако мой объект не вызывается нигде, кроме того места, где он добавляется в список.

Вне цикла

 Enemies = []
print("Enemies at start: ",len(Enemies))
  

Он возвращает «0»

Создание врага внутри цикла while

 if len(Enemies) <= 5:
    Enemies.append(Enemy(random.randint(0,500),-50,70,70))
        #Spawns an enemy while the list is still less than 5 not really relevant and should be removed after code below is fixed.
    print("Enemies at creation point: ",len(Enemies))
    for Enemy in Enemies:
        #Enemies.append(Enemy(random.randint(0,500),-50,70,70))
        print("Created")
        if Enemy.health <= 0:
            Enemies.pop(Enemies.index(Enemy))
            print("Destroyed")
        else:
            print("Skipping")
  

Ошибка: объект ‘Enemy’ не вызывается

Я ожидаю, что на выходе эти враги просто появятся на экране в случайных позициях. Хотя 5 одновременно не существуют. Таким образом, в начале он больше не будет создавать врагов. Однако, когда один уничтожен, создается новый.

Комментарии:

1. Обратите внимание, как вы создаете переменную с именем Enemy , а затем пытаетесь использовать Enemy в качестве имени класса для создания объекта. Просто измените переменную цикла (в любом случае вы должны использовать нижний регистр для имен ваших переменных).

2. где вы определяете класс Enemy ? Я вижу только переменную Enemy в for Enemy in Enemies , поэтому вы заменяете определение класса обычной переменной. Не используйте Enemy как переменную в for . Существует также хорошее правило — мы используем имена с первой заглавной буквой только для имени класса, но не для экземпляров и переменных. Поэтому лучше использовать for enemy in enemies

3. КСТАТИ: в Pygame есть класс Sprite для создания объекта, подобного enemy, и класс Group для сохранения спрайтов. Когда у вас есть спрайт в группе и вы используете sprite.kill() , он автоматически удалит спрайт из группы.

Ответ №1:

Ваша ошибка в том, что вы используете одно и то же имя для определения класса Enemy и переменной в for Enemy in Enemies

В PEP 8 — Руководство по стилю для кода Python есть хорошее правило использовать имена в нижнем регистре для переменных и имена в верблюжьем регистре (с первой заглавной буквой) для имен классов

Поэтому вам лучше иметь

 enemies = []
print("Enemies at start:", len(enemies))


if len(enemies) <= 5:
    enemies.append(Enemy(random.randint(0,500),-50,70,70))
        #Spawns an enemy while the list is still less than 5 not really relevant and should be removed after code below is fixed.
    print("Enemies at creation point: ", len(enemies))
    for enemy in enemies:
        #enemies.append(Enemy(random.randint(0,500),-50,70,70))
        print("Created")
        if enemy.health <= 0:
            enemies.pop(enemies.index(enemy))
            print("Destroyed")
        else:
            print("Skipping")
  

Как вы можете видеть, я использую Enemy только в Enemy(random.randint(0,500),-50,70,70) . В других местах я использую enemy

Кстати: даже редактор в SO знает это правило, и он использует светло-синий цвет, чтобы показать класс Enemy и сделать код более читаемым.

Комментарии:

1. Спасибо, однако возникла новая проблема. Он не считывается, если здоровье врага меньше 0…

2. Это тот же блок кода, я говорю о той части, где он выполняет «для врага в enemies:», После завершения создания он, похоже, полностью игнорирует блок.