我绘制了一些三角形,它们应该在墙上反弹,但是它们不会弹跳,它们不会直线,它们会在几秒钟后打印出错误信息。
当我让三角形只以十字形移动时,三角形会动摇并出现错误信息。
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()
这应该是玩家避开盒子中的三角形的游戏。
当我运行它时,我看到错误
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
我同意@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
是由于你的关键事件,因为你的模型似乎是多个键可以一次关闭。但是如果一个键保持太长时间,它可能会导致键事件中的键事件,这看起来像递归。您通常可以通过禁用键事件处理程序作为事件处理程序中的第一件事,执行您的工作,然后重新启用键事件处理程序来解决此问题。
但是,您可能还有操作系统控制的自动键重复逻辑对您不利。如果您的密钥处理结果是一个问题,请考虑使用更简单的方法。