In this lab you will write a graphical game, in the file rain.py, in which a player attempts to stop rain drops (circles) from hitting the bottom of the screen. The goal of this lab is to give you more practice using functions, as well as give practice using an indefinite loop.
As in Lab 05, the key data in your program will be a list of circles, with one circle for each rain drop currently on the screen. You will use an indefinite loop to create rain drops at random locations near the top of the screen, and animate the rain as it gradually falls toward the bottom. The player earns points by clicking on a rain drop; when the player clicks a rain drop, you should undraw and stop animating that rain drop.
Here are some screen shots of my sample solution as I am playing:
The start: | A few seconds later: | The drops are falling: |
Ooooh, I clicked one: | They're getting low: | Game over: |
Below we suggest several functions that you should write to help implement your game. As usual, you should write these functions and then extensively test them in main. After you know that they work, you can remove your test code and write the main function of your program.
Write a function createDrop(window) that creates a new rain drop. It should take the following parameter:
Hint: You can use the randrange function from the random library to get a random integer from a given range. To use this, you can put the statement:
from random import randrangenear the top of your program.
Write a function moveDrops(drops, dx, dy) that moves the rain drops the specified amounts in the x and y directions. This function is like jumpAlien in Lab 05; the movement is not animated and the moveDrops function should not use sleep().
The moveDrops function has the following parameters:
The moveDrops function should not return anything. Once you have written this function, create some drops in main and use moveDrops to move them to test the correctness of the moveDrops function. Once you confirm that moveDrops is correct, use a loop in main and Python's sleep function (in main) to animate the drops so they fall gradually toward the bottom of the screen. To use the sleep function you will need to import it from the time library:
from time import sleep
The game ends when any rain drop hits the bottom of the screen. To help determine this, write a function noneOffBottom(window, drops) that takes two parameters:
Once you've written noneOffBottom, test it in main by
using it as the condition in an indefinite (while) loop, ending
the game when any rain drops reach the bottom of the screen.
When a user clicks on a rain drop, you should undraw that rain drop and remove it from the list of visible rain drops so that it is no longer animated and no longer ends the game if it hits the bottom of the screen.
To help determine if a rain drop has been clicked, write a function intersects(p, c) that takes two parameters:
dx = p.getX() - c.getCenter().getX() dy = p.getY() - c.getCenter().getY()p intersects c if (dx*dx + dy*dy) is less than or equal to (c.getRadius()*c.getRadius()). (This is just a regular distance computation, with both sides squared.)
As usual, test your intersects function inside main before continuing your implementation. To test this, you might consider using getMouse or checkMouse in a loop and printing whether or not the Point from the mouse click intersects a rain drop.
Once you've implemented and tested the above functions, you should have some list of rain drops that are animated down the screen in an indefinite loop, with the game ending when any rain drops hit the bottom of the screen. You can turn this into a game as follows:
Once you are satisfied with your program, hand it in by typing handin21 in a terminal window.