5
\$\begingroup\$

I'm just a normal guy trying to do some basic collision detection but I suck at it. I either get stuck in a wall or I go in reverse in the wrong direction trying to update the player position to a non collision part. So here is how I check for collision and this function will return true or false. True if collision and false if not.

roguelike.player.collision = function() {
  var player = roguelike.player;
  for(var i = 0; i < roguelike.map.rooms.length; i++) {
    var room = roguelike.map.rooms[i];
    if(player.x > room.x && player.x < room.x + room.width && player.y > room.y && player.y < room.y + room.height){
      return false;
    }
  }
  return true;
};

This function works just fine just like expected. But it's when I try to stop the player when he hits a wall is where I get bugs. When the player goes down and hits a wall he gets stuck there. Here is the function that updates the player position.

roguelike.update = function() {
  var player = roguelike.player;

  //Left
  if(player.moving.left && !player.collision()) {
    player.x -= roguelike.game.speedPerSecond(player.speed);
  } else if(player.collision()){
    player.resetPosition();
  }
  //Up
  if(player.moving.up && !player.collision()) {
    player.y -= roguelike.game.speedPerSecond(player.speed);
  } else if(player.collision()){
    player.resetPosition();
  }
  //Right
  if(player.moving.right && !player.collision()) {
    player.x += roguelike.game.speedPerSecond(player.speed);
  } else if(player.collision()){
    player.resetPosition();
  }
  //down
  if(player.moving.down && !player.collision()) {

    player.y += roguelike.game.speedPerSecond(player.speed);
  } else if(player.collision()){
    player.resetPosition();
  }
  player.savePosition();

};

So what I do is check what direction the player is moving and if there is no collision detected then the player is free to move. Otherwise if there is a collision I put the player position as the last position he was when there was no collision so he will be free to move. This works going left, up, and right, but not going down. Going down the player gets stuck in the collision and the resetPosition function doesn't put the player back in the safe zone.

So I know there must be a better way. And I would appreciate your advice on what you think that way should be.

\$\endgroup\$
2
  • \$\begingroup\$ From what I can see you are testing collisions ON the player instead of AHEAD of the player. This will cause problems, and is probably what causes this one. \$\endgroup\$ Jun 11, 2015 at 18:10
  • \$\begingroup\$ @AlexandreDesbiens Oh thank you. I just can't figure out how to check ahead. Can you show me an example? \$\endgroup\$
    – zachdyer
    Jun 11, 2015 at 18:25

1 Answer 1

6
\$\begingroup\$

Instead of testing the collisions ON the player, you should testing them AHEAD, to check whether there's a wall where the player WILL be walking. To do that, you'll only need to change 2 things:

1- Your player.collision function should accept two arguments: an x and y offset. You should add them to your collision checking algoythm too.

2- When calling player.collision, you should pass the offset equal to the movement the player would make.

In your code, this resumes as this:

roguelike.player.collision = function(x, y) { // The function now accepts 2 arguments
    var player = roguelike.player;
    for(var i = 0; i < roguelike.map.rooms.length; i++) {
        var room = roguelike.map.rooms[i];
        if(player.x + x > room.x && player.x + x < room.x + room.width
                && player.y + y > room.y && player.y + y < room.y + room.height)
        { // The offset is added to the player position when testing
            return false;
        }
    }
    return true;
};

And calling a movement would look like this:

if(player.moving.left
        && !player.collision(-roguelike.game.speedPerSecond(player.speed), 0) {
    player.x -= roguelike.game.speedPerSecond(player.speed);
} else if(player.collision()){
    player.resetPosition();
}
\$\endgroup\$
4
  • \$\begingroup\$ How did you figure this out? I had such a hard time. I really appreciate it! I've tested it out in game and it works like a charm. Now on to optimizations because I'm having some lag and consistent speed issues but that's for another topic. \$\endgroup\$
    – zachdyer
    Jun 11, 2015 at 19:24
  • 1
    \$\begingroup\$ @zachdyer I do have a lot of experience in game programming and I have faced these kinds of errors a lot during my younger days. With time and practice you become better at spotting errors and fixing them. \$\endgroup\$ Jun 11, 2015 at 19:26
  • \$\begingroup\$ Well I'm impressed. By the way this solution simplified my code I actually got to get rid of savePosition and resetPosition. I don't even need to mess with the players position anymore. Do you have any Chrome Apps on the market? \$\endgroup\$
    – zachdyer
    Jun 11, 2015 at 19:31
  • 1
    \$\begingroup\$ @zachdyer You should'nt use the comments to chat. If you want to discuss, please use the chat rooms or send me an email. You can find it in my profile. \$\endgroup\$ Jun 11, 2015 at 19:34

You must log in to answer this question.

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