0
\$\begingroup\$

Here is my collision code, any ideas on how I can improve it to fix the problem?

    public void collide(Entity entity){
    if(x + width >= entity.x && x <= entity.x + entity.width && y + height >= entity.y && y <= entity.y + entity.height){
        setShouldCollide(true);
    }else{
        setShouldCollide(false);
    }
}

enter image description here

\$\endgroup\$
4
  • 5
    \$\begingroup\$ It looks like if the objects collide, you prevent the object from moving; you should push-back the objects so that they no longer collide in order to let them move. \$\endgroup\$
    – Vaillancourt
    Aug 29, 2016 at 18:00
  • \$\begingroup\$ You should not play with enable or disable collision here. Just control that player should not move forward \$\endgroup\$
    – NightFury
    Aug 29, 2016 at 18:56
  • 4
    \$\begingroup\$ Which system are you using? add a tag. \$\endgroup\$
    – Surt
    Aug 29, 2016 at 19:32
  • 1
    \$\begingroup\$ You're getting "stuck." When you collide, you prevent motion. On the next frame, since the objects haven't moved, your still colliding. You have to prevent collision, not just react to it. (Bounce back from the wall a bit when you are about to hit it.) Search for "collision detection and response" \$\endgroup\$
    – 3Dave
    Dec 2, 2016 at 22:48

3 Answers 3

1
\$\begingroup\$

You are most likely running into problems with object interpenetration.

It is quite likely that you are implementing your movement code like this:

x += speed*Math.cos(theta)*deltaTime
y += .5 * gravity * Math.pow(delaTime,2) + speed*Math.sin(theta)*deltaTime

The problem with grid coordinates is that they are integers, so they can only round to the nearest integer pixel. The other problem is that points are essentially teleport-ing to their next position.

What can happen is that the next (x,y) position that the object "teleports" to could be inside an object in which case your physics engine stops the character. You need to have additional logic that can deal with interpenetration cases.


What do you mean by "dealing with interpenetration cases"?

Dealing with interpenetration means that you need to teleport the object outside of the collider object. You are currently implementing an Axis Aligned Bounding Box collision algorithm (using squares to check for collision). All you have to do is to modify your collision algorithm a bit.

public void collide(Entity entity){
    if(x + width >= entity.x && x <= entity.x + entity.width && y + height >= entity.y && y <= entity.y + entity.height){
        //we know the object is interpenetrating at some point within our entity

        //set x,y coordinate of moving object to the nearest point outside of the box.
        //you will have to decide what is "acceptable visual behavior"
        //closer approximations will cause greater performance hits
        //
        //iex. use distance formula to teleport the object outside the entity
        //relative to the closest corner
        //
        //or
        //
        //Draw an imaginary line that represents the vector that the object came
        //into the object and follow that line backwards until you are no longer colliding with the object.

    }else{
        //object did not collide
    }
}

Additional note on AABB

You may want to consider using the built in Rectangle Class and leverage it's built in .intersects(Rectangle r) which implements a AABB algorithm.

\$\endgroup\$
0
\$\begingroup\$

Just have bools like "canMoveForward" or "canMoveBackwards" or have one global bool that controls movement. However you want to implement it, when you detect collision, simply stop the player from moving forward. Good luck!

\$\endgroup\$
0
\$\begingroup\$

I am not sure how you coded your player, however since it is 2D perhaps you can make collision checks for left and right and maybe even top and bottom if needed.

If the collision on the left side is checken then the player can only move towards the right and not the left. If for example left and right have a collision then the player can only move up or down.

I think it is a simple yet effective solution. The checks would need to be placed at your movement codes, for example the player can only move left when the left collision boolean is false.

\$\endgroup\$

You must log in to answer this question.

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