I am trying to get the collision detection in my code to work. I am using vectors and I want the player sprite to collide and stop when it collides with a sprite group called walls
. The problem is that the player can pass through the bottom wall.
I've turned the gravity off in this example.
The x collision is okay but it draws a bit funny, only the y direction won't work properly with the same code.
I've already tried to debug the code with a debugger to no avail.
I'm mainly interested in figuring out why the vertical collision detection doesn't work, but I'd also appreciate suggestions about the horizontal collision detection.
LINKS:
Github : Complete code
Current collision detection code:
def collide_with_walls(self, dir):if dir == 'x':hits = pg.sprite.spritecollide(self, self.game.walls, False)if hits:if self.pos.x > 0:self.pos.x = hits[0].rect.left - self.rect.widthif self.pos.x < 0:self.pos.x = hits[0].rect.rightself.rect.x = self.pos.xif dir == 'y':hits = pg.sprite.spritecollide(self, self.game.walls, False)if hits:if self.pos.y >= 0:self.pos.y = Wall.rect.top - self.rect.height / 2if self.pos.y < 0:self.pos.y = hits[0].rect.bottomself.rect.y = self.pos.y
As far as I can see your horizontal movement and collision detection work correctly. I enabled the vertical movement again and had to fix only a few things. Wall
had to be changed to hits[0]
and the y-velocity had to be set to 0
after touching a wall.
def collide_with_walls(self, dir):if dir == 'x':hits = pg.sprite.spritecollide(self, self.game.walls, False)if hits:if self.pos.x > 0:self.pos.x = hits[0].rect.left - self.rect.widthif self.pos.x < 0:self.pos.x = hits[0].rect.rightself.rect.x = self.pos.xif dir == 'y':hits = pg.sprite.spritecollide(self, self.game.walls, False)if hits:if self.pos.y >= 0:# `Wall` had to be changed to `hits[0]`.self.pos.y = hits[0].rect.top - self.rect.heightif self.pos.y < 0:self.pos.y = hits[0].rect.bottomself.rect.y = self.pos.yself.vel.y = 0 # Stop the player, otherwise he'll keep accelerating.
There's still a problem: If the player sprite falls too long, it will accelerate and move so fast downwards that it can skip the collision detection with the wall and will just fall through it. Make sure that the sprite can't skip the collision detection, either by limiting the distances that it can fall, giving it a maximum speed or simply by making the walls thicker. You could also use ray casting, but that would be a bit more complex to implement.