3
\$\begingroup\$

I have a render loop. In it I always call the update() method which moves all the objects in their own directions. Then after that I call checkCollision on each object with each object like that:

for (GameBodyObject gbo1 : objects) {
   for(GameBodyObject gbo2 : objects) {
      if(!gbo1.equals(gbo2)) {
         gbo1.checkCollision(gbo2);
      }
   }
}

btw I am using Circle as collider

now in checkCollision I first check if they collide and then if yes I calculate the displacement like this:

if(CircleCollider.collide(p1, r1, p2, r2)) {
   double totalR = r1 + r2;
   double a = new Vector(p1.getX() - p2.getX(), p1.getY() - p2.getY()).getAngle();

   double intersection = Math.abs(totalR - p1.distance(p2));

   return new Vector(Math.cos(a) * intersection, Math.sin(a) * intersection);
} else {
   return new Vector(0, 0);
}

then I move the GameBodyObject by this displacement vector like this:

public Point moveByVector(Vector v) {
    if(v.getX() == 0 && v.getY() == 0) {
        return this;
    }
    double a = v.getAngle();
    double l = v.getLength();
    x += l * Math.cos(a);
    y += l * Math.sin(a);
    return this;
}

However I get a bouncing effect so the one gameBodyObject goes into another gameBodyObject and back and again into that gameBodyObject and back. I want it to stop, not to bounce.

How could I do that?

One way that come up to my mind is that I will check for collision in the update() function directly and if it occurs I won't move the guy, but then it may get stuck if he runs into another gameBodyObject...

How should I deal with that?

(BTW did you play Dota 2? I want the mechanics similar to that game so that one player can block another player and trees are static so they don't move so the player can't push them instead he stops...)

\$\endgroup\$
  • \$\begingroup\$ Dota almost guaranteed doesn't use any sort of physics engine to handle collisions. It's probably all done tile-by-tile / navmesh during the broadphase and very simple bounding boxes / ellipses during the narrow-phase. How they handle collisions is by not handling collisions at all except for setting a flag that you cannot move in that direction. \$\endgroup\$ – Charanor Jul 31 '17 at 1:33
  • \$\begingroup\$ That's interesting, let me try to apply that \$\endgroup\$ – durisvk10 Jul 31 '17 at 12:39
  • \$\begingroup\$ Btw I don't know what tile-by-tile and navmesh means. To me Dota 2 engine and the physics is based on Warcraft III from which the Dota originally come from and there it looks like they are also using circle collider (because if you select unit you see the circle under it and if you watch carefully the two circles never intersects) @Charanor \$\endgroup\$ – durisvk10 Jul 31 '17 at 13:38
1
\$\begingroup\$

You need to check whether or not collision will occur before you transform the object. When collision is imminent change the transformation number to be small enough so that the colliding object only touches the border of the other object.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I think there's no need to move the object by small amount, I think you're right that I should not move in this direction so I am going to try to store my last position, then move, then check the collision, if it appears move back to last position, so I don't need to calculate the displacement \$\endgroup\$ – durisvk10 Jul 31 '17 at 12:57
  • \$\begingroup\$ @durisvk10: Then how close you can get to the other object depends on how fast you move and how far you are away. So when the player tries moving from another position he might be close or farther away which feels wrong. So move as far as possible would be my suggestion too. \$\endgroup\$ – Skalli Aug 1 '17 at 13:56
1
\$\begingroup\$

If you want to use collision detection to prevent movement, then don't do collision checks for everything with everything in your update loop. Do a collision check whenever you change the position of an object. Check if the destination is clear, and when it is not, don't execute the move (or alternatively, only execute it up to the collision position).

When you do this rigorously on every position change (including newly spawned entities), then there can not be a situation where two objects share the same space. But if there is some obscure corner-case where two entities sharing the same space can not be avoided, then you might want to at least allow the space-sharing entities to move away from each other. You can do that by checking for collisions with the old position of an object and then ignore any objects you find there when you check for collisions with the new position.

By the way, you can drastically improve collision detection performance by only checking collisions with objects which are close enough that they could potentially collide. So when you run into performance problems, check out data structures like spatial hashing or 2d trees which allow you to quickly get all objects in a given area.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.