I am coding a game in pygame
and my entity objects have attribute lists of hit boxes.
All the hit boxes are pygame.rect
objects and when i have them drawn on the screen all of them show up but for some reason the objects only act like they collide if the last hit box in their list collides with the last hit box in the other objects list.
Here is the method I use for the check:
def collide_check(self, obj): self.update_hit_boxes() obj.update_hit_boxes() is_collide = False if self.can_collide and obj.can_collide: for box in self.hit_boxes: for obj_box in obj.hit_boxes: is_collide = box.colliderect(obj_box) if is_collide: break else: is_collide = False return is_collide
Anyone have an idea what I’m doing wrong here or if this is even possible using only pygame.rect
objects and pygame.rect.collide_rect
?
Advertisement
Answer
I can’t test it but problem can be because break
can exit only last/inner for
-loop – so code still runs outer for
-loop which can set again is_collide = False
(because it runs is_collide = box.colliderect(obj_box)
). And finally it gets is_collide = True
only if last boxes collides.
You should check collision without assigning to variable and assign variable only inside if`
if box.colliderect(obj_box): is_collide = True break
instead of
is_collide = box.colliderect(obj_box) if is_collide: break
Ot put both for
-loops in separated function and use return True
instead of break
def test(obj1, obj2): for box1 in obj1.hit_boxes: for obj2 in obj2.hit_boxes: if box1.colliderect(box2): return True return False def collide_check(self, obj): self.update_hit_boxes() obj.update_hit_boxes() is_collide = False if self.can_collide and obj.can_collide: is_collide = test(self, obj) return is_collide
EDIT:
You could use return
directly in original function
def collide_check(self, obj): self.update_hit_boxes() obj.update_hit_boxes() if self.can_collide and obj.can_collide: for box in self.hit_boxes: for obj_box in obj.hit_boxes: if box.colliderect(obj_box): return True return False