如何将乌龟弹离 canvas

How to bounce turtle off the canvas

我目前正在学习 Charles Dierbach 的书《计算机科学导论》Python。

我试图让我的乌龟从 canvas 上反弹,但它不起作用。我尝试了不同的变体,但无法修复它

这是我的代码:

    #Drunkard walk PYTHON

from turtle import *
from random import *

#draw a house
def house(t):
    pu()
    goto(270,100)
    pd()
    pensize(5)
    for i in range(4):
        fd(100)
        right(90)
    setheading(120)
    fd(100)
    setheading(240)
    fd(100)
    pu()
    goto(200,0)
    pd()
    setheading(90)
    fd(70)
    setheading(0)
    fd(40)
    setheading(270)
    fd(70)
    pu()


#make roads
def road(t):
    pu()
    goto(80, 280)
    pd()
    begin_fill()
    color('black')
    setheading(270)
    fd(250)
    setheading(180)
    fd(100)
    setheading(90)
    fd(250)
    setheading(0)
    fd(100)
    end_fill()
    pu()
    goto(80,25)
    pd()
    begin_fill()
    color('white')
    setheading(270)
    for i in range(4):
        fd(70)
        right(90)
        fd(100)
        right(90)
    end_fill()
    pu()
    goto(80, -45)
    pd()
    begin_fill()
    color('black')
    setheading(270)
    fd(240)
    setheading(180)
    fd(100)
    setheading(90)
    fd(240)
    setheading(0)
    fd(100)
    end_fill()

  #this is my code to keep turtle on canvas   
def isInScreen(window, t):
    xmin=-299
    xmax=299
    ymin=-299
    ymax=299

    xTcor = t.xcor()
    yTcor = t.ycor()

    if xTcor<xmin or xTcor>xmax:
        new_heading = (180 - t.heading())
        return new_heading
    if yTcor<ymin or yTcor>ymax:
        new_heading = (360 - t.heading())
        return new_heading
    #house coord
    if (170<=xTcor<=200 or 200<=xTcor<=270)and yTcor==0:
        new_heading = (360 - t.heading())
        return new_heading
    if xTcor==170 and 0<=yTcor<=100:
        new_heading = (180 - t.heading())
        return new_heading
    if (170<=xTcor<=200 or 200<=xTcor<=270) and yTcor==100:
        new_heading = (360 - t.heading())
        return new_heading
    if xTcor==270 and 0<=yTcor<=100:
        new_heading = (180 - t.heading())
        return new_heading
    if 170<=xTcor<=271 and 100<=yTcor<=150:
        new_heading = (360 - t.heading())
        return new_heading
    if  200<=xTcor<=240 and yTcor ==0:
        new_heading = 0 
        return new_heading
    return  100




#################MAIN####################
setup(600,600)
window=Screen()
window.title("Drunkard walk")
window.bgcolor("grey")


#get the turtle and change the shape
t=getturtle()
t.shape('turtle')
shapesize(2,1.2,1.2)

pu()

#change coords and make the ouer roads
goto(290,290)
pd()
setheading(270)
pensize(10)

for i in range(4):
    fd(580)
    right(90)


shape('circle')
house(t)
goto(80,0)
road(t)
penup()
goto(-250,-260)
shapesize(1,1,1)
walking = True
while walking:
    pendown()
    fd(10)
    color = choice(["black", "red", "yellow", "blue", "white", "green"]) 
    fillcolor(color)
    ch = randrange(2)
    if ch == 0:
        left(90)
    else:
        right(90)
    setheading(isInScreen(window, t))


mainloop()
exitonclick()

我已经从您的代码中提取了一个最简单的示例,并让它在屏幕上跳来跳去。主要变化是:

1) 如果乌龟实际上还没有到达墙壁,您决定乌龟是否应该从墙上弹回的例程不应该做任何事情——但是您 return 一个新的航向

2) 你不应该在使用海龟图形时创建无限循环,这会阻止事件处理程序 运行ning(例如 exitonclick() 在你的代码中不起作用,因为它从未达到.) Intead 在事件框架内使用提供给 运行 你的乌龟的计时器功能:

import turtle

CANVAS_WIDTH, CANVAS_HEIGHT = 600, 600

def headIntoCanvas(t):
    """ keep turtle on canvas """
    xmin, xmax = -CANVAS_WIDTH // 2, CANVAS_WIDTH // 2
    ymin, ymax = -CANVAS_HEIGHT // 2, CANVAS_HEIGHT // 2

    xTcor, yTcor = t.position()

    old_heading = t.heading()

    if not xmin < xTcor < xmax:
        new_heading = (180 - old_heading)
        return new_heading  # bounce off wall

    if not ymin < yTcor < ymax:
        new_heading = (360 - old_heading)
        return new_heading  # bounce off floor/ceiling

    return old_heading  # stay the course

def motion():
    """ make the turtle march around """
    t.forward(5)
    t.setheading(headIntoCanvas(t))
    turtle.ontimer(motion, 25)  # again!

turtle.setup(CANVAS_WIDTH, CANVAS_HEIGHT)

# get the turtle and change the shape
t = turtle.Turtle()
t.shape('circle')
t.shapesize(1, 1, 1)
t.speed("fastest")

t.penup()
t.goto(- CANVAS_WIDTH // 3, - CANVAS_HEIGHT // 3)
t.pendown()

t.setheading(120)

motion()

turtle.exitonclick()