One problem is with the nature of this loop:
for i in trees:
collision = wall_detect(player.x, player.y, player.width, player.height, i.x, i.y, i.width, i.height)
player.update(collision)
Suppose the player collides with the first tree in trees
. Then collision
will be True, but the for
loop continues. So collision
will only end up being True if the player is colliding with the last tree in your list. There are multiple ways to fix this.
# Change the assignment to check if it is already true
collision = False
for i in trees:
collision = collision or wall_detect(...
or
# Exit the loop if it is true
for i in trees:
collision = wall_detect(...)
if collision:
break
or
# Turn it into a function that returns when it is true
def walls_detect(player, trees):
for tree in trees:
if wall_detect(...):
return True
return False
...
# Call it like this
player.update(walls_detect(player, trees))
Your logic for when collisions occur looks right to me, though it can also be simplified quite a bit:
def wall_detect(x1, y1, w1, h1, x2, y2, w2, h2):
return (x2+w2>=x1>=x2 or x2+w2>=x1+w1>=x2) and (y2+h2>=y1>=y2 or y2+h2>=y1+h1>=y2)