Jump to content
  • Advertisement
Sign in to follow this  
kingpinzs

python collision recursion issue

This topic is 1667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

    def touching(self, bubble, bubbles):
        for bubble1 in bubbles:
            bubble_old = bubble1
            if self.color == bubble_old.color and dist(bubble.pos, bubble_old.pos) <= 2 * BUBBLE_RADIUS:
                bubbles.remove(bubble_old)
                self.touching(bubble1, bubbles)
 
 
The error occurs when there are two rows right next to each that need to be removed.

for example like this
x x  x  x  x
x O O O x
x x  O O x
x x  O  x x
       O <-current ball

Traceback (most recent call last):
  File "main.py", line 140, in draw
    if a_bubble.remove_matching(stuck_bubbles):
  File "main.py", line 72, in remove_matching
    self.touching(bubble_old, bubbles)
  File "main.py", line 81, in touching
    self.touching(bubble1, bubbles)
  File "main.py", line 80, in touching
    bubbles.remove(bubble_old)
KeyError: <__main__.Bubble instance at 0x192c878>

 

Share this post


Link to post
Share on other sites
Advertisement

I'm struggling to see how you got a KeyError for this, unless you're doing something exotic ( in which case I'll need more code ).

 

Anyway, instead looping through a list and remove elements in the for loop, you should instead try one of the below:

  • Loop through a copy of the list of bubbles, removing from them from the original list ( for bubble1 in bubbles[:]: )
  • Loop through the list using an iterator ( for bubble1 in iter(bubbles): )

 

Also, you don't need to set bubble_old = bubble1. When you remove old_bubble from the list, you still hold the reference to it ( old_bubble is referenced to bubble1 ).

def touching(self, bubble, bubbles):
    for bubble1 in bubbles[:]:
        if self.color == bubble_old.color and dist(bubble.pos, bubble1.pos) <= 2 * BUBBLE_RADIUS:
            bubbles.remove(bubble1)
            self.touching(bubble1, bubbles)
Edited by ScoreX

Share this post


Link to post
Share on other sites

    def remove_matching(self, bubbles):
        bubble_old = []
        for bubble in list(bubbles):
            if self.color == bubble.color and self.collide(bubble):
                bubble_old = bubble
                bubbles.remove(bubble)
                self.touching(bubble_old, bubbles)
                return True
        return False

this is the method that calls it. 

The code works when the bubbles are lined up like this

 

x O x

x O x

x O x

  O <-current ball   

 

x  O  x

x  O  x

O O O

   O <-current ball

 

the issue happens with anything like this

 

O O

O O

   O <-current ball

 

I have also tried this

  def touching(self, bubble, bubbles):
        for bubble1 in list(bubbles):
            if self.color == bubble1.color and dist(bubble.pos, bubble1.pos) <= 2 * BUBBLE_RADIUS:
                bubbles.remove(bubble_old)
                self.touching(bubble1, bubbles)

I got the same error

 

and this gets this error RuntimeError: Set changed size during iteration 

    def touching(self, bubble, bubbles):
        for bubble1 in iter(bubbles):
            if self.color == bubble1.color and dist(bubble.pos, bubble1.pos) <= 2 * BUBBLE_RADIUS:
                bubbles.remove(bubble1)
                self.touching(bubble1, bubbles)
Edited by kingpinzs

Share this post


Link to post
Share on other sites

I changed bubbles.remove(bubble1)  to bubbles.discard(bubble1) and I no longer get the error. Thanks every one for taking the time to read my post.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!