Я хочу, чтобы в стене черепахи прыгал мяч на стене, но они останавливаются, бродят и отправляют ошибку - PullRequest
1 голос
/ 28 апреля 2019

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

Когда я пропускаю треугольникидвигаться только в форме креста, треугольники запинаются и появляется сообщение об ошибке.

import turtle
import random
def draw_sq(t,distance=400):#Draw a box
    t.penup()
    t.goto(-200,200)
    t.pendown()
    t.forward(distance)
    t.right(90)
    t.forward(distance)
    t.right(90)
    t.forward(distance)
    t.right(90)
    t.forward(distance)
    t.penup()
    t.goto(0,0)
    t.pendown()
def add_tri():
    global l_tri
    t=turtle.Turtle()
    t.shape("triangle")
    x=-200
    y=random.randint(-200,200)
    t.penup()
    t.goto(x,y)
    t.setheading(random.randint(-89,89))
    # make triangle and start
    l_tri.append(t)# add a triangle to list
def successMan():#write word succes 
    global playing
    if playing==True:
        t.write("success")

def turn_right():
    global right
    right = True

def turn_left():
    global left
    left = True

def turn_up():
    global up
    up = True

def turn_down():
    global down
    down = True

def _turn_right():
    global right
    right = False

def _turn_left():
    global left
    left = False

def _turn_up():
    global up
    up = False

def _turn_down():
    global down
    down = False

def is_touch(x,y,triangle,threshold=20):
    global playing
    if((x-triangle.position()[0])**2+(y-triangle.position()[1])**2<=threshold**2):
        playing=False#if triangle touches the turtle make playing False

def timer_go():
    global heading
    global l_tri
    global t
    global playing
    global up
    global left
    global down
    global right# heading is where turtle heads
    if up:
        if right:
            heading=45
        elif left:
            heading=135
        elif down:
            heading = heading
        else:
            heading=90
    if down:
        if right:
            heading=315
        elif left:
            heading=225
        elif up:
            pass
        else:
            heading = 270
    if left:
        if right:
            heading = heading
        elif up:
            pass
        elif down:
            pass
        else:
            heading = 180
    if right:
        if left:
            pass
        elif up:
            pass
        elif down:
            pass
        else:
            heading = 0

    t.setheading(heading)
    t.forward(10)
        # turtle controller
    for i in range(3):#triangles move
        if (l_tri[i].position()[0]<-200):
            l_tri[i].setheading(180-l_tri[i].heading())
            l_tri[i].forward(10)
        if (l_tri[i].position()[0]>200):
            l_tri[i].setheading(180-l_tri[i].heading())
            l_tri[i].forward(10)
        if (l_tri[i].position()[1]<-200):
            l_tri[i].setheading(-l_tri[i].heading())
            l_tri[i].forward(10)
        if (l_tri[i].position()[1]>200):
            l_tri[i].setheading(-l_tri[i].heading())
            l_tri[i].forward(10)#triangle bounces on the wall
        l_tri[i].forward(10)
        is_touch(t.position()[0],t.position()[1],l_tri[i],threshold=20)
    # check triangle and turtle
    if (playing==False):
        t.write("FAIL")
        #Fail

up = False
down = False
right = False
left = False
playing = True
heading = 0
l_tri = []

t = turtle.Turtle()
t.shape('turtle')
t.speed(0)
draw_sq(t)
screen = t.screen

screen.onkeypress(turn_right, 'Right')
screen.onkeypress(turn_left, 'Left')
screen.onkeypress(turn_up, 'Up')
screen.onkeypress(turn_down, 'Down')
screen.onkeyrelease(_turn_right, 'Right')
screen.onkeyrelease(_turn_left, 'Left')
screen.onkeyrelease(_turn_up, 'Up')
screen.onkeyrelease(_turn_down, 'Down')


for i in range(3):
    add_tri()
for i in range(1,200):
    time = i*100
    screen.ontimer(timer_go, time)
screen.ontimer(successMan,20000)
screen.listen()
screen.mainloop()

Это должна быть игра, в которой игрок избегает треугольников в поле.

Ответы [ 2 ]

1 голос
/ 28 апреля 2019

Когда я его запускаю, я вижу ошибку

RecursionError: maximum recursion depth exceeded while calling a Python object

