0

I am looking for a different way to create collision detection using Zelle Graphics and find_overlapping. I believe the overlapping shows where the bounding box of an object has come in contact with the bounding box of another object (the tuple)? I was hoping for some feedback on this code. Presently, the object goes through the rectangle before it breaks, but I think the idea has merit. This is just a test and need much more fine tuning.

from graphics import *
win = GraphWin("game loop", 500, 500, autoflush=False)
win.master.attributes('-topmost', True)

x=20
y=20
dx=20
play=0
cir1=Circle(Point(x,y),10)
cir1.setFill("red")
cir1.draw(win)
x1=300
x2=310
y1=0
y2=50


rect1=Rectangle(Point(x1,y1),Point(x2,y2))
rect1.setFill("blue")
rect1.draw(win)

xwidth=win.getWidth()

while play==0:

    for i in range(100):
        xposition = cir1.getCenter().getX()
        test1=win.find_overlapping(x1,y1,x2,y2)
        print("This is the length of test1:",len(test1))
        print(test1)
        if xposition+1>=xwidth or xposition-1<=0:
            dx=-dx
        cir1.move(dx, 0)
        update(15)
        if len(test1)==2:
            print("overlap")
            play=1
            break

print("game over")
win.mainloop()
netrate
  • 423
  • 2
  • 8
  • 14
  • 1
    maybe first use `print()` to see whant you check with `find_overlapping()` - maybe you use wrong values and you check in wrong place – furas Jul 30 '22 at 14:52
  • 1
    I'm not sure but `find_overlap()` may check if it overlap partially but it can't detect it when object is inside rectangle and it doesn't touch borders – furas Jul 30 '22 at 14:56
  • 1
    you could use `play = True/False` instead of `play = 0/1` and then you could write `whil play:` – furas Jul 30 '22 at 14:57
  • 1
    I run code and problem can be because you use `dx = 20` but rectangle has width only `10` - you would have to use smaller step. And when you detect collision then you should move circle into previous position - or check circle's direction and if it moves right then you should set circle's right position (x2) at position of left border of rectangle (x1). etc. – furas Jul 30 '22 at 15:00

1 Answers1

1

I see few problems:

  1. you first check collision, next you move to new position, and next you check if to stop game - but you should stop game after checking collision without moving to new position. OR you should first move to new position, next check collision and check if to stop game.

  2. you move dx = 20 but wall has width only 10 and it can jump it - you should use smaller dx and use bigger value in update()

  3. you check if wall overlaps any other objects but if you will have many walls then it would be simpler to check if circle overlaps any other objects.

  4. when circle overlap then you would have to move it back - if you move right then you should set circle's right border in place of rectangle' left border.


Minimal working example with changes 1, 2, 3 but without 4 because it would need more changes.

from graphics import *

win = GraphWin("game loop", 500, 500, autoflush=False)
win.master.attributes('-topmost', True)

x = 200
y = 20
dx = -5
play = True

cirle = Circle(Point(x, y), 10)
cirle.setFill("red")
cirle.draw(win)

x1 = 300
x2 = 310
y1 = 0
y2 = 50

rect1 = Rectangle(Point(x1, y1), Point(x2, y2))
rect1.setFill("blue")
rect1.draw(win)

xwidth = win.getWidth()

while play:

    for i in range(100):
        # move circle to new position
        cirle.move(dx, 0)

        # get circle's new position
        p1 = cirle.getP1()
        p2 = cirle.getP2()
        
        # check circle's collision in new position
        overlaps = win.find_overlapping(p1.x, p1.y, p2.x, p2.y)
        
        print("test:", len(overlaps), overlaps)
        
        if len(overlaps) > 1:
            print("overlap")
            play = False
            break

        # check circle's collision with window's boders
        if p2.x >= xwidth or p1.x <= 0:
            dx = -dx
            
        update(50)
            
print("game over")
#win.mainloop()  # no need if you use `update()`
furas
  • 134,197
  • 12
  • 106
  • 148
  • Ok thank you. I see what you mean. I was a bit confused about P1 and P2. It says " Returns a clone of the corresponding endpoint of the segment." in the notes. I am not sure what that exactly means. Also, does the TUPLE continue to add objects that it overlaps? I added a second rectangle and the tuple comes up as 1,2 for the original rectangle and 1,3 for the second rectangle, so it seems to erase the placeholder each time. – netrate Jul 30 '22 at 16:55
  • 1
    it gives copy of points `(x1,y1)`, `(x2,y2)` so you can modify there values but it will not move `circle`. Every object has own ID (circle probably has ID `1`, and rectangles have IDs `2` and `3`) and `find_overlaps()` gives list of overlaping objects - circle overlaps itself so it always gives ID `1` on list. When it overlap first rectangle then it gives also `2` on list, when it overlap second rectangle then it gives `3` on list. BTW. `find_overlaps()` doesn't gives information if circle overlap rectangles on left, right, top or bottom so you can use speed (`dx`) to check it. – furas Jul 30 '22 at 17:24
  • 1
    if you will move in two direction at the same time (`dx, dy`) then you will have to first move in one direction (`dx`) and use `find_overlaps()` to detect overlaps on left or right, next you will have to move only in other direction (`dy`) and use again `find_overlaps()` to detect overlaps on top or botton. This method is used in PyGame (in `maze_runner.py` in [Platformer examples](http://programarcadegames.com/index.php?chapter=example_code&lang=pl#section_38) on page [Program Arcade Games With Python And Pygame](http://programarcadegames.com/index.php) – furas Jul 30 '22 at 17:33