【发布时间】:2013-09-02 20:57:46
【问题描述】:
我试图让画布上的球对象发生碰撞并适当移动。我有一些额外的运动变量对我的问题并不重要,但我想让它们保持原样。我的球:
class Ball(Coords):
def __init__(self,canvas,color,drawX1,drawY1,drawX2,drawY2,startX,startY,moveX,moveY):
self.canvas = canvas
self.drawX1 = drawX1
self.drawY1 = drawY1
self.drawX2 = drawX2
self.drawY2 = drawY2
self.startX = startX
self.startY = startY
self.moveX = moveX
self.moveY = moveY
self.id = canvas.create_oval(drawX1,drawY1,drawX2,drawY2, fill=color)
self.canvas.move(self.id,self.startX,self.startY)
def draw(self,ran1,ran2):
self.ran1 = ran1
self.ran2 = ran2
ranspeed = random.randint(ran1,ran2)
pos = self.canvas.coords(self.id)
self.canvas_height = self.canvas.winfo_height()
self.canvas_width = self.canvas.winfo_width()
self.canvas.move(self.id,self.moveX,self.moveY)
ball 的 init 中的变量只是让我改变了球的各种属性,而在 draw 中我将速度设置为一个随机的 int 范围,因为我喜欢这样。
我决定使用 tkinter 获取重叠函数来获取球的项目 ID,这样我就可以使碰撞对象独立。我的问题是结果是一个元组,我不能用它来提取项目 ID 以便对其执行一些移动操作。我的碰撞检查代码在 draw 函数内部,如下所示:
pos = self.canvas.coords(self.id)
inside = canvas.find_overlapping(pos[0],pos[1],pos[2],pos[3])
if pos[0] <= 0:
self.moveX = ranspeed
if pos[1] <= 0:
self.moveY = ranspeed
if pos[2] >= self.canvas_width:
self.moveX = ranspeed*-1
if pos[3] >= self.canvas_height:
self.moveY = ranspeed*-1
还要注意,元组也返回 self.id 因为它本身,所以我排除了第一个元组索引:
idcolliders = inside[1:]
当我打印 idcolliders 时,我收到了 ballobject one 的元组流 - 最后一个,包含当前在其坐标内的所有 id。 有没有办法从这个元组中获取一个 ID 结果并将其放入一个函数中以在它存在时对其进行更改(特别是移动它),而不是在它不存在时抛出错误?
【问题讨论】:
-
虽然我确信你可以用 tkinter 做到这一点,但我可以建议你改用 pygame 吗?我认为即使您可能需要学习一个全新的模块,您也可能会更轻松(至少从长远来看)。 Pygame 具有处理碰撞检测的内置类和函数,最终可能会比使用 tkinter 画布快得多。祝你好运
-
是的,学习一个新模块会很耗时,但更重要的是,我不知道 pygame 是否会为这个程序做我想要的。我仍然需要能够以数字方式合成“球”,这在使用 .png 或 .bmp 时很难做到。有没有办法将 pygame 与 tkinters 画布接口?
-
我怀疑是否可以将它们连接在一起,但您的算法可能很容易适应 pygame。图形需要从图像文件中导入,你可以在 pygame 中使用 pygames
draw方法绘制东西。 pygame.org/docs/ref/draw.html -
谢谢,是的,它确实工作得很好,但也不是没有问题。 :D
-
啊,很高兴能帮上忙。祝你好运!
标签: python tkinter tuples collision-detection collision