'''Show a ball bouncing off the sides of the window.
User always has mouse control over the direction and speed of the ball.
Version where all conditions that change the direction of the shape
are handled inside one animation loop.'''
from graphics import *
import time, random
def moveInBox(shape, stopHeight, xLow, xHigh, yLow, yHigh, win):
''' Animate a shape moving toward any mouse click below stopHeight and
bouncing when its center reaches the low or high x or y coordinates.
The animation stops when the mouse is clicked at stopHeight or above.'''
scale = 0.01
delay = .001
dx = 0 #NEW dx and dy are no longer parameters
dy = 0 #NEW
win.clearLastMouse()
while True: #NEW exit loop at return statement
center = shape.getCenter()
x = center.getX()
y = center.getY()
isInside = True
if x < xLow or x > xHigh:
dx = -dx
isInside = False
if y < yLow or y > yHigh:
dy = -dy
isInside = False
if isInside:
pt = win.getLastMouse()
if pt != None: #NEW dealing with mouse click now here
if pt.getY() < stopHeight: # switch direction
(dx, dy) = getShift(center, pt)
(dx, dy) = (dx*scale, dy*scale)
win.clearLastMouse()
else: #NEW exit from depths of the loop
return #NEW
shape.move(dx, dy)
time.sleep(delay)
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)
lineHeight = winHeight - 40
textHeight = winHeight - 20
Line(Point(0, lineHeight), Point(winWidth, lineHeight)).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
center = Point(winWidth/2, lineHeight/2)
ball = makeDisk(center, radius, win)
prompt = 'Click above the line to stop\nor below to move toward the click.'
Text(Point(winWidth/2, textHeight), prompt).draw(win)
moveInBox(ball, lineHeight, xLow, xHigh, yLow, yHigh, win)
win.close()
bounceBall()