This lab assignment requires you to write programs that use multiple functions.
As always, first run update21. This will create the
cs21/labs/06 directory and the starter programs.
Next, move into your cs21/labs/06 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/06
$ pwd
/home/your_user_name/cs21/labs/06
We will only grade files submitted by handin21
in this labs directory, so make sure
your programs are in this directory!
The usual set of rules before we start:
Please comment your code:
Your programs should start off with a header that states your name, the date, and what your program is supposed to be doing.
Inline comments: If there is something in your program that is hard to understand (for a third-party who knows Python but does not necessarily know what you are thinking), please comment and explain.
Use variable names that make sense. Please. No x and y. In general, somebody else should be able to know what your program is doing just by reading the code. The comments are supposed to be supplementary only.
Where possible, try not to use hard-coded values once the computation begins. Store your hard-coded values in variables at the start of your program, and use the variables instead. It makes it a lot easier to understand what you are doing.
Please follow the specifications that are given. If we say that we want a function with a particular name and that takes particular values, we mean it. Points will be taken off for not following specifications.
Coding with Functions
Our programs are starting to get bigger and resemble applications that you can actually use. However, in order to be able to write large programs effectively, we need to use functions to break up our code into more manageable chunks.
We start with what we'd like you to be able to accomplish for this assignment. Watch the following video. Turn on annotations to see the explanations.
High-level Specifications:
Basically, your job for this assignment is to write the above game. The rules are:
You start with one small balloon of radius 5 in a big window (size 1000x1000)
You can control the balloon using the arrow keys
Apart from the balloon, you have lots (I had 100 of them) of colored bubbles scattered around the screen. Each bubble should be of a random color. The radius of a bubble should be 10.
In addition, you also have some stars scattered around the screen. You make a star in exactly the same way as you did last week. I started with 5 stars.
Whenever your balloon collides with a bubble, the bubble gets "absorbed" into the balloon. In programming terms, your bubble should not appear in the window anymore. Your balloon should grow by a factor of 5 for each bubble absorbed. Your score goes up by 1 for each bubble absorbed
The objective of the game is to make your balloon absorb as many bubbles as possible. The score should be displayed in the window for the user
If your balloon collides with a star during the process of the game, that's game over.
Breaking things up into functions
This looks pretty daunting at a first glance, so we'll break it up into functions. You should have a starter program in your labs/06 subdirectory. Write the functions in the following order:
Step 1
Write the following functions:
def drawStar(centerPoint, size, color, window)
Accepts:
one Point object representing the center of the star
one int representing the size of the star
one string representing the color of the star
the window object
This is what you did last week! It draws a star at the specified location.
Returns the newly-drawn star.
def drawAllStars(window, numOfStars)
Accepts:
the window object
the number of stars to create.
Creates the specified number of stars (hint: call drawStar()) in the window.
Returns a list of the generated stars.
def drawAllBubbles(window, numOfBubbles)
Accepts:
the window object
the number of bubbles to create.
Creates the needed bubbles.
Returns a list of the generated bubbles.
Now that you have these functions, test them by writing programming statements in main() that creates
a window, and draws lots of different numbers of bubbles and stars in the window. Something like this:
Step 2
Add the following functions:
def steerBalloon(balloon, window, keypress)
Accepts:
The balloon object
The window object
The keypress from the user (from checkKey())
This function moves the balloon up, down, left or right depending on the key pressed by the user. It should also call keepBalloonInWindow() to make sure that the balloon stays within the window.
This function does not have a return value.
def keepBalloonInWindow(balloon, window)
Accepts:
The balloon object
The window object
This function checks whether the entirety of the balloon is inside the window. (The radius of the balloon and the position of the center will give you that information -- draw a figure and you'll see why.) If part of the balloon is outside of the window, it should move the balloon so that it's back within the window.
This function does not have a return value.
Once you are done with these, add some programming statements to main() that will:
Make a big balloon (make it big -- like 100 radius -- it'll be easier to test.)
Create a while (True) loop in which you call checkKey(), and use the result to steer your balloon around.
Make sure that steerBalloon() does its job. Pressing the "Up" arrow should move the balloon up, etc etc.
Make sure that keepBalloonInWindow() does its job and doesn't let the balloon exit the window!
Step 3
Add the following functions:
def getDistance(point1, point2)
Accepts:
Two Point objects
This function calculates the distance between two given Points. The distance between two points, (x1, y1) and (x2, y2) can be found using the Pythagoras Theorem:
Returns: a float with the distance.
def balloonBubbleCollide(balloon, bubble)
Accepts:
Two Circle objects (the balloon and the bubble).
Checks the distance between two Circle objects (Hint: use getDistance() to check the distance between the centers, and compare with the sum of the radii).
Returns: True if the circles overlap (or touch), False if not.
Checks whether the balloon has collided with any of the bubbles in the list.
This function checks whether any bubbles were just absorbed by the balloon (hint: call balloonBubbleCollide(). Bubbles that the balloon collides with should disappear from the window.
Returns an int specifying the number of bubbles that the balloon has collided with
Same as before, after you have implemented these functions, write some programming statements in main():
Call checkForBubblesAbsorbed() in the while (True) loop after checkKey(). This means that checkForBubblesAbsorbed() should be called everytime after one movement has been made in response to a user keypress.
Steer the balloon around and hit some bubbles, and see if they disappear. Do not worry about "growing" the balloon yet. If your balloon is clearly running into bubbles but they are not disappearing, print out the results calculated by getDistance() and balloonBubbleCollide(), and make sure that they make sense.
Step 4
We're almost done! Add the following functions:
def balloonStarCollide(balloon, star)
Accepts:
One Circle object (the balloon)
One Polygon object (the star)
Checks the distance between the Circle and the Polygon to see if they touch (or collide). (Hint: use getDistance() to get the distance between the center of the Circle and each of the vertices (the points) of the Polygon, and compare with the radius of the Circle.)
Returns: True if the circle and the polygon collide or touch, and False if they do not.
def checkForStarCollision(balloon, stars)
Accepts:
The balloon object
The list of stars
Checks whether the balloon has collided with any of the stars (hint: call balloonStarCollide()).
Returns True if the balloon has collided with any of the stars, False if not.
After writing these functions, add programming statements to main():
Call checkForStarCollision() after checkForBubblesAbsorbed() to see if the balloon hits a star. If the balloon has hit a star, you should just break out of the while (True) loop and end the game.
Step 5
Now we're entering the home stretch. Add programming code to main() to do the following:
Grow the balloon when it absorbs a bubble:
Get the return value from checkForBubblesAbsorbed() -- that gives you the number of bubbles
Get the current value of the balloon's radius
Calculate the new radius of the balloon = old_radius + number_of_bubbles * 5
Get the center point of the balloon
Make a new balloon with the new radius and with the old balloon's fill color
Undraw the old balloon
Draw the new balloon
Set the variable used by the old balloon to point to the new balloon.
Show the instructions to the user at the beginning of the game
Show the score to the user while the game is happening
You will probably find these methods to be useful:
isDrawn() -- works for all shapes. It returns True if the object is drawn (visible in some window) and False if not.
getFill() -- works for all shapes. It returns a list with 3 integers that show the rgb components of the object's current fill color
getOutline() -- works for all shapes. Does the same thing as getFill() except that it works on the object's outline color
In addition, you can also print out an object. Printing the object gives you its basic information -- e.g. what kind of object it is, the coordinates of its center point (or its corners), etc. It is very very very useful for debugging!
Once you are done with the basic program, you can feel free to add enhancements to it. Some ideas of enhancements (kind of in order of increasing difficulty) are listed below. You may get up to 50% extra credit for enhancements.
At this point, sometimes you will see that the stars are generated right inside the balloon, which makes for a very short game. Likewise, sometimes, bubbles get generated touching the balloon, which gives the user free points. Modify the program to make sure that doesn't happen. (This is not too bad. You really only need a while loop inside the drawAllStars() and drawAllBubbles() functions for this.)
Pretty up the game by making a dedicated area for the scoreboard and the instructions.
Change the colour of the balloon every time it picks up one bubble. You can use the getFill() and setFill() methods to do this.
Change the colour of the background depending on how "dangerous" the situation is (i.e. how close the balloon is to the nearest star)
Let the user pay a certain number of points to "kill" a star by clicking on it (checkMouse() and checking the location of mouse click)
Let the user pay a certain number of points to "squeeze" the balloon and reduce its size by a certain percentage in order to squeeze past stars (this will involve time.time(), checkMouse(), and checking whether the mouse click is actually on a balloon
Put in gravity and physics to make the balloon float around; the keypresses then redirect the balloon instead of moving it. (involves time.sleep() -- but be careful when sleeping, as any user input that comes in during sleep time is not detected. So don't let the computer sleep for too long -- experiment with different values, but 1 second of sleep is definitely too long.)
Make dynamically moving stars and/or bubbles that move according to physics or Brownian motion (same considerations as the above.)
You can also add other enhancements that you can think of. Some of these enhancements will require changes to the original specified functions -- for example, maybe a function will have to take in additional parameter, or a different type of parameter, etc. Therefore, to make life easier for us and our graders when we grade, we would like you to turn in additional file called documentation.txt that contains:
A description of all the enhancements that you made, if any
A list of all the additional functions that you added, if any
A list of all the changes that you made to the specifications of the original functions, if any
Please be clear and precise. The burden of making sure that the reader understands what you are saying rests on you.
Submit
Once you are satisfied with your programs, hand them in by typing
handin21 at the unix prompt.
You may run handin21 as many times as you like. We will grade the most recent submission submitted prior to the deadline
Remember: for this lab,
programs must appear in your cs21/labs/06 directory.
If you create your programs in a different directory, use the unix mv or
cp commands to move or copy them into the cs21/labs/06 directory.
For example:
cp myprog.py ~/cs21/labs/06/myprog.py
Last updated: Tuesday, September 22, 2020 at 12:25:28 PM