''' Show a ball bouncing off the sides of the window. User always has mouse control over the direction and speed of the ball. ''' from graphics import * import time, random def bounceInBox(shape, dx, dy, xLow, xHigh, yLow, yHigh, win): ''' Animate a shape moving in jumps (dx, dy), bouncing when its center reaches the low and high x and y coordinates. The animation stops when the mouse is clicked, and the last mouse click is returned.''' delay = .001 win.clearLastMouse() #NEW pt = None #NEW while pt == None: #NEW shape.move(dx, dy) center = shape.getCenter() x = center.getX() y = center.getY() isInside = True #NEW if x < xLow or x > xHigh: dx = -dx isInside = False #NEW if y < yLow or y > yHigh: dy = -dy isInside = False #NEW time.sleep(delay) if isInside: # NEW don't mess with dx, dy when outside pt = win.getLastMouse() #NEW return pt #NEW def moveInBox(shape, stopHeight, xLow, xHigh, yLow, yHigh, win): #NEW '''Shape bounces in win so its center stays within the low and high x and y coordinates, and changes direction based on mouse clicks, terminating when there is a click above stopHeight.''' scale = 0.01 pt = shape.getCenter() # starts motionless while pt.getY() < stopHeight: (dx, dy) = getShift(shape.getCenter(), pt) pt = bounceInBox(shape, dx*scale, dy*scale, xLow, xHigh, yLow, yHigh, win) def makeDisk(center, radius, win): '''Return a red disk that is drawn in win with given center and radius.''' disk = Circle(center, radius) disk.setOutline("red") disk.setFill("red") disk.draw(win) return disk def getShift(point1, point2): '''Returns a tuple (dx, dy) which is the shift from point1 to point2.''' dx = point2.getX() - point1.getX() dy = point2.getY() - point1.getY() return (dx, dy) def bounceBall(): '''Make a ball bounce around the screen, and react to mouse clicks.''' winWidth = 290 winHeight = 290 win = GraphWin('Ball Bounce 3', winWidth, winHeight) win.setCoords(0,0,winWidth, winHeight) #NEW to mark and label the area where a click stops the program lineHeight = winHeight - 40 textHeight = winHeight - 20 Line(Point(0, lineHeight), Point(winWidth, lineHeight)).draw(win) prompt = 'Click above the line to stop\nor below to move toward the click.' Text(Point(winWidth/2, textHeight), prompt).draw(win) radius = 10 xLow = radius # center is separated from the wall by the radius at a bounce xHigh = winWidth - radius yLow = radius yHigh = lineHeight - radius #NEW lower top to bouncing limits center = Point(winWidth/2, lineHeight/2) ball = makeDisk(center, radius, win) moveInBox(ball, lineHeight, xLow, xHigh, yLow, yHigh, win) #NEW win.close() bounceBall()