【问题标题】:How to find is a canvas item is touching another canvas item, Tkinter如何找到一个画布项目正在触摸另一个画布项目,Tkinter
【发布时间】:2014-02-09 17:03:52
【问题描述】:

我有一个程序,用户可以控制一个块并通过管道导航,类似于游戏中的小鸟。我想知道 tkinter 是否有办法告诉我一个矩形是否接触或撞击另一个矩形。我知道画布有一个 find_overlapping 方法,但是当我在管道的矩形上使用 find_overlapping 时,它给了我管道的 ID!我想知道画布项目是否有办法知道另一个画布项目是否正在触摸它!

谢谢

这是我的代码:

from Tkinter import *
from random import *
root=Tk()
c=Canvas(root,width=600,height=600)
speed=20
num=1
first=True
b=0
pipes=[]
done=False
class Pipe():
    def __init__(self,canvas,pipes,length,width=75,color="Green",position=600,speed=5):
        self.speed=speed
        self.canvas=canvas
        self.length=length
        self.width=width
        self.color=color
        self.position=position
        self.current1=self.canvas.create_rectangle((self.position,0,self.position+self.width,self.length),outline=self.color,fill=self.color)
        self.current2=self.canvas.create_rectangle((self.position,600,self.position+self.width,self.length+150),outline=self.color,fill=self.color)
        self.pipes=pipes
        self.pipes.append(self.current1)
        self.pipes.append(self.current2)
    def move(self):
        global done
        if (len(self.canvas.find_overlapping(self.position,0,self.position+self.width,self.length))==1 and len(self.canvas.find_overlapping(self.position,600,self.position+self.width,self.length+150))==1) and not done:
            self.position-=3
            self.canvas.coords(self.current1,(self.position,0,self.position+self.width,self.length))
            self.canvas.coords(self.current2,(self.position,600,self.position+self.width,self.length+150))
            if self.position>-75:
                self.canvas.after(self.speed,self.move)
            else:
                self.pipes.remove(self.current1)
                self.pipes.remove(self.current2)
                self.canvas.delete(self.current1)
                self.canvas.delete(self.current2)
        else:
            print self.canvas.find_overlapping(self.position,0,self.position+self.width,self.length)
            print
            print self.canvas.find_overlapping(self.position,600,self.position+self.width,self.length+150)
            done=True
class Player():
    def __init__(self,canvas,x=150,y=300,size=40):
        self.size=size
        self.faller=True
        self.x=x
        self.y=y
        self.fell=5
        self.canvas=canvas
        #For now
        self.current=self.canvas.create_rectangle((self.x-20,self.y-20,self.x+20,self.y+20),tags="user",outline="Blue",fill="Blue")
        self.canvas.after(100,self.fall)
        self.canvas.bind("<1>",self.jump)
    def fall(self):
        global done
        if self.faller and not done:
            self.y+=self.fell
            self.fell*=1.001
            self.canvas.coords(self.current,(self.x-20,self.y-20,self.x+20,self.y+20))
            self.canvas.after(30,self.fall)
        elif done:
            a=600-self.y+20
            a/=50
            while self.y<580:
                self.y+=a
                self.canvas.coords(self.current,(self.x-20,self.y-20,self.x+20,self.y+20))

    def jump(self,e):
        if not done:
            self.faller=False
            for x in range(10):
                self.canvas.after(100,self.move)
            self.faller=True
            self.fell=5
    def move(self):
        self.y-=7.5
        self.canvas.coords(self.current,(self.x-20,self.y-20,self.x+20,self.y+20))
    def changey(self,a):
        self.y=a
def run():
    global b,first,done
    if not done:

        if first:
            b=randint(5,450)
            first=False
        else:
            if b<225:
                b=randint(5,b+225)
            if b>225:
                b=randint(b-225,450)
            else:
                b=randint(0,600)
        a=Pipe(c,pipes,b)
        a.move()
        c.after(2000,run)
    else:
        return
root.focus_set()
user=Player(c)
c.after(2000,run)
c.pack()
root.mainloop()

【问题讨论】:

    标签: python canvas tkinter flappy-bird-clone


    【解决方案1】:

    Canvas.find_overlapping 返回一个元组,其中包含 bbox 中所有形状的 id。如果只返回您的 id,可能是因为它是唯一的。

    您可以将它与其他形状的bbox 一起使用,例如:canvas.find_overlapping(*canvas.bbox(aShape))

    请注意,重叠适用于矩形,并且可能是错误的,例如在圆形上。

    【讨论】:

    • 不,但是当我使用它时,它会返回管道的 ID,因为管道完全在它的边界框中!
    • 确实,您正在测试碰撞的形状将在 find_overlapping 输出中,但元组中可能还有其他形状。因此,碰撞测试可以(正如您在示例中所做的那样)测试 find_overlapping 输出的长度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2012-10-24
    • 2010-09-11
    • 2014-02-11
    • 2015-08-12
    • 2020-04-12
    相关资源
    最近更新 更多