1
votes

Whenever the player collides with the wall, they just get stuck in the wall and can't move. Here's the code:

collide = pg.sprite.collide_mask(self, self.game.map)

        if keys[pg.K_w]:
            self.pos.y -= playerSpeed
            if collide:
                self.pos.y += playerSpeed
        if keys[pg.K_a]:
            self.pos.x -= playerSpeed
            if collide:
                self.pos.x += playerSpeed
        if keys[pg.K_s]:
            self.pos.y += playerSpeed
            if collide:
                self.pos.y -= playerSpeed
        if keys[pg.K_d]:
            self.pos.x += playerSpeed
            if collide:
                self.pos.x -= playerSpeed
2

2 Answers

1
votes

Well that is exactly what your code tells:

collide = pg.sprite.collide_mask(self, self.game.map)

so this will be true when the player hits the wall

if keys[pg.K_s]:
    self.pos.y += playerSpeed
    if collide:
        self.pos.y -= playerSpeed

so if collide is true, what effectively happens is:

self.pos.y += playerSpeed
self.pos.y -= playerSpeed

So the net result is that the position does not change (same for all other directions).

The real question is now: what would you like to happen? Probably you should know which of the four directions is blocked by the wall, and only set the movement in that direction to 0.

0
votes

The issue is that you need to check for collisions before the player gets stuck on the object. Once the player is in a collision state, the test:

collide = pg.sprite.collide_mask(self, self.game.map)

Will simply return True no matter what. As @ChrisMaes points out, once collided, the movement will never again effect the outcome.

The solution is to test the collision before the movement is finalised:

if keys[pg.K_w]:
    self.pos.y -= playerSpeed
    if ( pg.sprite.collide_mask( self, self.game.map ) ):
        self.pos.y += playerSpeed                          # Undo the movement
# ... etc, same change for the rest of the movement keys

There is a problem with this method though. If playerSpeed is say a constant of 5, it would be impossible for the player to move to be resting against a barrier, since the test is done at 5 pixels, they get stopped at 1-5 pixels away. If the player speed is fixed (and > 1), it would be necessary to determine how much the player could have moved up-to the barrier, and only allow movement of that distance. This leaves the player right-next to the thing it collided with, rather than 1-4 pixels away.