, но не вижу рекурсии в коде.

Возможно, проблема в

for i in range(1,200):
    time = i*100
    screen.ontimer(timer_go, time)

Возможно, это создаетслишком много функций.

Вы можете запустить его один раз

screen.ontimer(timer_go, 100)

и использовать снова в конце timer_go()

def timer_go():

    # ... rest of code ...

    screen.ontimer(timer_go, 100)

, и он будет повторять все этовремя.

Вы можете увидеть этот метод даже в официальном документе: turtle.ontimer

0 голосов
/ 28 апреля 2019

Я согласен с @furas (+1) о том, как настроить ontimer(timer_go, 100), но я вижу другие проблемы с вашим кодом. Я переделал это ниже, и я надеюсь, что вы найдете некоторые изменения полезными.

Конкретные проблемы: вам нужно (пере) прочитать примерно global как половину времени, когда вы используете его неправильно; вам не нужно заново изобретать turtle.distance() (например, в is_touch()); вам нужно отделить playing == False от неудачи, так как вам нужно остановить игру в случае успеха или неудачи; Вам нужно только указать количество треугольников в одном месте:

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

FONT = ('Arial', 16, 'normal')

def draw_square(turtle, distance=400):  # Draw a box
    turtle.speed('fastest')
    turtle.penup()
    turtle.goto(-200, 200)
    turtle.pendown()

    for _ in range(4):
        turtle.forward(distance)
        turtle.right(90)

def add_triangle():
    triangle = Turtle("triangle")
    triangle.penup()
    triangle.goto(choice([(choice([-150, 150]), randint(-150, 150)), (randint(-150, 150), choice([-150, 150]))]))
    triangle.setheading(randint(-89, 89))
    # make triangle and start
    triangles.append(triangle)  # add a triangle to list

def successMan():  # write word success
    global playing

    if playing:
        player.write("Success!", font=FONT)
        playing = False

def turn_right():
    global right
    right = True

def turn_left():
    global left
    left = True

def turn_up():
    global up
    up = True

def turn_down():
    global down
    down = True

def _turn_right():
    global right
    right = False

def _turn_left():
    global left
    left = False

def _turn_up():
    global up
    up = False

def _turn_down():
    global down
    down = False

def is_touch(player, triangle, threshold=20):
    return player.distance(triangle) < threshold

def timer_go():
    global playing

    heading = player.heading()

    if up:
        if right:
            heading = 45
        elif left:
            heading = 135
        elif down:
            pass
        else:
            heading = 90

    if down:
        if right:
            heading = 315
        elif left:
            heading = 225
        elif up:
            pass
        else:
            heading = 270

    if left:
        if right:
            pass
        elif up:
            pass
        elif down:
            pass
        else:
            heading = 180

    if right:
        if left:
            pass
        elif up:
            pass
        elif down:
            pass
        else:
            heading = 0

    player.setheading(heading)
    player.forward(10)

    # turtle controller
    for triangle in triangles:  # triangles move
        x, y = triangle.position()

        if not -200 < x < 200:
            triangle.setheading(180 - triangle.heading())
            triangle.forward(10)

        if  not -200 < y < 200:
            triangle.setheading(-triangle.heading())
            triangle.forward(10)

        triangle.forward(10)

        # check triangle and turtle
        if is_touch(player, triangle, threshold=20):
            playing = False
            player.write("FAIL!", font=FONT)  # Fail

    if playing:
        screen.ontimer(timer_go, 100)

up = False
down = False
right = False
left = False

playing = True
triangles = []

draw_square(Turtle(visible=False))

for _ in range(3):
    add_triangle()

player = Turtle('turtle')
player.speed('fastest')

screen = Screen()

screen.onkeypress(turn_right, 'Right')
screen.onkeypress(turn_left, 'Left')
screen.onkeypress(turn_up, 'Up')
screen.onkeypress(turn_down, 'Down')

screen.onkeyrelease(_turn_right, 'Right')
screen.onkeyrelease(_turn_left, 'Left')
screen.onkeyrelease(_turn_up, 'Up')
screen.onkeyrelease(_turn_down, 'Down')

screen.ontimer(successMan, 20_000)

timer_go()

screen.listen()
screen.mainloop()

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

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

...