[Tutor] How to make object disappear?

Peter Otten __peter__ at web.de
Mon May 9 12:20:30 EDT 2016


Lisa Hasler Waters wrote:

> My students and I are creating a maze game in tkinter. We are trying to
> make the ball disappear when it hits the wall (black lines). We are not
> having much luck. The following code has run the best, but still, the ball
> does not disappear. Any advice would be appreciated!

You need to consider not just the ball, but the whole trajectory. When you 
can only move up/down/left/right that is roughly the rectangle spread by the 
starting and the end position of the ball. 

I calculate that rectangle as (x0,y0)-(x1,y1) in the checked_move() method 
below. I recommend that you use pen and paper, draw two rectangular "balls" 
on a horizontal or vertical line and the rectangle between them to try it 
yourself before you take a look.

I then use that rectangle to find overlapping canvas items. Of course the 
ball will always overlap with itself, so I have to make sure to rule that 
out. 

While dabbling with the code I have also cleaned it up a bit -- but you 
should still recognize it ;)


from tkinter import *
import random
import time


class Ball:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_oval(
            15, 15, 30, 30,
            fill='Blue')

    def checked_move(self, dx, dy):
        """Move unless we would hit a wall"""
        x0, y0, x1, y1 = self.canvas.coords(self.id)
        if dx > 0:
            x1 += dx
        else:
            x0 += dx
        if dy > 0:
            y1 += dy
        else:
            y0 += dy
        for id in self.canvas.find_overlapping(x0, y0, x1, y1):
            if id != self.id:
                # we will hit something other than ourselves
                # jump back to the start instead of
                # deleting ourselves
                self.canvas.coords(self.id, 15, 15, 30, 30)
                # uncomment line below if you insist on deletion
                # self.canvas.delete(self.id)
                return
        self.canvas.move(self.id, dx, dy)


def mt(event):
    STEP = 15
    if event.keysym == 'Left':
        ball.checked_move(-STEP, 0)
    elif event.keysym == 'Up':
        ball.checked_move(0, -STEP)
    elif event.keysym == 'Down':
        ball.checked_move(0, STEP)
    elif event.keysym == 'Right':
        ball.checked_move(STEP, 0)


WALLS = [
    (0, 0, 0, 300, 20),
    (0, 300, 300, 300, 10),
    (80, 240, 80, 0, 10),
    (160, 300, 160, 60, 10),
    (240, 240, 240, 0, 10),
    (300, 300, 300, 150, 10),
    (300, 150, 600, 150, 10),
    (80, 0, 2000, 0, 30),
    (300, 75, 600, 75, 10),
    (760, 0, 760, 300, 10),
    (600, 75, 680, 75, 10),
]


def main():
    global ball  # needed for mt()

    tk = Tk()
    tk.title("Game")
    tk.resizable(0, 0)
    tk.wm_attributes("-topmost", 1)
    canvas = Canvas(tk, width=1400, height=835, bd=0, highlightthickness=0)
    canvas.pack()

    ball = Ball(canvas, 'blue')

    canvas.bind_all('<KeyPress-Up>', mt)
    canvas.bind_all('<KeyPress-Down>', mt)
    canvas.bind_all('<KeyPress-Left>', mt)
    canvas.bind_all('<KeyPress-Right>', mt)

    for wall in WALLS:
        coords = wall[:4]
        width = wall[4]
        canvas.create_line(*coords, width=width, tags="wall")

    tk.mainloop()


if __name__ == "__main__":
    main()




More information about the Tutor mailing list