简体   繁体   English

在 Python 乌龟游戏中检测碰撞

[英]Detecting collision in Python turtle game

I am trying to make a Python game where the red turtle chases the blue turtle.我正在尝试制作一个红海龟追逐蓝海龟的 Python 游戏。 When the red turtle catches the blue turtle, I want it to say 'COLLISION' on the screen but it is not working.当红海龟抓住蓝海龟时,我想让它在屏幕上说“碰撞”,但它不起作用。 When it collides, nothing happens and it gives me an error 'Turtle' object is not callable'.当它发生碰撞时,什么也没有发生,它给我一个错误“Turtle”对象不可调用。

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()

This code seems to be more wishful thinking than actual programming:这段代码似乎比实际编程更一厢情愿:

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!'

Turtles don't have a .rect() method.海龟没有.rect()方法。 You can't simply add a is_collided_with() method to an existing class with this def statement.您不能简单地使用此def语句向现有类添加is_collided_with()方法。 There are no run() and follow() functions.没有run()follow()函数。 This collision test would only be executed once when you need it after every motion.这个碰撞测试只会在你每次运动后需要的时候执行一次。 Let's try to salvage what we can and make this work:让我们尝试挽救我们所能做的事情并使其工作:

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()

I use 10 as a collision radius based on the size of a turtle cursor, you can adjust as you see fit.我使用 10 作为基于海龟光标大小的碰撞半径,您可以根据需要进行调整。 This code simply ends the game, with a message, when a collision occurs, you might want to do something more sophisticated.这段代码只是简单地结束游戏,并显示一条消息,当发生碰撞时,您可能想要做一些更复杂的事情。 You could consider making the collision logic its own function to use after each keystroke in case the runner accidentally rams the follower!您可以考虑使碰撞逻辑成为自己的函数,以便在每次击键后使用,以防跑步者不小心撞到跟随者!

We have a function for distance in Turtle, so let's say turtle1 is at x1, y1, and turtle2 is at x2, y2, then the distance will be calculated as the mathematical xy distance between those two points.我们在 Turtle 中有一个距离函数,所以假设turtle1 在x1, y1 处,而turtle2 在x2, y2 处,那么距离将计算为这两个点之间的数学xy 距离。

Now, let's say that turtle1 has a "radius" of r1, and turtle2 a radius of r2, we could check for a collision by chencking if the distance is less than the sum of these two radii.现在,假设turtle1的“半径”为r1,而turtle2的半径为r2,如果距离小于这两个半径的总和,我们可以通过检查来检查碰撞。

So I think it would suffice to check if (r1+r2)<=turtle1.distance(turtle2.pos())所以我认为检查是否 (r1+r2)<=turtle1.distance(turtle2.pos())就足够了

These radii could be set as this: turtle1.r=10, turtle2.r=5, or as global variables, r1=10, r2=5.这些半径可以设置为:turtle1.r=10,turtle2.r=5,或作为全局变量,r1=10,r2=5。 Remember the global keyword in the def's if the last option is applicable.如果最后一个选项适用,请记住 def 中的 global 关键字。

For checking collisions with a given turtle, turtle1, and a list of turtles, say turtles=[jim,ben,kate,jane], and all turtles have a field for radius, r, You could iterate over this list, to check if turtle1 collided with any of them:为了检查与给定海龟、海龟 1 和海龟列表的碰撞,假设海龟 =[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

Now to make a function of this last one:现在来制作最后一个的功能:

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

This will detect if turtle1 collided with any in the group, remove the turtle that turtle1 collided with, and add 1 to global points, and then, if needed, return True if collision occured, False otherwise.这将检测turtle1是否与组中的任何人发生碰撞,移除turtle1与之碰撞的海龟,并在全局点上加1,然后,如果需要,如果发生碰撞,则返回True,否则返回False。

This way the follower could try to overtake a group of turtles.通过这种方式,追随者可以尝试超越一群海龟。 Hope this can help somewhat.希望这可以有所帮助。

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

This is the easiest way I can think of.这是我能想到的最简单的方法。 Just use .pos() like this只需像这样使用 .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")
jonny = Turtle()
marie = Turtle()


if (jonny.distance(marie) < 15):
 print('Jonny punch marie')

如果turtle.pos() == turtle2.pos():

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM