I've been at this for 2-3 weeks now and I still can't manage to have a proper collision detection. I have created a maze using rectangles. I want my object (which is in a Rectangle) to stop whenever my object collides with any wall and be able to move anywhere (or slide down a wall). My walls (the rectangles) have negative coordinates like the following:
shapeRenderer.rect(0.9f, 12, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); //NORTH
shapeRenderer.rect(1, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // WEST
shapeRenderer.rect(2, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // EAST
shapeRenderer.rect(0.9f, 11, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); // SOUTH
I'm currently using an overlaps method that I've found in SO. Here's the method that's in my CollisionManager class:
private boolean overlaps (Rectangle collision, Rectangle wall) {
return Math.min(collision.x, collision.x + collision.width)
< Math.max(wall.x, wall.x + wall.width)
&& Math.max(collision.x, collision.x + collision.width)
> Math.min(wall.x, wall.x + wall.width)
&& Math.min(collision.y, collision.y + collision.height)
< Math.max(wall.y, wall.y + wall.height)
&& Math.max(collision.y, collision.y + collision.height)
> Math.min(wall.y, wall.y + wall.height);
}
I have a function which saves all position moves made by the object. Thus, when a collision occurs, the object restores to the previous move before the last move (since the last move is when the collision occured) (example below):
private void overlapsTop(Entity object, Rectangle wall){
Rectangle r = new Rectangle();
if(spritePositions.size() != 0){
r = spritePositions.get(spritePositions.size()-1);
}
object.update(r.x, r.y, r.width, r.height);
object.getObject().setBounds(r.x, r.y, r.width, r.height);
spritePositions.clear();
}
Additional information: I'm moving my object like this:
public void moveRight(){
position.x += 1f;
update();
}
public void update(){
boundingRectangle.set(position.x, position.y, object.getWidth(), object.getHeight());
}
Where I'm stuck is my overlaps function (the one I've found in SO). It works most cases; yet, for example, if the object moves near a wall on the right and touches it, the function returns true and everything gets executed. But let's say if I slide along the wall and move directly down and that there are no walls, the object stops at one point because it detects a collision between the bottom of the object and the top of a wall (when there's none) and a collision between the right of the object and the left of a wall.
I'm trying to find another solution for this. I just want my object to stop at any wall and be able to move (or slide down a wall) without suspecting that there might be a collision where there are no walls nearby. I feel that I'm very close to a solution, but I would need a little bit of extra help.
UPDATE
I've updated the moveRight function and the update function. @Adrian Shum and @Matthew Mark Miller I've made everything now with an integer (meaning instead of 0.01f, I use 1f).
Thus the following code that I use to move the object is like this:
if(Gdx.input.isKeyPressed(Keys.RIGHT)){
if(collisionManager.canSpriteNotMoveRight(object)){
object.stopGoingRight();
}else{
object.moveRight();
}
}
In my collisionManager class, the function stopGoingRight is the following:
public void stopGoingRight(){
position.x -= 1f;
update();
}
So far, so good. When the object collides with the wall, the object stops and bounces back. That's good. But I have another problem (which is irritating) that I'll try to describe the best I can. If, for example, I keep moving the object up to a wall, the object will bounce back many times from that wall; if I stop pressing the up key, the object will sometimes stay stuck within the wall. Thus what happen is when I press the down key, it'll go up instead of going down (or if I press left, the object will go right instead of going left) because the overlaps function gets executed (since both object and the wall intersect).
Is there a way for me to solve this? It seems as though Libgdx isn't perfectly well-suited to handle this kind of collision detection, but I'm just far into deep in building my game right now.
overlaps
, so that instead of writinga < b
, writea < b-EPSILON
– Adrian Shum