Python修改Turtle程序使其在命中时掉头

2024-09-28 21:50:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我创造了2只乌龟,它们一直在移动,直到其中一只撞到墙上,导致它们完全停止。在

我的问题是,当它撞到墙上/另一只乌龟时,它会转身而不是停下来继续前进?我对如何用1只海龟做这个有一个粗略的想法,但是每当我尝试用2只海龟时,它就是不起作用。在

import random
import turtle

def moveRandom(wn, t):
    coin = random.randrange(0,2)
    if coin == 0:
        t.left(90)
    else:
        t.right(90)

    t.forward(50)

def areColliding(t1, t2):
    if t1.distance(t2) < 2:
        return True
    else:
        return False

def isInScreen(w, t):
    leftBound = - w.window_width() / 2
    rightBound = w.window_width() / 2
    topBound = w.window_height() / 2
    bottomBound = -w.window_height() / 2

    turtleX = t.xcor()
    turtleY = t.ycor()

    stillIn = True
    if turtleX > rightBound or turtleX < leftBound:
        stillIn = False
    if turtleY > topBound or turtleY < bottomBound:
        stillIn = False
    return stillIn

t1 = turtle.Turtle()
t2 = turtle.Turtle()
wn = turtle.Screen()

t1.shape('turtle')
t2.shape('circle')

leftBound = -wn.window_width() / 2
rightBound = wn.window_width() / 2
topBound = wn.window_height() / 2
bottomBound = -wn.window_height() / 2

t1.up()
t1.goto(random.randrange(leftBound, rightBound),
        random.randrange(bottomBound, topBound))
t1.setheading(random.randrange(0, 360))
t1.down()

t2.up()
t2.goto(random.randrange(leftBound, rightBound),
        random.randrange(bottomBound, topBound))
t2.setheading(random.randrange(0, 360))
t2.down()


while isInScreen(wn, t1) and isInScreen(wn, t2):
    moveRandom(wn, t1)
    moveRandom(wn, t2)

wn.exitonclick()

Tags: ifrandomwindowwidtht1heightturtlerandrange
2条回答

实际上,您需要重新组织代码,以避免重复。在

import random
import turtle

让我们创造世界的特性

^{pr2}$

以及它的生物

t1 = turtle.Turtle()
t1.shape('turtle')
t2 = turtle.Turtle()
t2.shape('circle')

delta_move = 50

# Let us build a list so as to have all turtles in hands in one object
turtles = [
    t1,
    t2,
    #t3,
    #t4,
    #...
]

for t in turtles:
    t.speed(0) # To make turtles be faster (0 is the FASTEST SPEED)
    t.setheading(random.randrange(0, 360))
    # We do not need what follows anymore, since collisions
    #  will be managed thereafter
    ##t.goto(random.randrange(leftBound, rightBound),
    ##        random.randrange(bottomBound, topBound))

一些物理约束

def isCollidingOtherTurtle(t):
    # Let us define the reciprocity between turtles
    #  using the just-defined list "turtles" above
    other_turtles = [t_ for t_ in turtles if t_ is not t]
    # This python function called any,
    #  checks whether there is at least one 
    #   other turtle at a distance lower than 2.
    #    In this case, any(...) returns True
    return any([t.distance(ot) < 2\
                for ot in other_turtles])


def isInScreen(t):
    # There is no need to redefine the bounds
    #  since they already have a global scope 
    #   definition working in the local
    #    scope of this function 
    #     [see global versus local variables]
    ## leftBound   = - w.window_width() / 2
    ## rightBound  = w.window_width() / 2
    ## topBound    = w.window_height() / 2
    ## bottomBound = -w.window_height() / 2

    turtleX = t.xcor()
    turtleY = t.ycor()

    stillIn = True
    if turtleX > rightBound or turtleX < leftBound:
        stillIn = False
    if turtleY > topBound or turtleY < bottomBound:
        stillIn = False
    return stillIn

定义每个普通海龟的大脑

def getDirection():
    #return random.random()*360. - 180 # returns a float between -180 and 180
    return random.choice([-180,-90,0,90,180])

def moveRandom(t):
    # A generic turtle moves forward 
    #  if it is going to collide 
    #   with no other turtle
    if not isCollidingOtherTurtle(t):
        if isInScreen(t):        
            t.left(getDirection())    
            t.forward(delta_move)
        else:
            t.backward(delta_move)
    else:
        t.backward(delta_move)

让我们来定义如何使这个世界充满活力,并使之充满活力

def anim(delta_time=60):
    wn.tracer(0, 0)
    for t in turtles:
        moveRandom(t)
    wn.update()
    wn.ontimer(anim, delta_time) # delta_time is in milliseconds

anim()
turtle.mainloop()

这里有一个你的代码的重做,我相信它能满足你的需要。我的大多数其他更改都是对代码的简化。一个主要的改变是我抛出了移动海龟的while()循环,并将它们放在自己的计时器上:

import random
from turtle import Turtle, Screen

def moveRandom(wn, t):
    coin = random.randrange(0, 2)

    [t.left, t.right][coin](90)

    t.forward(50)

    if not isInScreen(t) or areColliding(t1, t2):
        t.undo()  # pretend it never happened
        t.left(180)  # turn around
        t.forward(50)  # go the other way

    wn.ontimer(lambda: moveRandom(wn, t), 100)

def areColliding(t1, t2):
    return t1.distance(t2) < 2

def isInScreen(t):
    turtleX, turtleY = t.position()

    return leftBound < turtleX < rightBound and bottomBound < turtleY < topBound

t1 = Turtle('turtle', visible=False)
t2 = Turtle('circle', visible=False)
wn = Screen()

leftBound, rightBound = -wn.window_width() // 2, wn.window_width() // 2
bottomBound, topBound = -wn.window_height() // 2, wn.window_height() // 2

t1.up()
t1.goto(random.randrange(leftBound, rightBound), random.randrange(bottomBound, topBound))
t1.setheading(random.randrange(0, 360))
t1.showturtle()
t1.down()

t2.up()
t2.goto(random.randrange(leftBound, rightBound), random.randrange(bottomBound, topBound))
t2.setheading(random.randrange(0, 360))
t2.showturtle()
t2.down()

moveRandom(wn, t1)
moveRandom(wn, t2)

wn.exitonclick()

为了处理这些碰撞,我调用了isInScreen(t)areColliding(t1, t2)中的moveRandom(wn, t)并简单地撤消移动,如果它导致了碰撞,则转向相反的方向移动。在

相关问题 更多 >