CSC111 Lab 8

From dftwiki3
Revision as of 14:27, 24 March 2010 by Thiebaut (talk | contribs) (Holes)
Jump to: navigation, search

This lab deals with the moving ball example we saw in class recently. Your work for today is to add new functionality similarly to the way we added functionality to the graphics example with buttons.

You should start the Mac in Mac OS mode for today (graphics is more easily done this way). Make sure you start the X11 utility first, then the Terminal window.



Fileicon-pdf.png
You may find the following document describing the different graphic objects introduce in the Zelle's textbook useful.


Moving Ball, Part 1

  • Create a program called movingBall.py, which contains the version we ended up in class yesterday. It is available here.
  • make sure the graphics.py library is in the same directory where your program is located.
  • Run the program and make sure it works.
  • Clean up the testing of x and y coordinates of the center, in the function simul(), so that it is simpler. Use AND or OR to simplify the testing.
  • Verify that your ball still moves well. You may increase the number of simulation steps in simul to make the simulation go longer.

Moving Balls, Part 2

  • Add an extra ball to the simulation. The result should be two balls moving around the box and bouncing off the sides.
  • You will need to create a new circle, say c2 in main(), and pass it to the simul() function as well. But make sure simul() contains only one for-loop. The same for-loop should move both balls around.
Your program will have a structure close to this one (but you may be inspired to organize your program differently):
#----------------------------------------------------------------
def simul( c1, dx1, dy1, c2, dx2, dy2 ):

    for step in range( 2000 ):
         ...
         ...
         ...
 
#----------------------------------------------------------------
def main():
    c1 = Circle( Point( ..., ... ), 15 )
    c2 = Circle( Point( ..., ... ), 15 )
    ...

    waitForClick( win, "Click to Start" )
    dx1 = ...     # some random number
    dy1 = ...     # some random number
    dx2 = ...     # some random number
    dy2 = ...     # some random number

    simul( c1, dx1, dy1, c2, dx2, dy2 )

    ...

Moving Balls in a List

  • Once the program of the previous section works, put the two balls in a list L.
  • Try to use for-loops as much as possible. Use the program we wrote in class with buttons for ways of using a list of graphic objects. The code of this program is shown below. In particular see if you can
    • create the circles in a for-loop and append them to the list
    • use a for-loop inside the for-step-in-range( 2000 ) statement.



# clickMe0.py
# A demo program that draws a button on the graphics window
# and waits for the user to click the mouse 10 times, counting
# and displaying the count at every tick. 
from graphics import *

def drawButton( win, x1, y1, w, h, label ):
    """draws a rectangle with the top-left corner at x1, y1,
    with width w and height h on the screen.  Puts the label
    in the middle of the rectangle"""
    r = Rectangle( Point( x1, y1 ),
                   Point( x1+w, y1+h ) )
    r.draw( win )
    r.setFill( "red" )
    t = Text( Point( x1 + w / 2, y1 + h / 2 ), label )
    t.draw( win )

def isInside( userPoint, x, y, w, h ):
    mx = userPoint.getX()
    my = userPoint.getY()
    if x <= mx <= x+w and y <= my <= y+h:
        return True
    else:
        return False

def main():
    """Opens a graphics window 300x300 and draws a button on
    it.  Then wait for the user to click the mouse 10 times
    before exiting"""
    W = 300
    H = 300
    win = GraphWin( "Click Me!", W, H )
    border = 10

    #--- draw the button ---
    L = [ [ border, border, 70, 20, "Button1" ],
          [ W-border-70, border,70, 20, "Button 2" ],
          [ W-border-70, H-border-20, 70, 20, "Button 3" ] ]

    for x, y, w, h, label in L:
        drawButton( win, x, y, w, h, label )

    #--- draw "click me!" in middle of screen ---
    t = Text( Point( W/2, H/2 ), "click me!" )
    t.draw( win )

    #--- get 10 mouse clicks and count them ---
    for i in range( 1000 ):
        userPoint = win.getMouse()
        count = 0
        for x, y, w, h, label in L:
            if isInside( userPoint, x, y, w, h ):
                count += 1
        if count!=0:
            t.setText( "Inside #" + str(i+1) )
        else:
            t.setText( "Outside #" + str(i+1) )

        
    #--- wait for  one more click and close up window---
    #win.getMouse()
    win.close()

main()



Adding more balls

  • If you get stuck on the previous part, you may want to take a look at this code for inspiration...
  • Make your program ask the user for the number of balls he/she wants to see move around the window.

Balls of different colors

  • The colors supported by the Zelle graphics library are listed in this document.
  • Figure out a way to make your program use different colors (at least 5) for the balls.
  • Make your program robust, so that if the user requests to have 10 balls, but you have defined only 5 colors, the program will rotate through the colors.
Hints: remember the modulo operator %! In particular, try this code in interactive python:
 >>> for i in range( 20 ):
 >>> ...    print i % 7

Holes

  • Go back to the original program with only 1 ball, and no list, no colors.
  • Add a 60x60 square somewhere in your window.
  • Modify your code so that when the ball falls completely in the square it stops.
  • Once your program works, modify the last version of your program, with lists and colors, and add the stopping hole to it.
Hints: Be careful that when you take a ball out of the list, like so:
c, dx, dy = L[i]
and you modify either dx, or dy, it will not modify the dx or dy that are in the list. Just the copy of them that you got out. You have to store c, dx, and dy back in the list to "remember" the changed quantities:
L[i] = [ c, dx, dy ]