使用'if'语句检测两只海龟的碰撞

时间:2019-04-25 04:15:47

标签: python turtle-graphics

我正在尝试创建一个将乌龟限制在盒子里的游戏。球在盒子周围反弹,如果它与乌龟发生碰撞,或者如果乌龟碰到盒子的周围,则游戏结束。一个红色的点会在盒子中的任意位置生成,当海龟在该点上运行时,该点应该消失并在其他地方重新生成。但是,这有时仅适用。有时,即使乌龟离它不近,该点也会随机消失并在其他地方产生。我该如何解决?

from turtle import Screen, Turtle, mainloop

wn = Screen()
wn.bgcolor("light blue")



#CONTROLLABLE TURTLE
t = Turtle()
t.color('black')
t.pensize(10)
t.shape("turtle")
t.speed("fastest")
t.penup()
t.goto(-130,-200)
t.pendown()

global hit
global score
hit = False
score = 0

#MAKE SQUARE
for i in range(4):
    t.forward(400)
    t.left(90)


t.penup()
t.goto(50,0)
speed = 2
t.color("black")

#BALL
ball1 = turtle.Turtle()
ball1.color("blue")
ball1.speed(0)
ball1.penup()
ball1.shape("circle")




A = random.randint(30,60)
B = random.randint(120,150)
C = random.randint(210,240)
D = random.randint(300,330)
Directions = [A, B, C, D]
direct = random.choice(Directions)
def tDirection(direct):
  ball1.right(direct)
tDirection(direct)
angle = 90

#DOT TURTLE
dot = turtle.Turtle()
dot.color("black")
dot.speed(0)
dot.hideturtle()

def createDot():
    dotx = random.randint(-10,230)
    doty = random.randint(-160,200)
    dot.penup()
    dot.goto(dotx,doty)
    dot.pendown()
    dot.pensize(3)
    dot.fillcolor("Red")
    dot.begin_fill()
    dot.circle(7)
    dot.end_fill()

createDot()


#make score function

while True:
  if hit == False:

    #moving ball
    ty = ball1.ycor()
    tx = ball1.xcor()
    if ty < -183:
      angleCurr = ball1.heading()
      if(270>angleCurr>180):
        ball1.right(angle)
      else:
        ball1.left(angle)

      ball1.forward(2)
    elif ty > 185:
      angleCurr = ball1.heading()
      if(0<angleCurr<90):
        ball1.right(angle)
      else:
        ball1.left(angle)

      ball1.forward(2)
    elif tx < -115:
      angleCurr = ball1.heading()
      if(180<angleCurr<270):
        ball1.left(angle)
      else:
        ball1.right(angle)

      ball1.forward(2)
    elif tx > 251:
      angleCurr = ball1.heading()
      if(0<angleCurr<90):
        ball1.left(angle)
      else:
        ball1.right(angle)

    ball1.forward(9)  

    wn.onkey(lambda: t.setheading(180), 'Left')
    wn.onkey(lambda: t.setheading(0), 'Right')
    wn.onkey(lambda: t.setheading(90), 'Up')
    wn.onkey(lambda: t.setheading(270), 'Down')



    w = turtle.Turtle()
    w.hideturtle()
    w.penup()
    w.speed("fastest")

    def end():
      w.goto(-95,-20)
      w.pendown()
      w.write("GAME OVER", font=("Arial", 40, "normal")) 
      t.hideturtle()
      ball1.hideturtle() 
      dot.hideturtle()
      dot.clear()

    speed = 2

    def turtleMove():
        t.forward(speed)
        wn.ontimer(turtleMove, 10)
    dodx = dot.xcor()
    dody = dot.ycor()
    if abs(t.xcor() - dodx) < 5 and abs(t.ycor() == dody) < 5:
      hit = True
      dot.clear()
    elif abs(t.xcor() - tx) < 5 and abs(t.ycor() - ty) < 5:
      end()

    if t.xcor() > 253 or t.xcor() < -115 or t.ycor() > 185 or t.ycor() < -183:
      end()

    turtleMove()
    wn.mainloop()
    wn.listen()


  if hit == True:
    createDot()
    score+=1
    print(score)
    hit = False

2 个答案:

答案 0 :(得分:0)

我认为这可能只是一个错字:

if abs(t.xcor() - dodx) < 5 and abs(t.ycor() == dody) < 5:

您的碰撞检测正在与y坐标进行比较,而不是像对x坐标那样进行减法。

所以这应该解决它:

if abs(t.xcor() - dodx) < 5 and abs(t.ycor() - dody) < 5:

答案 1 :(得分:0)

我会避免这样的代码:

