2
\$\begingroup\$

I've been working on a small game, and I've been stuck on the collision part. During the collision, when my player hits a block, he stops just as it should, but it then doesn't allow me to another direction (ex: the collision happens on the y axis, it won't allow me to move along the x axis). What I want is to be able to move along the wall while still moving into it (If you know what I mean). I've checked here and here, but they aren't what I'm looking for.

EDIT: The new code allows me to move along the axis's fine, but I'm getting some different problems (shown in pictures)

This is the NEW code for my collision detection:

if(key[KEY_A])
{
    if(tileMap[(x/zoomLevel)-1][y/zoomLevel] < 1 && tileMap[(x/zoomLevel)-1][(y/zoomLevel)+1] < 1)
    {
        if(tileMap[((x/zoomLevel)+1)][y/zoomLevel] < 1 && tileMap[((x/zoomLevel)+1)][(y/zoomLevel)+1] < 1)
        {
            x-=moveSpeed;
            dirX = 0;
        }
    }
}
else if(key[KEY_D])
{
    if(tileMap[(x/zoomLevel)+1][y/zoomLevel] < 1 && tileMap[(x/zoomLevel)+1][(y/zoomLevel)+1] < 1)
    {
        x+=moveSpeed;
        dirX = 1;
    }
}

if(jumping == false)
{
    if(tileMap[(x/zoomLevel)][(y/zoomLevel)+2] < 1)
    {
        y+=gravSpeed;
        gravSpeed*1.2;
        dirY = 1;
    }
}
else
{
    if(tileMap[(x/zoomLevel)][(y/zoomLevel)-1] < 1)
    {
        gravSpeed = 4;
        y-=gravSpeed;
        dirY = 0;
    }
}

Thanks to anyone who can help me with my problem!

And here are some picture based on the new collision:

Falling on ground: Falling on ground

Moving to the left when on top of a block: Moving to the left when on top of a block

Moving to the left: Moving to the left

Jumping when moving right: Jumping when moving right

\$\endgroup\$
5
  • \$\begingroup\$ How do you set "prevY" and "prevX"? \$\endgroup\$
    – Heckel
    Commented Aug 24, 2015 at 13:35
  • \$\begingroup\$ Is there some reason that I'm missing why top/bottom is using the horizontal axis and left/right is using the vertical axis? \$\endgroup\$ Commented Aug 24, 2015 at 16:55
  • \$\begingroup\$ @Heckel I set it before the player moves, so his last position is tracked. \$\endgroup\$
    – PlatyPi
    Commented Aug 24, 2015 at 17:27
  • \$\begingroup\$ @FuzzyLogic Oh Ha! Didn't notice that, I'll go fix that right now. \$\endgroup\$
    – PlatyPi
    Commented Aug 24, 2015 at 17:28
  • \$\begingroup\$ PlatyPi, @davidvanbrink and anyone else who would like to help. I've set up a chatroom. We should continue discussing in there instead of here. It is becoming an extended discussion and question/answers is not suited for dynamic exchange. When the problem is resolved, then a proper answer can be posted. \$\endgroup\$ Commented Aug 24, 2015 at 19:30

1 Answer 1

2
\$\begingroup\$

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.

\$\endgroup\$
10
  • 1
    \$\begingroup\$ Off-topic: Use the braces for your if statements if they are multiple lines. It's pedantic but trust me, it's better. The only time it should be ok to use if without braces is when the entire statement is one line (which you could and should do in this case). Even then, it could be argued that you should still use the braces. It's more readable, less prone to mistakes and saves a lot of vertical space. I would make a similar suggestion to PlatyPi regarding the opening braces on new lines but that is more subjective and unfortunately some editors enforce it. \$\endgroup\$ Commented Aug 24, 2015 at 15:57
  • 1
    \$\begingroup\$ +1 This should fix the issue, but I would actually suggest handling all 4 directions separately or you could still run into issues. You can also use else if statements or a boolean || for the opposing directions, since if you are colliding to the left then the object most likely came from the right and even if not, it doesn't matter. \$\endgroup\$ Commented Aug 24, 2015 at 16:02
  • 1
    \$\begingroup\$ Thanks @FuzzyLogic I agree with you on both counts. :) I was keeping the text briefer for display purpose (but one-line would be even better, edited). And, yes, taking cardinal directions into account separately becomes even more important if more than one thing is moving! \$\endgroup\$ Commented Aug 24, 2015 at 16:19
  • 1
    \$\begingroup\$ @davidvanbrink The code doesn't seem to correctly work. When my player is falling, he stops at the very top block of the map (like the very top colliding block), not where it's supposed to be. Do you have any other ways that you could make this work? \$\endgroup\$
    – PlatyPi
    Commented Aug 24, 2015 at 17:40
  • \$\begingroup\$ @PlatyPi Is it an improvement/difference from your original? Or same issues? \$\endgroup\$ Commented Aug 24, 2015 at 18:10

You must log in to answer this question.

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