我正在使用graphics.py库生成从屏幕顶部掉落的多个球的模拟。球应该从底部“反弹”然后恢复下降。球落下的速度取决于球的大小。
目前该程序以适当的速率生成和丢弃球,但当它们“反弹”时,无限期地继续向上而不是再次下降。
非常感谢任何想法。
代码如下:
from graphics import *
from random import randint, choice
from time import sleep
# Generate a graphics window and set the 0,0 to the lower left corner.
win= GraphWin("Falling Bubbles!",600,600)
win.setCoords(0,0,600,600)
cornerB1= Point(-100,-100)
cornerB2= Point(700,700)
Background= Rectangle(cornerB1, cornerB2) #Create a white background
Background.setFill('white')
Background.draw(win)
# Distance function and check function used to determine if two bubbles will be generated overlapping
def dist(p1, p2):
x1, y1 = p1.getX(), p1.getY()
x2, y2 = p2.getX(), p2.getY()
return ((x1-x2)**2+(y1-y2)**2)**.5
def check(center, radius, bubbles):
overlapping= False
bubble= [item[0] for item in bubbles]
for i in bubbles:
radiSum= radius + bubble[0].getRadius()
if (dist(center, bubble[0].getCenter())< radiSum):
overlapping= True
return overlapping
# This function defines between 3 and 6 Circle objects with a random radius between
# 10 and 35 pixels and stores them in a list with the format [bubble, dx, dy]
def makeBubbles():
bubbles = []
colors = ['red','blue','green','pink','yellow','cyan']
n= randint(3,6)
for i in range(n):
center = Point(randint(40,560),randint(540,560))
radius = randint(10,35)
while (check(center, radius, bubbles)):
center= Point(randint(40,560),randint(540,560))
newbubble = Circle(center,radius)
newbubble.setFill(choice(colors))
bubbles.append([newbubble,0,-.6])
return bubbles
# This function accepts the list of bubbles with their dx, dy values as a parameter
# The function increases the speed of all bubbles in the list with smaller
# bubbles should increasing proportionally faster than larger bubbles
# The function returns the moddified 'bubbles' list
def speed(bubbles):
for bubble in bubbles:
radius= bubble[0].getRadius()
if radius<=15:
bubble[2] -= 1.1
elif 16<=radius<=25:
bubble[2] -= 1.05
else:
bubble[2] -= 1.025
return bubbles
# This function accepts the list of bubbles with their dx, dy values as a parameter
# The function determines it the bubble is too close to the bottom border of the Graphics window
# reverses it’s dy value and simultaneously reduce it’s speed
# The function returns the moddified 'bubbles' list
def sink(bubbles):
for bubble in bubbles:
center = bubble[0].getCenter()
radius= bubble[0].getRadius()
y= center.getY()
if y+ bubble[2]< radius:
bubble[2] *= -.9
if bubble[2]>0:
bubble[2]*=.9
if .7<bubble[2]<-.7:
bubble[2]= 0
bubble[0].move(bubble[1], bubble[2])
time.sleep(.025)
# Main
def main():
bubbles= makeBubbles()
n= len(bubbles)
x= 0
for bubble in bubbles:
bubble[0].draw(win)
while True:
speed(bubbles)
sink(bubbles)
x+= 1
main()
EDIT1:新线添加球减速停止弹跳
EDIT2:跟进问题。在生成时,我需要生成的气泡完全不重叠。
EDIT3:添加代码以确定球是否重叠生成
答案 0 :(得分:0)
这是关于避免气泡重叠的后续问题的答案:
这是一个半伪代码方法,用于检查生成的中心和半径对是否与气泡列表中的另一个气泡重叠。请注意,它确实是伪代码,因为我不太了解python语法。另请注意,您需要实现一个dist函数,该函数接收两个Point对象并计算它们之间的距离。
def checkIfOverlapping(center, radius, bubbles):
overlapping = false;
for i in range(bubbles.length):
radiSum = radius + bubbles[i].radius
if (dist(center, bubbles[i].center) < radiSum):
overlapping = true
return overlapping
你可以通过将for循环转换为while循环来消除for循环完成的一些工作,并且如果确定重叠也是如此,则退出:
while (i < bubbles.length and !overlapping)
这是生成气泡时你的for循环现在的样子:
for i in range(n):
center = Point(randint(40,560),randint(540,560))
radius = randint(10,35)
while (checkIfOverlapping(center, radius, bubbles)):
center = Point(randint(40,560),randint(540,560))
newbubble = Circle(center,radius)
newbubble.setFill(choice(colors))
bubbles.append([newbubble,0,-.6])
循环现在重新生成中心点,直到气泡不与列表中当前的任何气泡重叠。您也可以考虑在while循环中重新生成半径,以防原始半径太大而不存在非重叠点。这可能导致无限循环。