Jacek Pietal
Jacek Pietal

Reputation: 2019

how to prevent [circle] body from sliding into 0px gaps between static bodies

So I have this body that is a circle collider

and it has sometimes a big velocity

the problem is that the tiled map of the boundaries is made of small tiles

and at high velocity the body goes through it

here is my config of all bodies:

const config = {
  inertia: Infinity, // do not spin
  friction: 0, // X*100% stop on hit
  frictionAir: 0, // X*100% slow on move
  restitution: 0.5, // bounce X*100% on hit
  collisionFilter: this.level.getCollisionFilter(), // default collision filter
  isStatic
}

...

getCollisionFilter (key = null) {
  switch (key) {
    case 'fly':
    return {
      category: 0x0008,
      mask: 0xFFFFFFF1,
      group: -1
    }
    case 'items':
    return {
      category: 0x0004,
      mask: 0xFFFFFFF1,
      group: -1
    }
    case 'woda':
    return {
      category: 0x0002,
      mask: 0xFFFFFFFF,
      group: -1
    }
    default:
    return {
      category: 0x0001,
      mask: 0xFFFFFFFF,
      group: 0
    }
  }
}

```

woda means water if it's of any relevance

this is between the default and woda

Upvotes: 4

Views: 855

Answers (1)

isp-zax
isp-zax

Reputation: 3873

The problem is that matter.js you are using has no continuous collision detection. It has been a feature request for a few years. Now that doesn't mean there is nothing you can do. There is some code in the issue description itself which is probably the cheapest way of fixing issue with going through rectangular boundaries:

It detects if a body is outside the world bounds and then reverses the velocity and translates the body back

Alternatively, this post gives a few ideas.

If you want to implement something yourself, I'll try to explain continuous collision detection algorithm.

Basically, for each moving object in your scene you have to calculate moment of next collision within the fraction of the frame 0<t0<1, then advance positions to this moment t0 within the frame, update velocities due to collision and proceed further to the next collision t0<t1<1, until you reach time of tn=1 (end of frame), making sure you don't get stuck in a the middle of the frame due to rounding of calculation or "cornered" objects. For spherical colliders, that is usually done by using capsule vs capsule (for pairs of objects) intersection and capsule vs box for the boundaries.

You can also cheat by having multiple hidden frames at a slower speed:

  • take highest object velocity
  • take smallest object collider radius
  • divide highest velocity by smallest radius of your colliders and get 'slowdown scale' rounded it to an integer
  • slow down all the objects in the scene by that integer 'slowdown scale' and update scene 'slowdown scale' times, without redrawing the screen
  • redraw the screen only once with result of 'slowdown scale' updates and you should get same positions as without slowdown, but respecting collisions

Good luck colliding!

Upvotes: 3

Related Questions