CSC111 Lab 7 2015
--D. Thiebaut (talk) 11:09, 8 March 2015 (EDT)
In this lab you will play with a graphics library. A graphic library typically allows the user to draw simple shapes on the screen. You will also write some boolean functions that will help you control the dynamic movement of objects on the screen. The lab is different from the previous labs, as you must demonstrate that you have finished and implemented the different challenges before being allowed to submit your program on Moodle. When your programs for the challenges work, demonstrate your solutions to the lab instructor (or the TA), who will instruct you about the Moodle submission.
Setup for Graphics
Step 1: Download the graphics.py Library
- Copy/Paste the code from this page to Idle and save it in the directory where you will save your programs for Week 7, under the name graphics.py.
Step 2: Testing your installation
- With graphics.py in your Idle window, simply click run to run the library. Normally libraries are not run by themselves, but this library has its own test program to help users verify that the library is working properly.
- If everything goes well, you should see this simple window appear on your screen:
- Click a few times on the window and verify that the window responds by changing the color or size of various graphic objects.
Graphics programs have to be run from Idle to work correctly, and need the graphics.py library distributed by Zelle, the author of our textbook.
Step 3: A simple Graphics Program
- Create a new program and call it lab7.py.
- Important: save your program in the same directory/folder where you saved the graphics.py library.
- Copy the code below in it.
# lab7.py # your name # draws a circle in a window that is 600x400. from graphics import * def main(): win = GraphWin("My Circle", 600, 400) c = Circle(Point(50,50), 10) c.draw(win) win.getMouse() # Pause to view result win.close() # Close window when done main()
- Run the program. Verify that you see a single circle in the graphic window.
- Click with the mouse on the graphics window to close it.
Step 4: Explanations
- Observe the program from Step 3 above and recognize the main features:
- First we open a new graphic window on our desktop with the win = GraphWin( ... ) statement. 600 and 400 define how wide and high the window will be. "My Circle" is the title that will appear at the top of the window.
- Next, we create a circle object with the statement c = Circle( Point(50,50), 10 ). This does not draw the circle. It simply creates one in memory, centered on the point of coordinates 50, 10, with a radius of 10.
- Once the circle is created in memory, we make it appear on the graphic window with c.draw( win ).
- Finally, we wait for the user to click on the graphic window, and then close the window.
Step 5: Modifications
- Modify your program, using the code shown below:
# lab7.py # your name # Uses graphics.py from Zelle # # This program displays a red circle, a label # and a rectangle. from graphics import * def main(): #open the graphic window. win = GraphWin( "Lab 7 Demo", 600, 400 ) # create and draw a red circle center = Point( 100, 100 ) circ = Circle( center, 30 ) circ.setFill( 'red' ) circ.draw( win ) # add a label inside the circle label = Text( center, "red circle" ) label.draw( win ) # create and draw a rectangle rect = Rectangle( Point( 30, 30 ), Point( 70, 70 ) ) rect.draw( win ) win.getMouse() # Pause to view result win.close() # Close window when done main()
- Using this new bit of knowledge of graphic commands, could you generate the figure below? Note that the graphics system used here can recognize many different colors, all defined by strings, such as 'red' used above. You can find all the available colors on this page.
Moving a Ball on the Graphic Window
- Create a new program similar to the one covered in Monday's lecture.
# Uses graphics.py from Zelle # # This program displays the basic elements of a program # from graphics import * def main(): win = GraphWin( "Lab 7 Moving ball", 600, 400 ) # create and draw a red circle center = Point( 100, 100 ) circ = Circle( center, 30 ) circ.setFill( 'red' ) circ.draw( win ) # define the direction the circle will start moving in. # 5 pixels to the right every move, and 0.25 pixels down # every move. dx = 5 dy = 0.25 # as long as the mouse hasn't been clicked on the window # keep on looping. while win.checkMouse() == None: # move the circle in the current direction. circ.move( dx, dy ) # get the x and y of the center of the circle. x = circ.getCenter().getX() y = circ.getCenter().getY() # if the center is outside the right or left boundary, # reverse the x direction of movement. if x > 600 or x < 0: dx = -dx # if we're here, it's because the the user clicked on the graphic window. # we can close everything and quit. win.close() main()
- Run the program. Verify that the circle/ball bounces off the left and right boundaries of the window, but disappears down the bottom of the screen.
- You can stop the program by clicking on the graphic window a couple of times.
Challenge 1 |
- Modify your program so that it makes the ball bounce off the bottom and top boundaries of the windows.
Challenge 2 |
- Modify your program so that the ball bounces when its side (and not its center) touches the "walls" of the graphics window.
Adding an Obstacle
- Add a rectangle in the middle of the graphic window. You should declare it at the beginning of your main() function, as illustrated here:
def main(): win = GraphWin( "Lab 7 Moving ball", 600, 400 ) # create a green obstacle in the middle of the window x1 = 200 y1 = 200 x2 = 250 y2 = 250 obstacle1 = Rectangle( Point( x1, y1 ), Point( x2, y2 ) ) obstacle1.setFill( "green" ) obstacle1.draw( win ) # the remaining part of your code follows below...
Challenge 3 |
- Make your ball stop when its center enters the green rectangle. The image below illustrates this situation.
Challenge 4 |
- Modify your program one more time, and this time the ball will bounce off the obstacle. When you detect that the center of the ball is inside the green rectangle, change dx and dy to their opposite.
if ... : dx = -dx dy = -dy
Adding a Second Obstacle
- Add a second rectangle in the right side of the graphic window. You should declare it at the beginning of your main() function, as illustrated here:
def main(): win = GraphWin( "Lab 7 Moving ball", 600, 400 ) # create a green obstacle in the middle of the window x1 = 200 y1 = 200 x2 = 250 y2 = 250 obstacle1 = Rectangle( Point( x1, y1 ), Point( x2, y2 ) ) obstacle1.setFill( "green" ) obstacle1.draw( win ) # create another green rectangle on the right of the first one x3 = 350 y3 = 200 x4 = 400 y4 = 200 obstacle2 = Rectangle( Point( x3, y3 ), Point( x4, y4 ) ) obstacle2.setFill( "green" ) obstacle2.draw( win ) # the remaining part of your code follows below...
Challenge 5 |
- Make your ball stop when its center is fully inside the first green obstacle, and bounce off the magenta obstacle. For this challenge, simply make the ball bounce off the second obstacle when its center enters the obstacle.
- If you find that the ball never gets to hit both boxes, you may want to change the initial direction and add decimal digits to the dx and dy to create an angle that may not create path that repeat back and forth in the forward or backward direction without hitting the obstacles. For example:
dx = 5.105 dy = 2.511
Note: A ball with initial position 100, 100, and an initial direction defined by dx = 5.111, and dy = -2.51 manages to stop of Ostacle1.
Using Boolean Functions
isInside()
- Add the code of the function isInside(), shown below, to your last program, above the main() function.
# ifInside: returns true of the coordinates of a point defined by # its coordinates ballX and ballY, are inside the rectangle defined by a top # left point of coordinates obsX1, obsY1, and a bottom-right point # with coordinates obsX2, obsY2. Returns false if the point is outside # the rectangle. def isInside( ballX, ballY, obsX1, obsY1, obsX2, obsY2 ): if obsX1 < ballX < obsX2 and obsY1 < ballY < obsY2: return True else: return False
- Modify the code inside the while loop in your main function, so that it uses the isInside() function to detect contact with Obstacle1 and with Obstacle2.
- Here's what your code should look like (you will have to pass the appropriate parameters to the function):
# if the center of the ball is inside the first obstacle, stop # the ball. if isInside( ... ) == True: dx = 0 dy = 0 # if the center of the ball is inside the second obstacle, bounce # off if isInside( ... ) == True: dx = -dx dy = -dy
IsLeftSide() Boolean Function
- Add a new boolean function to your program called isLeftSide(). This function receives 3 parameters, in this order:
- an x coordinate
- a y coordinate
- the width of the window.
- and it returns true if the point (x, y) is on the left side of the window, and false if the point (x, y) is on the right side of the window. This function basically compares the x coordinate to the midpoint on the x axis of the window.
- Use your new function to color the ball rid when it is moving on the left side of the window, and yellow when it is moving on the right side of the window. Example:
if isLeftSide( x, y, win.getWidth() ) == True: circ.setFill( 'red' ) else: circ.setFill( 'yellow' )
isUpperHalf Boolean Function
- Comment out or remove the previous if statement that changes the color of the ball, so that it won't interfere with the code you are about to write.
- Create a new boolean function called isUpperHalf(), that takes 3 parameters, the first two being the coordinates of a point, the third one the height of the window, and that returns true if the point is in the top half of the screen, an false otherwise.
- Use your new function to control the color of the ball as it moves around the window. The ball should be 'blue' when it is in the upper half of the screen, and 'brown' when it is in the lower half.