Манипулировать несколькими черепахами Python, определенными внутри функции - PullRequest
0 голосов
/ 07 октября 2018

Вот часть моего кода, которая, я считаю, является проблемой.Имея это в виду, у меня есть два вопроса, первый: «Как я могу манипулировать несколькими объектами (черепахами Python)?»который я пытаюсь решить с помощью списков и .append().Это вызывает следующую проблему:

if enemy.index(enemy).ycor() < -100:
NameError: name 'enemy' is not defined

Я думаю, что это как-то связано с невозможностью (я полагаю) определения объекта Turtle внутри функции.В связи с этим возникает второй вопрос: «Как я могу создать Turtle объект внутри функции?»

def spawn(t,shape,color,x,y):
        t = turtle.Turtle() 
        t.speed(0)
        t.up()
        t.goto(x,y)
        t.shape(shape)
        t.color(color)
def go_upx():
    if enemy.index(enemy).heading() != 90:
        enemy.index(enemy).seth(90) 

def go_downx():
    if enemy.index(enemy).heading() != 270:
        enemy.index(enemy).seth(270)

def go_leftx():
    if enemy.index(enemy).heading() != 180:
        enemy.index(enemy).seth(180)
def move():
    if enemy.index(enemy).heading() == 90:
        y = enemy.index(enemy).ycor()
        enemy.index(enemy).sety(y + 20)

    if enemy.index(enemy).heading() == 270:
        y = enemy.index(enemy).ycor()
        enemy.index(enemy).sety(y - 20)

    if enemy.index(enemy).heading() == 180:
        x = enemy.index(enemy).xcor()
        enemy.index(enemy).setx(x - 20)

def enemies_direction():
    en_direction = random.randint(1,3)
    if 1 == en_direction:
        go_upx()
    if 2 == en_direction:
        go_leftx()
    if 3 == en_direction:
        go_downx()

enemies = []
#Main Loop
while True:
    wn.update()
    for x in range(0,10):
        for enemy in enemies:
            randy = random.randint(-90,300)
            enemies.append(spawn(enemy.index(enemy),"circle","blue",490,randy))
            enemies_direction()
            if enemy.xcor<-600:
                enemy.pop(enemy.index(enemy))
    BgLimits()           
    move()
    time.sleep(delay)

wn.mainloop()

1 Ответ

0 голосов
/ 07 октября 2018

Как я могу создать черепаху внутри функции?

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

здесь мы имеемчасть кода, которая относится к проблеме

Вот то, что я вижу, это проблема s с этим кодом:

while True:

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

if enemy.xcor<-600:

Неправильная логика Python для черепах, это должно быть:

if enemy.xcor() < -600:

В этой ситуации:

enemies.append(spawn(...))

, как упоминает @JohnnyMopp, spawn() возвращает None, поэтому enemies представляет их список.Вам нужно, чтобы spawn() вернул новую черепаху.Здесь:

enemy.pop(...)

Вы, похоже, путаете вашу переменную enemy (черепаха) и глобальный список enemies черепах.(Вы можете pop() список, но не черепаха.)

Другие проблемы включают в себя смешивание вашего цикла инициализации и вашего основного цикла - двух разных циклов.

Ниже мойЛучшее предположение - переделка того, что пытается сделать ваш код:

from turtle import Screen, Turtle
from random import choice, randint

def spawn(shape, color, x, y):
    t = Turtle(shape, visible=False)
    t.speed('fastest')
    t.color(color)
    t.penup()
    t.goto(x, y)
    t.showturtle()

    return t

def go_upx(enemy):
    enemy.seth(90)

def go_downx(enemy):
    enemy.seth(270)

def go_leftx(enemy):
    enemy.seth(180)

def move(enemy):
    if enemy.heading() == 90:
        y = enemy.ycor()
        enemy.sety(y + 20)

    if enemy.heading() == 180:
        x = enemy.xcor()
        enemy.setx(x - 20)

    if enemy.heading() == 270:
        y = enemy.ycor()
        enemy.sety(y - 20)

def enemy_direction(enemy):
    direction_function = choice([go_upx, go_downx, go_leftx])

    direction_function(enemy)

wn = Screen()
wn.setup(640, 640)
wn.tracer(False)

enemies = []

for _ in range(10):
    rand_y = randint(-300, 300)
    enemy = spawn("circle", "blue", 300, rand_y)
    enemy_direction(enemy)
    enemies.append(enemy)

def move_all():

    for enemy in enemies:
        if -320 <= enemy.ycor() <= 320 and enemy.xcor() >= -320:
            pass  # still on the screen
        else:
            enemy.hideturtle()
            enemies.pop(enemies.index(enemy))

        move(enemy)
        enemy_direction(enemy)
        wn.update()

    if enemies:
        wn.ontimer(move_all, 100)  # still enemies left to move
    else:
        wn.tracer(True)  # all done, restore normal graphics mode

move_all()

wn.mainloop()

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

...