The goal of this example is to write a program that fills the screen with a random collection of debris (ovals) and then allows the user to click and remove debris pieces. This program lets you practice many techniques that we have learned in class. You will be using functions, for loops, graphics, random numbers, the mouse, and maybe even more!

The first step is to make the debris. Create constants that set limits for how large the debris pieces can be and how many pieces the screen will contain. For every piece, create a new oval with a random size, position, and color (within the limits you have set). Remember, this should work with any size screen. Perhaps you want to split this into a few functions to make your code easy to read!


Next, we need to let users remove debris from the screen. Add an infinite loop and check if the user has clicked on an object. If they have, clean that debris up (remove it from the screen)!

Getting a clicked object

The canvas function canvas.find_element_at(x, y) will get the object at the provided (x, y) argument. If there is no object, it will return None. To perform some actions on an object (if it exists), you could write something like below:

object = canvas.find_element_at(x, y)    # x and y are some coordinates
if object:    # If there was an object there...
    print("Object found at (" + str(x) + ", " + str(y) + ")")
else:
    print("Object not found")

Bonus!

If you want, as a bonus, you could add a way to check if all the debris is clear. When it is, tell the user congratulations and thank them for cleaning up the screen!

Solution

"""
File: debris_sweeper.py
-------------------
Puts a random collection of debris (ovals) on the screen
and then allows the user to click and remove the debris.
"""

from graphics import Canvas
import random

# minimum and maximum size of a piece of debris
MIN_DEBRIS_SIZE = 50
MAX_DEBRIS_SIZE = 150

# number of pieces of debris
NUM_DEBRIS_PIECES = 2


def main():
    canvas = Canvas()
    canvas.set_canvas_title("Debris Sweeper")

    create_debris(canvas)
    while True:
        clicks = canvas.get_new_mouse_clicks()
        for click in clicks:
            remove_debris(canvas, click.x, click.y)
        canvas.update()

    canvas.mainloop()


def create_debris(canvas):
    """
    Creates NUM_DEBRIS_PIECES pieces of "debris" (ovals) with random locations,
    sizes and colors.
    """
    for i in range(NUM_DEBRIS_PIECES):
        # Calculate a random location and size
        width = random.randint(MIN_DEBRIS_SIZE, MAX_DEBRIS_SIZE)
        height = random.randint(MIN_DEBRIS_SIZE, MAX_DEBRIS_SIZE)
        x = random.randint(0, canvas.get_canvas_width() - width)
        y = random.randint(0, canvas.get_canvas_height() - height)

        # Create with a random color
        piece = canvas.create_oval(x, y, x + width, y + height)
        canvas.set_color(piece, canvas.get_random_color())


def remove_debris(canvas, x, y):
    """
    Removes the debris (if any) at the given location.  If multiple pieces
    of debris are at this location, removes the one on the top.
    """
    item = canvas.find_element_at(x, y)
    if item:
        canvas.delete(item)


if __name__ == "__main__":
    main()