Ryan
Ryan

Reputation: 747

Python: How do I detect visible shape detection in Tkinter

I am new to Python and I have a program that has 2 classes, one is essentially a rectangle and the other is essentially a circle. I am drawing them using the Canvas in Tkinter in the way below:

def draw(self):
    self.canvas.delete("all")
    self.rect.draw(self.canvas)
    self.ball.draw(self.canvas)

The Ball class has its location variables and diameter variables and the Rect class has its location and dimension variables.

I am wondering how I detect the collision between these two "shapes". I know that one was is to treat the Ball as a square and do basic rectangle collision but I would like to know how to be precise.

I was also wondering if there was anything similar in Python to the way shape collision can be done in Java. In my Java game I use the following code to detect collision between any 2 Shapes:

public boolean collisionCheck(Shape a, Shape b) {
     Area aA = new Area(a);
     Area aB = new Area(b);
     aA.intersect(aB);
     return !aA.isEmpty();
}

Is there anything similar to this simple solution in Python? And if not how would I go about circle-rectangle collision in Python?

Thank you for any help

Upvotes: 1

Views: 911

Answers (1)

Ryan
Ryan

Reputation: 747

I managed to figure this out using a method that Tkinter's Canvas object has. Every time something is drawn using Canvas it is given an ID. So as long as you record that ID somewhere you can use the find_overlapping method that the Canvas object has.

Say you have an object, in my case a custom Platform object, that keeps the ID stored in a variable. I did so like this:

def draw_platform(self, canvas): #Located in the Platform Class
    self.ID = canvas.create_rectangle(self.x, self.y, self.x+self.w, self.y+self.h)

Now I can use this ID to determine if there are any object overlapping it.

def check_collision(self, plat, other_plat):
    result = self.canvas.find_overlapping(plat.x, plat.y, plat.x + plat.w, plat.y + plat.h)
    for i in result:
        if i == other_plat.ID:
            return True
   return False

result returns a tuple of the ID's that are located within the rectangle bounds entered into find_overlapping. You can than loop through the tuple to see if any of the ID's match your other shape.

This works great for Rectangle-Rectangle collision and Circle-Rectangle collision.

Upvotes: 1

Related Questions