CS21 Lab5: Objects and Graphics

Due Saturday (October 17) before midnight

Note about the due date: The due date for this lab is set to be the Saturday after break. However, this lab is no longer than any other lab you've had this semester. We are giving you the extra week to complete the lab in case you'd prefer to use your break to work on this instead of completing it before break. A few important caveats:

  1. It may be difficult or impossible to use the graphics library remotely. If you are not on campus, we strongly recommend that you complete the lab before you leave.
  2. Professors may not answer emails in a timely manner over break. If you anticipate needing help from a professor, you are advised to complete the lab before break begins.

Lab description

This lab assignment requires you to write three programs in Python. First, run update21. This will create the cs21/labs/05 directory and copy over any starting-point files for your programs. Next, move into your cs21/labs/05 directory and begin working on the Python programs for this lab. The pwd command helps you verify that you are in the correct sub-directory.

$ update21
$ cd cs21/labs/05
$ pwd
We will only grade files submitted by handin21 in this directory, so make sure your programs are in this directory!

Programming tips

As you write your first programs, start using good programming practices now:

Zelle Graphics Reference

1. Shadow Boxer
Write a program shadowText.py that creates multiple drop shadows of a text object.

Your program should contain at least two helper functions in addition to main(). The first function make_text(msg, center, size, color) should make a new Text graphics object using the text provided in the string msg. Set the position, size, and color to the center, size, and color parameters, respectively. This function should not draw the text object in a graphics window, but instead should return the newly created text object.

The second function shadow_text(win, txt, num_shadows, dx, dy) should draw num_shadows copies of the Text object txt in the graphics window win. Each successive copy should get progressively darker until the final copy is colored black. Each copy should be translated by an amount (dx,dy) from the previous copy. Finally draw txt shifted by one more (dx,dy) from the final shadow copy.

Test your program by writing a small main function that creates at least three strings with different shadows. Prompt the user to click once to close the window. An example is shown below.

Shadow Text


2. Tiny Bubbles

Write a program bubbleGame.py that plays a basic interactive bubble game. Your game should create a set of circle objects representing bubbles or balls that slowly fall towards the bottom of the screen. When a user clicks on a bubble, it bounces up slightly. The user should try to keep all the bubbles on the screen. Once a bubble falls off the bottom of the screen, the game ends. Your program should print a game over message and wait for the user to click once more before closing the window and exiting the program.

Getting Started

The file bubbleGame.py has some functions implemented for you already. The function off_screen(circle) determines if a circle object has fallen off the bottom of the screen. You can use this function to help determine if the game is over.

The function inside(circ, pt) returns True if the Point object pt is inside the Circle object circ. You can use this to determine if you should bounce a particular circle up during gameplay.

You should start your implementation by writing the make_circles(win, num) function. This function should generate, but not draw, num Circle objects in the top half of the graphics window. Each circle you create should be appended to a list using the append method. You can choose the colors and size of the circles. The initial center of the circle should be chosen randomly, but each circle should have a center in the top half of the graphics window and not be too close to the left or right side of the window. Your function must return a list of num circle objects.

Test make_circles by writing code in main() to draw all the circles on the screen. Once this feature is working, proceed to animating your circles.

Animating Circles

Use the sleep() and move_circles(circs, amt) functions in a loop to move the circles down towards the bottom of the screen. Adjust amt and the sleep time to make the animation smooth. When the center of one circle has fallen off the bottom of the screen, end the animation. Your program should print a Game Over message and wait for a user click to quit the program.

Interactive Gameplay

To make your game interactive, you need to respond to mouse clicks. The getMouse() method pauses the program until the user clicks, but since we want the bubbles to fall when the user is not clicking, we cannot use this method. Instead we will use the checkMouse() method in the GraphWin class. The method checkMouse() returns a Point object if the user has recently clicked. Otherwise, the method returns a special value None. You can use this method as follows.

click = win.checkMouse()
if click:
  #user clicked recently, click now stores the Point they clicked
Add code using the checkMouse method to your game loop that bounces up any bubbles that intersect the mouse click. Adjust the amount of the bounce to make the game playable. This amount will likely be considerably larger than the amount each bubble falls during each time step.

An example of the complete game is shown in the video below:

3. Fake Plastic Trees
Write a program trees.py that interactively draws a set of trees on a landscape given a series of user clicks.


Getting started

The starter code provided draws a blank canvas containing only a blue sky. Begin by implementing the draw_ground and make_sun functions to draw a lawn and sun on the graphics window. Your make_sun object must return a Circle object.

Test these functions by choosing a ground and sun location of your choosing in main() and drawing the basic scene.

Write a loop that repeatedly gets clicks from the user until the user clicks on the sun, at which point the program exits.

Draw Tree

Implement the function draw_tree to draw a tree inside a box defined by two opposite corners p1 and p2. This function is a bit easier to implement if you begin with two points ll and ur describing the lower left and upper right corners of the box, respectively. The lower left has the smallest x and y coordinates of the box and the upper right has the largest x and y coordinates of the box. The helper functions get_lower_left(p1, p2) and get_upper_right(p1,p2) computes these two corners. You should use ll and ur to determine the coordinates of your tree.

Your tree must have a trunk and a canopy. The canopy should touch the top, left, and right sides of the bounding box. The trunk should touch the bottom of the box. Additionally, the trunk should touch the ground. If the lower left point of the box is greater than the ground height, lower this corner of the box to be the height of the ground. Trees should not float in the air.

Modify your main() function so that every pair of mouse clicks creates a new tree object. Your program should still exit if the user clicks the sun.

An interactive session is shown below. In this demo, the user clicks p1 and p2, and they are shown as red and green points, respectively. The computed lower left and upper right points are shown in white and black. An outline of the bounding box is also shown. You do not need to draw these points, or boxes, but they are shown to help show how the trees fit the box. Note on the last tree, the lower left corner is extended to the top of the ground.


Remember you may run handin21 as many times as you like. Each time you run it new versions of your files will be submitted. Running handin21 after you finish a program, after any major changes are made, and at the end of the day (before you log out) is a good habit to get into.