Skip to main content
The algorithm I posted was patently wrong! Replaced with correct two-step algo.
Source Link

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

// step 1, modify X
prevX = x;
x += movementX;
work out top, left, bottom, right
if(new span collides with anything) x = prevX;

// step 2, modify Y
prevY = y;
y += movementY;
work out top, left, bottom, right
if(new span collides with anything) y = prevY;

In certain cases, the order of checking x and y will make a difference. Specifically, heading directly onto a colliding corner will now favor X movement. This is probably ok, but can be changed if you need. (Literally a corner case!)

Hope that helps a little.

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

// step 1, modify X
prevX = x;
x += movementX;
if(collides with anything) x = prevX;

// step 2, modify Y
prevY = y;
y += movementY;
if(collides with anything) y = prevY;

Hope that helps a little.

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

// step 1, modify X
prevX = x;
x += movementX;
work out top, left, bottom, right
if(new span collides with anything) x = prevX;

// step 2, modify Y
prevY = y;
y += movementY;
work out top, left, bottom, right
if(new span collides with anything) y = prevY;

In certain cases, the order of checking x and y will make a difference. Specifically, heading directly onto a colliding corner will now favor X movement. This is probably ok, but can be changed if you need. (Literally a corner case!)

Hope that helps a little.

The algorithm I posted was patently wrong! Replaced with correct two-step algo.
Source Link

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

...previous stuff...

      // step collideUD1, =modify true;X
        collideLRprevX = true;
x;
        if     (bottom <= tileTop) collideUDx =+= false;movementX;
        else if(topcollides >=with tileBottomanything) collideUDx = false;prevX;

        if     (right <=// tileLeft)step collideLR2, =modify false;Y
        else if(left >= tileRight) collideLRprevY = false;
y;
      y += movementY;
if(collideLR) x = prevX;
      collides with if(collideUDanything) y = prevY;

Hope that helps a little.

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

...previous stuff...

        collideUD = true;
        collideLR = true;

        if     (bottom <= tileTop) collideUD = false;
        else if(top >= tileBottom) collideUD = false;

        if     (right <= tileLeft) collideLR = false;
        else if(left >= tileRight) collideLR = false;

        if(collideLR) x = prevX;
        if(collideUD) y = prevY;

Hope that helps a little.

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

// step 1, modify X
prevX = x;
x += movementX;
if(collides with anything) x = prevX;

// step 2, modify Y
prevY = y;
y += movementY;
if(collides with anything) y = prevY;

Hope that helps a little.

incorporated @fuzzylogic's style suggestions.
Source Link

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

...previous stuff...

        collideUD = true;
        collideLR = true;

        if(bottom <= tileTop) 
         (bottom <= tileTop) collideUD = false;
        else if(top >= tileBottom) 
            collideUD = false;

        if(right <= tileLeft) 
         (right <= tileLeft) collideLR = false;
        else if(left >= tileRight) 
            collideLR = false;

        if(collideLR)
            x = prevX;
        if(collideUD)
            y = prevY;

Hope that helps a little.

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

...previous stuff...

        collideUD = true;
        collideLR = true;

        if(bottom <= tileTop) 
            collideUD = false;
        if(top >= tileBottom) 
            collideUD = false;

        if(right <= tileLeft) 
            collideLR = false;
        if(left >= tileRight) 
            collideLR = false;

        if(collideLR)
            x = prevX;
        if(collideUD)
            y = prevY;

Hope that helps a little.

I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg

The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):

...previous stuff...

        collideUD = true;
        collideLR = true;

        if     (bottom <= tileTop) collideUD = false;
        else if(top >= tileBottom) collideUD = false;

        if     (right <= tileLeft) collideLR = false;
        else if(left >= tileRight) collideLR = false;

        if(collideLR) x = prevX;
        if(collideUD) y = prevY;

Hope that helps a little.

Source Link
Loading