# Problem with diagonal collision response using PyGame

So I have been having this problem for the last few days and it has me really frustrated. What I am trying to do is resolve collisions with custom hitboxes in PyGame and it looks something like this:

Everything works fine until I collide with something diagonaly, then I get a weird bug where the character suddenly teleports to the opposite axis side of what I am colliding with, like this:

https://gyazo.com/62c53cc4f3a944c317a951c0f8ae14ea

I have read a lot about this the last day and from what I have gathered this has to do with the fact that I don't resolve the x and y axis independently? maybe?

If I have a print("x") and print("y") statement in their respective code I get this when colliding with something on the "y" axis:

The bug seems to come from that somewhat random "x" in the middle there. The code resolves a collision as if the character was colliding with something on the "x" axis when in fact it was the "y" axis. It is worth nothing that this ONLY happens when diagonaly colliding with the last axis I check (y in this case). So I suppose that is my question really, why does this happen?

Here is my collision handling code:

def collide(self, direction):

hits = pg.sprite.spritecollide(self, all_sprites_wall, False, rectconverter)
if direction == "x":
if hits:
print("x")
if self.vx > 0:
hits[0].update()
self.x = hits[0].hitboxrect.left - self.rect.width - camera.camera.x
self.hitboxrect.right = hits[0].hitboxrect.left
if self.vx < 0:
self.x = hits[0].hitboxrect.right - self.rect.width + self.hitboxrect.width - camera.camera.x
self.hitboxrect.left = hits[0].hitboxrect.right
self.rect.x = self.x

if direction == "y":
if hits:
print("y")
if self.vy > 0:
self.y = hits[0].hitboxrect.top - self.rect.height - camera.camera.y
self.hitboxrect.bottom = hits[0].hitboxrect.top
if self.vy < 0:
self.y = hits[0].hitboxrect.bottom - self.rect.height + self.hitboxrect.height - camera.camera.y
self.hitboxrect.top = hits[0].hitboxrect.bottom
self.rect.y = self.y


And here is the players update function:

def update(self):
self.move()

self.hitboxrect.y = self.y + camera.camera.y + self.rect.height - self.hitboxrect.height
self.rect.y = self.y
self.collide("y")
self.hitboxrect.x = self.x + camera.camera.x
self.rect.x = self.x
self.collide("x")


I think the problem lies somewhere in this code, but if you think otherwise feel free to say so and I would happily add more code!

Somehow I found the answer myself:

The problem was in the fact that I was adding and subtracting the camera values, so by removing the cameras x and y values the bug disappeared. I am not really sure why this solved it to be honest but I will take it. Here is how the code looks now for anyone curious:

def collide(self, direction):
hits = pg.sprite.spritecollide(self, all_sprites_wall, False, rectconverter)
if direction == "x":
if hits:
print("x")
if self.vx > 0:
self.x = hits[0].hitboxrect.left - self.rect.width
self.hitboxrect.right = hits[0].hitboxrect.left
if self.vx < 0:
self.x = hits[0].hitboxrect.right - self.rect.width + self.hitboxrect.width
self.hitboxrect.left = hits[0].hitboxrect.right
self.rect.x = self.x
if direction == "y":
if hits:
print("y")
if self.vy > 0:
self.y = hits[0].hitboxrect.top - self.rect.height
self.hitboxrect.bottom = hits[0].hitboxrect.top
if self.vy < 0:
self.y = hits[0].hitboxrect.bottom - self.rect.height + self.hitboxrect.height
self.hitboxrect.top = hits[0].hitboxrect.bottom
self.rect.y = self.y