pythonpygamecollision-detectionpytmx

How to speed up or optimize for loop used for collision detection using pygame/pytmx?


I am using a for loop combined with .colliderect() for collision detection while attempting to make a game using pygame, the loop gets too slow with ~340 wall Rectangles, I was wondering if it could be faster somehow because it severely effects the game play loop?

I have tried using coordinate points on different places on every wall but only works if you're moving certain amounts of pixels at a time and every time you half the movement speed it quadruples the amount of coordinate points you save.

#disregard indent, this is all in an update function that is called every time that a player decides to move.
        self._old_position = self.position
        PlayerRectangle = pygame.Rect(self.position[0]+ x,self.position[1]+y,16,16)
        cwd = os.getcwd()
        tmxData = load_pygame(cwd+"\\Maps\\TestfileMap.tmx")
        movement = True
        for obj in self.walls:                   
                if(pygame.Rect(obj[0],obj[1],16,16).colliderect(PlayerRectangle)):
                        movement = False
                        self.move_back()
                else:
                        continue
        if movement:
                self.position[0] += x
                self.position[1] += y
                self.stats["position"]=self.position
                self.rect.topleft = self.position
                self.feet.midbottom = self.rect.midbottom

The provided code works, however it is too slow, I was wondering if there is a different method in collision detection or if there is a way to make what is shown faster, it bogs down things greatly. Thank you

EDIT:

So the solution was basically that I had load_pygame that ran literally every time it looped simply take out the line that does that and it clears things up a lot more, for further optimization change the line that makes a Rect for each object and just use a list of Rects that are already constructed, this limits function calls.


Solution

  • Without a minimal working example it is tough to give assertive advice.

    As I stated in the comments, there is a spurious call to a "load_pygame" function that seems to read file data inside this code - that alone could be the cause of your slowdown. Moreover, the data read is not used in the collision detection.

    The other advice I't have is to let your walls rectangles pre-calculated in a sprite group, instead of creating new rectangles for all walls in every check with: pygame.Rect(obj[0],obj[1],16,16).colliderect(PlayerRectangle)). then you can use the sprite method "spritecollideany" - https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.spritecollideany - that should optimize the rectangle-collision verification.

    (This will also require your Player object to be a Sprite if it is not already).