CSC111 carLab10.py

From dftwiki3
Jump to: navigation, search

--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()