python - 如何使对象在画布中相互反弹
问题描述
我试图让程序中的球相互弹跳,但没有奏效,而且大多数时候它只是出现故障。 这是我的主要源代码:
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)
解决方案
如果球的中心之间的距离小于它们的半径之和,则球会“弹跳”。
勾股定理说距离是 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)
编辑添加:
球碰撞时会发生什么取决于每个球的速度矢量和质量,并且可能是碰撞的偏移角......
以下是一些有效的在线示例:
Python(和 Matplotlib)球碰撞模拟
关于弹性碰撞的维基百科页面引用了这个页面
https://www.vobarian.com/collisions/index.html
其中包括讨论该理论的简短 PDF,以及模拟球碰撞的 Windows C++ 程序的源代码和二进制文件。
推荐阅读
- azure - Azure 复制数据无法从 http 服务器读取数据
- python - Python:TypeError:'float'对象不可迭代
- algorithm - 如何为 Graham Scan 生成最坏情况数据
- c++ - 如何在for循环中格式化输出
- python - 如何让用户在 Flask Web 应用程序中下载文件客户端?
- python - 在条形图(棒棒糖)的末尾添加数据标签
- reactjs - SPA 404 刷新:Heroku 上的 Go+React 应用程序
- javascript - 从异步函数中检索返回值
- reactjs - 如何只返回最后一个 api 请求(ReactJS)
- flutter - 收到错误“内部错误:解释器已关闭。” 调用 dispose() 释放内存后