我的画布上有一个网格,在某些单元格中有圆圈。我的目标是在网格周围移动圆圈,但不在另一个圆圈上移动圆圈。因此,当我移动圆圈时,我会检查是否有东西在路上,如果是的话,取消移动。首先,我试图在运动结束时检查碰撞,但我无法让它发挥作用。所以我试图在移动时检查,但我意识到画布线也是对象,因此存在碰撞。 是否有任何“简单”的方法可以忽略这些线条碰撞而不是圆圈碰撞?
class Deplacement:
def __init__(self, canvas, event):
self.x = event.x
self.y = event.y
self.canvas = canvas
self.obj = "à déterminer"
self.obj2 = "à déterminer"
self.couleur = "à déterminer"
self.couleur2 = "à déterminer"
self.collision = "à déterminer"
canvas.bind("<ButtonPress-1>", self.StartMove)
canvas.bind("B1-Motion", self.OnMotion)
canvas.bind("<ButtonRelease-1>", self.StopMove)
def StartMove(self, event): #Getting the object I want to move
self.x = event.x
self.y = event.y
self.obj = self.canvas.find_overlapping(self.x - 15, self.y - 15, self.x + 15, self.y + 15)
def OnMotion(self, event): #This is where I struggle
#Trying to get the second circle if it exists
self.obj2 = self.canvas.find_overlapping(event.x - 15, event.y - 15, event.x + 15, event.y + 15)
if not self.obj2:
self.collision = False
else:
self.collision = True
def StopMove(self, event): #This works fine, in context, checking items colors to move them or not
#And objects must be moved by one axis
self.couleur = self.canvas.itemcget(self.obj, "fill")
if not self.collision:
if self.couleur == 'black' or self.couleur == 'white' or self.couleur == 'red':
if event.x > self.x and self.y - 10 <= event.y <= self.y + 10:
self.move(event, self.obj)
elif event.x < self.x and self.y - 10 <= event.y <= self.y + 10:
self.move(event, self.obj)
elif event.y > self.y and self.x - 10 <= event.x <= self.x + 10:
self.move(event, self.obj)
elif event.y < self.y and self.x - 10 <= event.x <= self.x + 10:
self.move(event, self.obj)
def move(self, event, obj): #Finally moving objects, works nicely aswell
self.x = (event.x - 20) // 50 + 1
self.y = (event.y - 20) // 50 + 1
self.obj = obj
if event.x < 20:
self.x = 1
self.canvas.coords(self.obj, self.x * 50 - 25, self.y * 50 - 25, self.x * 50 + 15, self.y * 50 + 15)
elif event.y < 20:
self.y = 1
self.canvas.coords(self.obj, self.x * 50 - 25, self.y * 50 - 25, self.x * 50 + 15, self.y * 50 + 15)
elif event.x > 470:
self.x = 9
self.canvas.coords(self.obj, self.x * 50 - 25, self.y * 50 - 25, self.x * 50 + 15, self.y * 50 + 15)
elif event.y > 470:
self.y = 9
self.canvas.coords(self.obj, self.x * 50 - 25, self.y * 50 - 25, self.x * 50 + 15, self.y * 50 + 15)
else:
self.canvas.coords(self.obj, self.x * 50 - 25, self.y * 50 - 25, self.x * 50 + 15, self.y * 50 + 15)
PS:忽略法语单词。
答案 0 :(得分:0)
我假设名为canvas
的变量是Tkinters&#39;的一个实例。画布类。您没有显示填充画布的代码,但我假设您使用canvas.create_line()
或canvas.create_oval()
等方法调用填充它。这些方法中的每一个都返回一个整数,该整数是创建的形状的ID。您必须做的是存储要忽略的形状的ID,换句话说,创建一组不应构成碰撞的形状ID。我们假设您将这些放入名为ignore_these
的集合中。
方法find_overlapping
返回与指定矩形重叠的形状元组。假设我们将此返回值称为possible_collisions
。所以要告诉你是否有碰撞,你只需要一行代码:
if any(s not in ignore_these for s in possible_collisions):
# handle the collision
else:
# go ahead and make the move
这是一个两步过程(创建一组非碰撞形状,然后用它来分析find_overlapping的结果)。你问了一个简单的方法,但我怀疑是否有办法避免这两个步骤; Tkinter至少为你提供了编写必要逻辑所需的钩子。
手动参考:http://effbot.org/tkinterbook/canvas.htm#Tkinter.Canvas
答案 1 :(得分:0)
在画布中添加项目时,使用的方法会返回这些对象的唯一ID(整数)。您必须将这些ID收集到一个集合中,并为碰撞的项目的ID提供额外的集合。 (您可以隔离不会发生碰撞的项目,但每次运行碰撞检测部件时都必须对其进行过滤)
这是伪代码:
def create_canvas_objects(self):
id = canvas.create_object()
self.all_canvas_objects_ids.append(id)
if object_collides:
self.colliding_objects.append(id)
def check_collisions(self):
for object in self.colliding_objects:
check the collision
这样,您只能在创建时过滤碰撞对象与非碰撞对象,而不是每帧都过滤。