【问题标题】:Detecting collision in Python turtle game在 Python 海龟游戏中检测碰撞
【发布时间】:2021-08-26 13:04:35
【问题描述】:

我正在尝试制作一个红海龟追逐蓝海龟的 Python 游戏。当红海龟抓住蓝海龟时,我想让它在屏幕上说“碰撞”,但它不起作用。当它发生碰撞时,什么也没有发生,它给了我一个错误'Turtle' object is not callable'。

from turtle import Turtle, Screen

playGround = Screen()

playGround.screensize(250, 250)
playGround.title("Turtle Keys")

run = Turtle("turtle")
run.speed("fastest")
run.color("blue")
run.penup()
run.setposition(250, 250)

follow = Turtle("turtle")
follow.speed("fastest")
follow.color("red")
follow.penup()
follow.setposition(-250, -250)

def k1():
    run.forward(45)

def k2():
    run.left(45)

def k3():
    run.right(45)

def k4():
    run.backward(45)

def quitThis():
    playGround.bye()

def follow_runner():
    follow.setheading(follow.towards(run))
    follow.forward(8)
    playGround.ontimer(follow_runner, 10)

playGround.onkey(k1, "Up")  # the up arrow key
playGround.onkey(k2, "Left")  # the left arrow key
playGround.onkey(k3, "Right")  # you get it!
playGround.onkey(k4, "Down")

playGround.listen()

follow_runner()

def is_collided_with(self, run):
    return self.rect.colliderect(run.rect)

runner = run(10, 10, 'my_run')
follower = follow(20, 10)
if follow.is_collided_with(run):
    print 'collision!'

 playGround.mainloop()

【问题讨论】:

  • 或许你可以尝试检查run的位置是否与follow匹配?
  • 我在那段代码中没有看到任何关于 pygame.如果你正在使用 pygame,为什么不使用它的 sprite 功能,让 pygame 检测碰撞?

标签: python python-3.x turtle-graphics


【解决方案1】:

这段代码似乎比实际编程还要一厢情愿:

def is_collided_with(self, run):
    return self.rect.colliderect(run.rect)

runner = run(10, 10, 'my_run')
follower = follow(20, 10)
if follow.is_collided_with(run):
    print 'collision!'

海龟没有.rect() 方法。您不能简单地使用此 def 语句将 is_collided_with() 方法添加到现有类。没有run()follow() 函数。此碰撞测试仅在每次运动后需要时执行一次。让我们尽我们所能挽救并完成这项工作:

from turtle import Turtle, Screen

playGround = Screen()

playGround.screensize(250, 250)
playGround.title("Turtle Keys")

run = Turtle("turtle")
run.color("blue")
run.penup()
run.setposition(250, 250)

follow = Turtle("turtle")
follow.color("red")
follow.penup()
follow.setposition(-250, -250)

def k1():
    run.forward(45)

def k2():
    run.left(45)

def k3():
    run.right(45)

def k4():
    run.backward(45)

def quitThis():
    playGround.bye()

def is_collided_with(a, b):
    return abs(a.xcor() - b.xcor()) < 10 and abs(a.ycor() - b.ycor()) < 10

def follow_runner():
    follow.setheading(follow.towards(run))
    follow.forward(min(follow.distance(run), 8))

    if is_collided_with(follow, run):
        print('Collision!')
        quitThis()
    else:
        playGround.ontimer(follow_runner, 10)

playGround.onkey(k1, "Up")  # the up arrow key
playGround.onkey(k2, "Left")  # the left arrow key
playGround.onkey(k3, "Right")  # you get it!
playGround.onkey(k4, "Down")

playGround.listen()

follow_runner()

playGround.mainloop()

我使用 10 作为基于海龟光标大小的碰撞半径,您可以根据需要进行调整。这段代码只是简单地结束游戏,并带有一条消息,当发生碰撞时,您可能想要做一些更复杂的事情。您可以考虑将碰撞逻辑设置为自己的函数,以便在每次击键后使用,以防跑步者不小心撞到追随者!

【讨论】:

    【解决方案2】:

    我们在 Turtle 中有一个距离函数,假设 turtle1 在 x1, y1,turtle2 在 x2, y2,那么距离将计算为这两个点之间的数学 xy 距离。

    现在,假设 turtle1 的“半径”为 r1,turtle2 的半径为 r2,如果距离小于这两个半径的总和,我们可以通过检查来检查碰撞。

    所以我认为检查就足够了 如果 (r1+r2)

    这些半径可以这样设置:turtle1.r=10, turtle2.r=5,或者作为全局变量,r1=10, r2=5。如果最后一个选项适用,请记住 def 中的 global 关键字。

    要检查与给定海龟、turtle1 和海龟列表的碰撞,例如 turtles=[jim,ben,kate,jane],并且所有海龟都有一个半径字段 r,您可以遍历此列表,检查turtle1是否与其中任何一个发生碰撞:

    collsion=False
    for turtle in turtles:
        if (turtle.r+turtle1.r)<=turtle1.distance(turtle.pos()):
            collision=True
            # turtle.reset() # removes the turtle
            # points+=1, or whatever
    

    现在来做最后一个的函数:

    def group_collide(t1,group):
        global points
        turtle1=t1
        collide=False
        for turtle in group:
            if (turtle.r+turtle1.r)<=turtle1.distance(turtle(pos)):
                collide=True
                turtle.reset()
                points+=1
       # if needed:
       return collide
    

    这将检测turtle1是否与组中的任何一个碰撞,删除turtle1碰撞的乌龟,并将全局点加1,然后如果需要,如果发生碰撞则返回True,否则返回False。

    这样,追随者可以尝试超越一群海龟。希望这能有所帮助。

    【讨论】:

      【解决方案3】:
      def isCollision(t1, t2):
          d = math.sqrt(math.pow(t1.xcor()-t2.xcor(),2) + math.pow(t1.ycor()-t2.ycor(),2))
          if d < 20:
              return True
          else:
              return False
      

      【讨论】:

      • 为什么不简单:return t1.distance(t2) &lt; 20
      【解决方案4】:

      这是我能想到的最简单的方法。像这样使用 .pos()

      from turtle import *
      
      import turtle
      
      screen = turtle.Screen()
      
      screen.setup(1920, 1080)
      
      blue = turtle.Turtle()
      
      blue.shape = ('turtle')
      
      blue.color = ('blue')
      
      
      red = turtle.Turtle()
      
      red.shape = ('turtle')
      
      red.color = ('red')
      
      
      
      collision = turtle.Turtle()
      
      collision.hideturtle()
      
      
      
      if blue.pos() == red.pos():
      
          collision.goto(0,0)
      
          collision.showturtle()
      
          collision.write("COLLISION")
      

      【讨论】:

      • 海龟在浮点平面上游荡,所以 blue.pos() == red.pos() 作为一种策略最终会让你失败。 (请参阅turtle.distance() 以获得更好的方法。)您也不需要在write() 之前执行showturtle()
      【解决方案5】:
      jonny = Turtle()
      marie = Turtle()
      
      
      if (jonny.distance(marie) < 15):
       print('Jonny punch marie')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多