dodx = dot.xcor()
dody = dot.ycor()
if abs(t.xcor() - dodx) < 5 and abs(t.ycor() == dody) < 5:
    hit = True
    dot.clear()
elif abs(t.xcor() - tx) < 5 and abs(t.ycor() - ty) < 5:
    end()

相反,使用乌龟的distance()方法:

if t.distance(dot) < 5:
    hit = True
    dot.clear()
elif t.distance(ball1) < 5:
    end()
  

但是,这有时仅适用。有时点会随机   消失并在其他地方产卵,即使乌龟甚至不   靠近它。

您是否假装此代码可以运行?由于两个不同的import问题,它甚至没有启动。修复这些问题后,乌龟控件根本不起作用。而且球不会在盒子周围弹跳!

这似乎是从其他程序中借来的一些代码的随机集合,这些程序都是通过一厢情愿的方式进行修补的。根本行不通。

下面,我将您的代码分解并重新放回原处,以便它基本上可以运行。蓝色的球确实在盒子周围反弹。您可以使用箭头键移动乌龟;当海龟碰到它时,红点确实消失并重新出现在其他地方:

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

CURSOR_SIZE = 20

def tDirection(direct):
    ball.right(direct)

def turtleMove():
    turtle.forward(speed)
    screen.ontimer(turtleMove, 10)

def createDot():
    x, y = randint(CURSOR_SIZE - 200, 200 - CURSOR_SIZE), randint(CURSOR_SIZE - 200, 200 - CURSOR_SIZE)
    dot.goto(x, y)

def end():
    marker.write("GAME OVER", align='center', font=("Arial", 40, "normal"))

    turtle.hideturtle()
    ball.hideturtle()
    dot.hideturtle()

screen = Screen()
screen.bgcolor("light blue")

score = 0
speed = 2

# CONTROLLABLE TURTLE
turtle = Turtle("turtle")
turtle.color('black')
turtle.pensize(10)
turtle.speed("fastest")
turtle.penup()
turtle.goto(-200, -200)
turtle.pendown()

# MAKE SQUARE
for i in range(4):
    turtle.forward(400)
    turtle.left(90)

turtle.penup()
turtle.goto(50, 0)

# BALL
ball = Turtle("circle")
ball.color("blue")
ball.speed('fastest')
ball.penup()

A = randint(30, 60)
B = randint(120, 150)
C = randint(210, 240)
D = randint(300, 330)

directions = [A, B, C, D]
direct = choice(directions)

tDirection(direct)
angle = 90

# DOT TURTLE
dot = Turtle('circle')
dot.color("red")
dot.speed('fastest')
dot.pensize(3)
dot.penup()

createDot()

marker = Turtle(visible=False)
marker.penup()
marker.sety(-20)

screen.onkey(lambda: turtle.setheading(0), 'Right')
screen.onkey(lambda: turtle.setheading(90), 'Up')
screen.onkey(lambda: turtle.setheading(180), 'Left')
screen.onkey(lambda: turtle.setheading(270), 'Down')
screen.listen()

turtleMove()

while True:
    # moving ball
    tx, ty = ball.position()

    if ty < CURSOR_SIZE - 200:
        angleCurr = ball.heading()

        if 270 > angleCurr > 180:
            ball.right(angle)
        else:
            ball.left(angle)

        ball.forward(2)
    elif ty > 200 - CURSOR_SIZE:
        angleCurr = ball.heading()

        if 0 < angleCurr < 90:
            ball.right(angle)
        else:
            ball.left(angle)

        ball.forward(2)
    elif tx < CURSOR_SIZE - 200:
        angleCurr = ball.heading()

        if 180 < angleCurr < 270:
            ball.left(angle)
        else:
            ball.right(angle)

        ball.forward(2)
    elif tx > 200 - CURSOR_SIZE:
        angleCurr = ball.heading()

        if 0 < angleCurr < 90:
            ball.left(angle)
        else:
            ball.right(angle)

        ball.forward(2)

    ball.forward(9)

    if turtle.distance(dot) < CURSOR_SIZE/2:
        score += 1
        dot.hideturtle()
        createDot()
        dot.showturtle()
    elif turtle.distance(ball) < CURSOR_SIZE/2:
        end()

    if not CURSOR_SIZE - 200 < turtle.xcor() < 200 - CURSOR_SIZE or not CURSOR_SIZE - 200 < turtle.ycor() < 200 - CURSOR_SIZE:
        end()

screen.mainloop()

在寻求有关SO的帮助时,请诚实对待代码状态。

上面的代码不完整,仍有工作要做。例如。 while True:循环应转换为函数和ontimer()事件;分数需要显示;游戏应该重新启动。