-3

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.width
            if self.pos.x < 0:
                self.pos.x = hits[0].rect.right
            self.rect.x = self.pos.x
    if 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 / 2
            if self.pos.y < 0:
                self.pos.y = hits[0].rect.bottom
            self.rect.y = self.pos.y
skrx
  • 19,980
  • 5
  • 34
  • 48
Tudor Popescu
  • 509
  • 1
  • 5
  • 16
  • 2
    Why the capslock? Also, it would be helpful if you could paste the relevant parts of your code into your question and specify expected/actual behavior. – nnnmmm Feb 08 '18 at 21:30
  • @nnnmmm I updated the code to include the collision, I would like to redo this code as it doesn't work properly, sorry for the caps lock, as you can see I am not that experienced in writing comments – Tudor Popescu Feb 08 '18 at 21:45
  • Instead of giving me downvotes for no reason, actually tell me why you did it – Tudor Popescu Feb 09 '18 at 08:44
  • [Here's an answer](https://stackoverflow.com/a/45017561/6220679) that shows you one way to implement walls. – skrx Feb 09 '18 at 13:14
  • BTW, you haven't really asked a question. What's the problem? Do you want to ignore the y-movement for the moment? I can already see one problem here: `self.pos.y = Wall.rect.top - self.rect.height / 2`. That should be `hits[0]` instead of `Wall`, and don't divide the `self.rect.height` by 2. – skrx Feb 09 '18 at 13:25
  • Please read the ["how to ask"](https://stackoverflow.com/help/how-to-ask) page and this [checklist](https://meta.stackoverflow.com/questions/260648/stack-overflow-question-checklist). – skrx Feb 09 '18 at 13:28
  • @skrx the problem was that there was no collision in the y axis, I'll play around with the code as you gave me an answer:) – Tudor Popescu Feb 10 '18 at 10:51
  • Please update your question, so that it's easier to find and understand for people with the same problem. – skrx Feb 10 '18 at 10:52
  • @skrx I have edited the title – Tudor Popescu Feb 10 '18 at 10:58

1 Answers1

1

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.width
            if self.pos.x < 0:
                self.pos.x = hits[0].rect.right
            self.rect.x = self.pos.x
    if 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.height
            if self.pos.y < 0:
                self.pos.y = hits[0].rect.bottom
            self.rect.y = self.pos.y
            self.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.

skrx
  • 19,980
  • 5
  • 34
  • 48