CSC111 Blinking Light Example

From dftwiki3
Jump to: navigation, search

--D. Thiebaut 07:13, 8 December 2011 (EST)


# Blinking.py
# D. Thiebaut
# Graphic program that uses Zelle's graphics library
# Implements a class that represents a red blinking light
# every time it is "updated" in an animation loop, it
# increments a counter, and when the counter reaches a
# specified threshold, it changes state.  If it was ON
# it turns OFF, and if OFF, it turns ON.
#

from graphics import *
import random
import time

class BlinkingLight:
    """The blinking light contains a long vertical pole,
    a square box at the top, and a circle for the light.
    Methods supported:
        draw( win ): draws the whole light on the graphic
                     window
                     
        switchState(): changes from ON to OFF, or OFF to ON
        
        update():    update the internal counter and
                     decide when to change state.
    """
    
    def __init__( self, basePoint, w, h ):
        """builds the graphical obect.
        basePoint is a point on the ground, in the middle of the pole
        w is the width of the top box
        h is the height of the pole plus the box at top"""

        #--- save geometry of blinking light and pole ---
        self.basePoint = basePoint
        self.w = w
        self.h = h
        self.isOn = True

        #--- create the pole ---
        x = self.basePoint.getX()
        y = self.basePoint.getY()
        x1 = x - self.w/5
        x2 = x + self.w/5
        y1 = y - self.h
        y2 = y
        self.pole = Rectangle( Point( x1, y1), Point( x2, y2 ) )
        self.pole.setFill( "orange" )

        #--- create the top box ---
        x1 = x - self.w/2
        x2 = x + self.w/2
        y1 = y - self.h
        y2 = y - self.h + self.w
        self.top = Rectangle( Point( x1, y1), Point( x2, y2 ) )
        self.top.setFill( "orange" )

        #--- create the light in the top box ---
        xc = (x1+x2)/2
        yc = (y1+y2)/2
        radius = self.w * 4 / 5 / 2
        self.light = Circle( Point( xc, yc ), radius )

        if self.isOn:
            self.light.setFill( "red" )
        else:
            self.light.setFill( "black" )

        #--- initialize the counter to a random start ---   
        self.counter = random.randrange( 10 )
        
    def draw( self, win ):
        """draws the whole blinking light on the graphics window"""
        self.win = win
        self.pole.draw( win )
        self.top.draw( win )
        self.light.draw( win )

    def switchState( self ):
        """changes the state of the light to the opposite of what
        it currently is"""
        if self.isOn == True:
            self.isOn = False
            self.light.setFill( "black" )
            #print( "black" )
        else:
            self.isOn = True
            self.light.setFill( "red" )
            #print( "red" )
        
    def update( self ):
        """called once through the animation loop, every 10
        calls, changes the state of the light to the opposite"""
        self.counter = ( self.counter + 1 ) % 10
        if self.counter == 0:
            self.switchState()

            
def main():
    W = 600
    H = 400
    win = GraphWin( "Blinking Light", W, H )

    #--- create a blinking light ---
    blink1 = BlinkingLight( Point( W/3, H*4/5 ), 40, 200 )
    blink1.draw( win )
    
    #--- create a silly object that will move on the screen    ---
    #--- (this is important, as moving pixels in the animation ---
    #---  loop will slow down the animation enough to see the  ---
    #---  blinking of the light(s)                             ---
    r = Rectangle( Point( 10, 300 ), Point( 100, 350 ) )
    r.setFill( "yellow" )
    r.draw( win )
    dx = 5 # it's movement in the x direction

    #--- ANIMATION LOOP ---
    while True:
        #--- stop when user clicks window ---
        if win.checkMouse() != None:
            break

        #--- update blinking light(s) ---
        blink1.update()


        #--- move the rectangle ---
        if random.randrange( 100 ) < 20:
            dx = -dx
        r.move( dx, 0 )

        #--- slow down the loop ---
        time.sleep( 0.1 )
        
    win.close()

main()