首页 > 解决方案 > 如何使对象在画布中相互反弹

问题描述

我试图让程序中的球相互弹跳,但没有奏效,而且大多数时候它只是出现故障。 这是我的主要源代码:

from tkinter import *
from Ball import *
import time
HEIGHT = 500
WIDTH = 500
window = Tk()


canvas = Canvas(window,height=HEIGHT,width = WIDTH)
canvas.pack()
basket_ball = Ball(canvas,0,0,100,1,1,"orange")
soccer_ball = Ball(canvas,399,399,499,1,1,"black")

while True:
    basket_ball_coords = canvas.coords(basket_ball.image)
    soccer_ball_coords = canvas.coords(soccer_ball.image)
    basket_ball.move()
    soccer_ball.move()
    print (basket_ball_coords)
    print (soccer_ball_coords)
    if basket_ball_coords[2] == soccer_ball_coords[0] and ((soccer_ball_coords[3] - basket_ball_coords[3])<= 100 and (soccer_ball_coords[3] - basket_ball_coords[3])> -101):
        basket_ball.xVelo = -basket_ball.xVelo
        soccer_ball.xVelo = -soccer_ball.xVelo
    if basket_ball_coords[3] == soccer_ball_coords[1] and ((soccer_ball_coords[2]- basket_ball_coords[2]<=100)and (soccer_ball_coords[2] - basket_ball_coords[2])> -101):
        basket_ball.yVelo = -basket_ball.yVelo
        soccer_ball.yVelo = -soccer_ball.yVelo
    if basket_ball_coords[0] == soccer_ball_coords[2] and ((soccer_ball_coords[3] - basket_ball_coords[3]) <= 100 and (soccer_ball_coords[3] - basket_ball_coords[3]) > -101):
        basket_ball.xVelo = -basket_ball.xVelo
        soccer_ball.xVelo = -soccer_ball.xVelo
    if basket_ball_coords[1] == soccer_ball_coords[3] and ((soccer_ball_coords[2]- basket_ball_coords[2]<=100)and (soccer_ball_coords[2] - basket_ball_coords[2])> -101):
        basket_ball.yVelo = -basket_ball.yVelo
        soccer_ball.yVelo = -soccer_ball.yVelo
    window.update()
    time.sleep(0.01)


window.mainloop()

这是我用来创建 Ball 对象的 Ball 类

class Ball:
    def __init__ (self,canvas,x,y,diameter,xVelo,yVelo,color):
        self.canvas = canvas
        self.image = canvas.create_oval(x,y,diameter,diameter,fill=color)
        self.xVelo = xVelo
        self.yVelo = yVelo
    def move(self):
        coordinates = self.canvas.coords(self.image)
        if (coordinates[2] >= self.canvas.winfo_width() or coordinates[0] < 0):
            self.xVelo = -self.xVelo
        if (coordinates[3] >= self.canvas.winfo_height() or coordinates[1] < 0):
            self.yVelo = -self.yVelo
        self.canvas.move(self.image,self.xVelo,self.yVelo)

标签: pythontkintertkinter-canvas

解决方案


如果球的中心之间的距离小于它们的半径之和,则球会“弹跳”。

勾股定理说距离是 x 和 y 增量平方和的平方根。

假设:

  • 通过的 x 和 y 是左上角 (?)
  • self.radius = 直径/2
  • self.center_x = x + self.radius
  • self.center_y = y + self.radius

添加到类球:

def intersects_ball(self, other):
    xdelta = self.center_x - other.center_x
    ydelta = self.center_y - other.center_y
    distance = math.sqrt(xdelta*xdelta + ydelta*ydelta)
    return distance < (self.radius + other.radius)

编辑添加:

球碰撞时会发生什么取决于每个球的速度矢量和质量,并且可能是碰撞的偏移角......

以下是一些有效的在线示例:


推荐阅读