Python - Как вызвать действие в методе из другого метода - PullRequest
1 голос
/ 23 мая 2019

Я хочу, чтобы враги появлялись в игре со случайными интервалами 1-5 секунд.Чтобы предотвратить приостановку игровой части программы (движущийся персонаж и т. Д.) При наличии sleep, я разделил весь код на 2 метода, чтобы у меня было 2 потока - один, который устанавливает enemyspawn True каждый 1-5 секунд и еще одна, которая контролирует персонажа.

К сожалению, либо 2-й метод не изменится enemyspawn в первом методе, либо поток выдает ошибку.Я прочитал и попытался получить значение из EnemySpawn() перед оператором if, но это не сработало (или я просто сделал это неправильно).Я также попытался превратить enemyspawn в глобальную переменную.Ничего не изменилось.

def Gameplay():
    width=80
    height=80
    y = 720/2+height/2
    x = 720/2+width/2
    speed=2

    enemyspawn = False
    while True:
        #controll character here
        if enemyspawn:
            enemyspawn=False
            print(enemyspawn) #Spawn enemy here later

        window.blit(bg, [0,0])
        pygame.draw.rect(window,(100,100,100),(x,y,width,height))
        pygame.display.update()


def EnemySpawn():
    enemyspawn = EnemySpawn() #idrk about this line

    while True:
        sleep(randint(1,5))
        enemyspawn=True
        print(enemyspawn)
    return enemyspawn

Gameplay = threading.Thread(target=Gameplay)
Gameplay.start()
EnemySpawn = threading.Thread(target=EnemySpawn)
EnemySpawn.start()

Сообщение об ошибке потоков:

line 51, in EnemySpawn
    enemyspawn = Gameplay(enemyspawn)
UnboundLocalError: local variable 'enemyspawn' referenced before assignment

Другое сообщение об ошибке:

line 51, in EnemySpawn
    enemyspawn = EnemySpawn()
TypeError: 'Thread' object is not callable

1 Ответ

0 голосов
/ 23 мая 2019

Вы не захотите вызывать функцию из той же функции (рекурсивная функция) в этой ситуации.Лучшим подходом может быть:

def spawn_enemy():
    # code that makes an enemy
    print("an enemy has been spawned")
    return True # would be "return enemy" after you create your enemy entity

def EnemySpawnThread():
    enemy_list = [] # to maintain records of all enemies made
    while True: # make enemies forever
        sleep(randint(1,5))
        enemy_list.append(spawn_enemy()) # call our function we made above which spawns enemies

В настоящее время это будет просто список, подобный [True, True, True, ...], но в конечном итоге вы, вероятно, определите класс врага, и он станет [enemy_object, enemy_object, ...], что предпочтительнее, потому что лучший способЯ обнаружил, что для удаления объектов нужно сохранить их в списках, а затем del enemy_list[index], чтобы удалить их (например, когда враг умирает, так что он не использует память).Кроме того, он дает вам возможность перебирать, например:

for enemy in enemy_list:
    enemy.move()
    enemy.attack()
    enemy.die()

Именно поэтому вы бы хотели, чтобы enemy был классом с методами, подобными показанным выше.

В качестве примечаниявы, вероятно, захотите иметь enemy_list в качестве глобальной переменной (или в вашей основной функции), чтобы все ваши потоки могли получить к ней доступ.В противном случае вам нужно будет реализовать встроенный стандарт queue.Queue() с python.

...