# Java - simultaneous ground and wall collision

I've been working on a Line2D based collision system:

public void update() {
for (int i = 0; i < lines.size(); i++) {
line = lines.get(i);
if (line.line.intersects(player.hitbox))
playerCollision();
}
}

public void playerCollision() {
if (Math.abs(line.angle) <= 45) {
player.jumped = false;

if (player.speedY > 0)
player.speedY = 0;

// inefficient?
while (line.line.intersects(player.hitbox)) {
player.centerY--;
player.hitbox.setRect(player.centerX - player.WIDTH / 2, player.centerY - player.HEIGHT / 2,
player.WIDTH, player.HEIGHT);
}

player.centerY++;
player.hitbox.setRect(player.centerX - player.WIDTH / 2, player.centerY - player.HEIGHT / 2, player.WIDTH,
player.HEIGHT);

} else if (line.angle > 0) {
while (line.line.intersects(player.hitbox)) {
player.centerX--;
player.hitbox.setRect(player.centerX - player.WIDTH / 2, player.centerY - player.HEIGHT / 2,
player.WIDTH, player.HEIGHT);
}

} else if (line.angle < 0) {
while (line.line.intersects(player.hitbox)) {
player.centerX++;
player.hitbox.setRect(player.centerX - player.WIDTH / 2, player.centerY - player.HEIGHT / 2,
player.WIDTH, player.HEIGHT);
}
}
}


Overall, it works pretty well. There is, however, one problem I haven't been able to fix. When the player collides on a place where a wall and the ground meet, both the ground and wall collisions are executed, however, only one should be.

The result is that the player is abruptly pushed off a cliff when approaching one, or that the player is abruptly moved up when jumping alongside a cliff.

When approaching a cliff:

After one step to the right:

I've been able to come up with a method to determine which collision should be executed:

if (player.hitbox.getMaxY() - player.speedY > line.line.getY1())
// execute wall collision only
if (player.hitbox.getMaxY() - player.speedY <= line.line.getY1())
// execute ground collision only


However, I haven't been able to come up with how to implement this. I can't check all lines for collision first and execute the collision later, as the collision is executed per line. Does anyone know how I can fix my collision system?

P.S. I'm a beginning game developer, so my collision detection system might be bad or inefficient. If there's a better way to do this, that doesn't have the same problems, I'd love to hear about it. Please keep in mind, though, that I'm trying to keep the code simple and efficient.

• Instead of executing the collision per line, you could try saving the collision information - whether it is with a wall or with the ground, and how the player would move in response. When another collision is found, decide whether or not it replaces the saved one by using your method. After the loop, apply the collision response (if any collision was found). May 2, 2017 at 18:03
• I've already gone over this, but it wouldn't work since I use this: while (line.line.intersects(player.hitbox)), meaning that the only way for me to determine the distance the player needs to be moved is by constantly updating it's position. I can't wait till the end. As I said in the last lines of my question, if my system is bad or inefficient, please tell me how to do it differently. Could you give me an example on how to work this out, and submit that as an answer? Anyways, thanks for replying. I guess it would be better for me to move on to libGDX or another engine. May 2, 2017 at 18:34
• I see, you want to intentionally move the player after each intersection. That wasn't clear to me from your original question. I'll write up an answer with a possible solution. May 2, 2017 at 19:29

I think the key to fixing this situation without writing all new collision code is to identify the "cliff" situation while inside playerCollision().
The second step is inside playerCollision(), where you need to detect that the player is touching a cliff endpoint. This is also pretty simple, just test whether each line endpoint is part of a cliff, and if it is test whether the player collision shape contains that endpoint. If both are true, then the player is on a cliff edge.
Note 2: Your collision code seems fine, especially for small levels like your example image. If levels get larger and the collision code becomes too slow, you can look for ways to optimize the outer loop and still keep playerCollision() as it is.