1
\$\begingroup\$

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:

enter image description here

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:

enter image description here

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!

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .