The way I handle simple collision detection causes a really frequent and easy to reproduce glitch, which affects gameplay severely. Here's my code (Python 3.5):
def move(self, _map): self.col = False for y in _map.actors: for actor in y: if actor: if not (((self.y + self.h) < (actor.y - self.cam.y)) or (self.y > ((actor.y - self.cam.y) + actor.h)) or (self.x > ((actor.x - self.cam.x) + actor.w)) or ((self.x + self.w) < (actor.x - self.cam.x))): print(self.col) self.col = True if not self.col: if self.directions: self.cam.y -= self.speed if self.directions: self.cam.y += self.speed if self.directions: self.cam.x -= self.speed if self.directions: self.cam.x += self.speed else: if self.directions: self.cam.y += self.speed if self.directions: self.cam.y -= self.speed if self.directions: self.cam.x += self.speed if self.directions: self.cam.x -= self.speed if self.running: self.speed = system.RUNNING_PLAYER_SPEED else: self.speed = system.NORMAL_PLAYER_SPEED self.x = ((self.cam.w / 2) - (self.w / 2)) self.y = ((self.cam.h / 2) - (self.h / 2))
As you can see, I'm detecting collision against walls and whatever (Any actor in the map) in the player's "move" method. The logic is pretty straightforward, a basic bounding box collision test (I consider the position of the player relative to the camera, since the player is always in the center (It's the camera that moves)). If I just stop the player if there's a collision, the player gets stuck inside the wall, thus creating the necessity of "teleporting" the player to its former position, as you can see in this other question. The problem with that solution is that it leads to this glitch, which I need to illustrate in order to make myself clear.
In this first example, I'm going up (pressing W) towards the wall.
The collision works fine just pressing W, it gets teleported in the opposite direction at each collision. The problem is when I start pressing S (Down) at the same time. The player goes to the opposite direction, glitching up towards the other side of the wall, since the collision test always returns true when the player is "inside" the wall, just like this:
This would severely compromise the gameplay, since players would be able to play outside the boundaries of the map in multiplayer. How can I avoid this using bounding box collision or other method?