2

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

PlatyPi
  • 102
  • 11
  • How do you set "prevY" and "prevX"? – Heckel Aug 24 '15 at 13:35
  • Is there some reason that I'm missing why top/bottom is using the horizontal axis and left/right is using the vertical axis? – Fuzzy Logic Aug 24 '15 at 16:55
  • @Heckel I set it before the player moves, so his last position is tracked. – PlatyPi Aug 24 '15 at 17:27
  • @FuzzyLogic Oh Ha! Didn't notice that, I'll go fix that right now. – PlatyPi Aug 24 '15 at 17:28
  • 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. – Fuzzy Logic Aug 24 '15 at 19:30

1 Answers1

2

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.

david van brink
  • 2,572
  • 13
  • 16
  • 1
    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. – Fuzzy Logic Aug 24 '15 at 15:57
  • 1
    +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. – Fuzzy Logic Aug 24 '15 at 16:02
  • 1
    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! – david van brink Aug 24 '15 at 16:19
  • 1
    @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? – PlatyPi Aug 24 '15 at 17:40
  • @PlatyPi Is it an improvement/difference from your original? Or same issues? – Fuzzy Logic Aug 24 '15 at 18:10
  • Sorry. Is what I get for typing blind. The actual algorithm needs to do it in two complete steps, I will replace wrong code with correct psuedocode. – david van brink Aug 24 '15 at 18:13
  • @davidvanbrink I'm getting somewhere by doing something like this: 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; } } This lets the player move left/right while on the ground. But there are problems with the edges, specifically the left. Sorry, it's a bit messy, and hard to read :) – PlatyPi Aug 24 '15 at 18:38
  • @davidvanbrink That might work but it isn't necessary do two (or 4) passes... I'll have to dig in my ancient memory and code but I'll see if I can find the proper solution for this. – Fuzzy Logic Aug 24 '15 at 18:38
  • @FuzzyLogic if only the player moves, two steps is enough. If more things are moving, depending on policy, some kind of transitive-push resolution may be needed. If collision is rare, can optimize by doing xy move-and-test, and then do x&y separate only if collides. (And of course skip x if velX == 0, same for y.) – david van brink Aug 24 '15 at 18:44
  • @davidvanbrink I've updated my question with some new code and added pictures to show some of the problems. – PlatyPi Aug 24 '15 at 19:12