CSC111 carLab10.py
--D. Thiebaut 13:45, 14 April 2010 (UTC)
# carLab10.py
# D. Thiebaut
# first program using a class to define
# a new graphic object: a wheel, which
# is made of 2 concentric circles. The class
# Wheel supports methods to initialize the
# graphics object, draw it on the window,
# and move it.
from graphics import *
import random
W = 400
H = 400
#----------------------------------------------------------------
class Wheel:
"""A class with two concentric circles"""
def __init__( self, center, r1, r2 ):
"""constructor"""
self.radius1 = min( r1, r2 )
self.radius2 = max( r1, r2 )
self.circ1 = Circle( center, self.radius1 )
self.circ2 = Circle( center, self.radius2 )
def draw( self, win ):
"""draws the wheel on the graphics window win"""
self.circ2.draw( win )
self.circ1.draw( win )
def move( self, dx, dy ):
self.circ1.move( dx, dy )
self.circ2.move( dx, dy )
def setFill( self, color1, color2 ):
self.circ1.setFill( color1 )
self.circ2.setFill( color2 )
def getRadius1( self ):
"""returns the smallest radius"""
return self.radius1
def getRadius2( self ):
"""returns the largest radius"""
return self.radius2
class Car:
def __init__( self, P1, P2, dx ):
pp1 = Point( min( P1.getX(), P2.getX() ), min( P1.getY(), P2.getY() ) )
pp2 = Point( max( P1.getX(), P2.getX() ), max( P1.getY(), P2.getY() ) )
pp3 = Point( (pp1.getX()+pp2.getX())/2, pp1.getY() )
pp4 = Point( pp3.getX(), pp1.getY()-30 )
pp5 = Point( (pp1.getX()+pp2.getX())/3, pp1.getY() )
pp6 = Point( (pp1.getX()+pp2.getX())*2/3, pp1.getY() )
self.body = Rectangle( pp1, pp2 )
P1 = pp1
P2 = pp2
w =abs( P2.getX()-P1.getX() )
h =abs( P2.getY()-P1.getY() )
center1 = Point( w/4+P1.getX(), P2.getY() )
center2 = Point( P2.getX()-w/4, P2.getY() )
r2 = w/8
r1 = r2/2
self.w1 = Wheel( center1, r1, r2 )
self.w2 = Wheel( center2, r1, r2 )
if dx < 0:
self.shield = Polygon( pp1, pp3, pp4 )
else:
self.shield = Polygon( Point( pp2.getX(), pp1.getY() ), pp3, pp4 )
self.door = Rectangle( pp5, center2 )
self.dx = dx
def setFill( self, bodyc, tirec, insidec ):
self.body.setFill( bodyc )
self.shield.setFill( "lightblue" )
self.door.setFill( bodyc )
self.w1.setFill( tirec, insidec )
self.w2.setFill( tirec, insidec )
def draw( self, win ):
self.body.draw( win )
self.door.draw( win )
self.shield.draw( win )
self.w1.draw( win )
self.w2.draw( win )
def move( self, dx, dy):
self.body.move( self.dx, 0 )
self.shield.move( self.dx, 0 )
self.door.move( self.dx, 0 )
self.w1.move( self.dx, 0 )
self.w2.move( self.dx, 0 )
def IsOutside(self, W, H):
P1 = self.body.getP1()
P2 = self.body.getP2()
leftX = P1.getX()
rightX = P2.getX()
if leftX > W or rightX < 0:
return True
return False
#----------------------------------------------------------------
def waitForClick( win, message ):
""" waitForClick: stops the GUI and displays a message.
Returns when the user clicks the window. The message is erased."""
# wait for user to click mouse to start
startMsg = Text( Point( win.getWidth()/2, win.getHeight()/2 ), message )
startMsg.draw( win ) # display message
win.getMouse() # wait
startMsg.undraw() # erase
def main():
"""demo program for wheel: draws wheel on screen"""
global W, H
win = GraphWin( "wheel demo", W, H )
waitForClick( win, "click to start" )
List = []
for i in range( 3 ):
car = Car( Point( 120, 60+i*50 ), Point( 20, 20+i*50 ), 3-random.randrange( 6 ) )
car.setFill( "red", "yellow", "black" )
car.draw( win )
List.append( car )
waitForClick( win, "click to move" )
#--- move the cars ---
while True:
outsideCount = 0
for car in List:
car.move( 3, 0 )
if car.IsOutside(W, H):
outsideCount += 1
if outsideCount >= len(List):
break
waitForClick( win, "click to end" )
#main()