Python模拟

时间:2016-07-19 23:21:08

标签: python graphics

我正在使用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:添加代码以确定球是否重叠生成

1 个答案:

答案 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循环中重新生成半径,以防原始半径太大而不存在非重叠点。这可能导致无限循环。