SFML community forums

Help => General => Topic started by: aradarbel10 on June 13, 2018, 12:06:10 pm

Title: player-wall collision in game
Post by: aradarbel10 on June 13, 2018, 12:06:10 pm
Hello!
my friend and I are creating a top down puzzle game, and we have an issue with the walls.
When the player is walking into a wall, it stops (which is good), but then, it gets bad.
Let me give you an example:
  the player is moving right, and suddenly hitting a wall.
  the player stops by velocity.x = 0;
  while(1 = 1){ //do it forever
    I am clicking up and the player moves 1 pixel upwards.
    I am clicking rights and the player moves 1 pixel rightwards.
    This happens until the player moves all the way through the wall.
  }

So, I hope you got my explenation... I used a while loop to tell you that I am doing these actions forever, but remember that its not accualy part of the code.

also, when I am walking right and hitting a wall, if I am tring to move up or down the player is moving only 1 pixel, and then stop and I cant move it anymore to this direction.

And now for the question. Can you share a code of rectangle collision with walls and players?
I dont have a code at all so I need to see a working example/ a tutorial for this subject.

Thanks for any help,
Arad.
Title: Re: player-wall collision in game
Post by: Hapax on June 13, 2018, 03:21:23 pm
Detecting collision is (genenrally) testing to see if two things are overlapping. However, the response to collision is what you do what that occurs.

One thing to do is, as you've done, stop the thing from moving anymore if they collide. However, this means that they stop where they are overlapping. Generally, and especially for things like walls, you want to move the thing to where it should be - outside of the wall. There are different approaches to this and I don't profess to know lots about this.

One approach is to move is back to where it was before it collided. This is the easiest step and could be the best solution depending on how accurate you want it to look and how fast the thing is moving.

The next approach would be to take the previous position and the colliding position and use geometry to project the first position towards the second to work out where it would have collided between the two.

A more advanced approach could be to take the previous approach and the work how much further it would've travelled to the colliding position and 'bounce' the thing from the wall by that much. You should probably take into account the direction of travel and angle of the wall for this. However, this is less useful for things that should stop when hitting a wall. ;D
Title: Re: player-wall collision in game
Post by: aradarbel10 on June 13, 2018, 04:40:52 pm
Detecting collision is (genenrally) testing to see if two things are overlapping. However, the response to collision is what you do what that occurs.

One thing to do is, as you've done, stop the thing from moving anymore if they collide. However, this means that they stop where they are overlapping. Generally, and especially for things like walls, you want to move the thing to where it should be - outside of the wall. There are different approaches to this and I don't profess to know lots about this.

One approach is to move is back to where it was before it collided. This is the easiest step and could be the best solution depending on how accurate you want it to look and how fast the thing is moving.

The next approach would be to take the previous position and the colliding position and use geometry to project the first position towards the second to work out where it would have collided between the two.

A more advanced approach could be to take the previous approach and the work how much further it would've travelled to the colliding position and 'bounce' the thing from the wall by that much. You should probably take into account the direction of travel and angle of the wall for this. However, this is less useful for things that should stop when hitting a wall. ;D

Thank you very much for your reply :)
I think I will go with the first option because its the best for my case: the player is moving in a constent velocity, and I don't need to calculate anything about the direction because there are only 4 of them (up, down, left and right).

unluckily, it does not work.

this is my code:
for (int i = 0; i < lvl.getSizeInTiles().x; i++) {
        for (int j = 0; j < lvl.getSizeInTiles().y; j++) {
            if (lvl.getTileFromBuffer(i, j).getType() == "wall") {
                if (intersects(lvl.getTileFromBuffer(i, j).getPosition().x, lvl.getTileFromBuffer(i, j).getPosition().y, lvl.getTileFromBuffer(i, j).getSize().x, lvl.getTileFromBuffer(i, j).getSize().y)) {
                    if (faceDirection == "UP" && vel.y < 0) {
                        collidesUp = true;
                        pos.y += walkSpeed;
                        vel.y = 0;
                    }
                    else {
                        collidesUp = false;
                    }

                    if (faceDirection == "DOWN" && vel.y > 0) {
                        collidesDown = true;
                        pos.y -= walkSpeed;
                        vel.y = 0;
                    }
                    else {
                        collidesDown = false;
                    }

                    if (faceDirection == "LEFT" && vel.x < 0) {
                        collidesLeft = true;
                        pos.x += walkSpeed;
                        vel.x = 0;
                    }
                    else {
                        collidesLeft = false;
                    }

                    if (faceDirection == "RIGHT" && vel.x > 0) {
                        collidesRight = true;
                        pos.x -= walkSpeed;
                        vel.x = 0;
                    }
                    else {
                        collidesRight = false;
                    }
                }
            }
        }
    }
}
 

I hope it will help you, but if you have questions about the code; just ask me.

Thank you very much again,
Arad.
Title: Re: player-wall collision in game
Post by: Hapax on June 14, 2018, 02:52:30 am
Unfortunately, when you say "it doesn't work", it's not possible to know how it doesn't work and what happens instead of what is expected.

One thing to note, though, is that the collision flags (collidesUp, collidesRight etc.) seem a little pointless now since you've dealt with the collision and they are no longer colliding. ;)
Title: Re: player-wall collision in game
Post by: Tigre Pablito on July 01, 2018, 05:14:34 am
Hi

I agree with you that Hapax's first option is the best (for this case at least)

What I would suggest is to add into the main loop (maybe in the players update() function), (instead of the code you showed), something like this:

while (collideLeft())
    pos.x++;
while (collideRight())
    pos.x--;
while (collideUp())
    pos.y++;
while (collideDown())
    pos.y--;

You would have to define the 4 functions

If you (that it seems) make the player move by 'walkSpeed' pixels, then it may happen that you get stuck into the wall by more than 1 pixel, that's why the code above loops: *) nothing, if you haven't hit a wall, *) or, until you are at 0 pixels from it if you have (for the 4 possible ways ... you can put each one with the code that moves the player on its own direction, for higher performance)