Loading...
Logo
Processing Forum
I'm working on a little platformer game, and in PJS objects appear to be bouncing off of invisible walls - a behavior that does not appear in Java Mode. I suspect the problem lies in how Javascript is (mis)handling the collision code, but I'm just not seeing it:

Copy code
  1.   PVector collisions(PhysicsThing thing) {
  2.     PVector force = new PVector(0,0);
  3.     Circle c = thing.circ;
  4.     for (int i=0; i < segments.size(); i++) {
  5.       LineSegment s = (LineSegment) segments.get(i);
  6.       if (PVector.dist(s.a, thing.location) < cellSize*2) {
  7.         if (collides(c, s)) {
  8.           PVector f = normalVector(c, s);
  9.           f.mult(0.2);
  10.           PVector proj = project(thing.velocity, PVector.sub(s.a, s.b));
  11.           proj.mult(0.1);
  12.           f.add(proj);
  13.         force.add(f);
  14.         }
  15.       }
  16.     }
  17.     force.normalize();
  18.     force.mult(0.5);
  19.     return force;
  20.   }
  21.   
  22.   boolean collides(Circle c, LineSegment s) {
  23.     return magSq(normalVector(c, s)) < c.radius*c.radius;
  24.   }
  25.   
  26.   PVector normalVector(Circle c, LineSegment s) {
  27.     PVector seg = PVector.sub(s.b, s.a);
  28.     PVector proj = project(PVector.sub(c.location, s.a), seg);
  29.     
  30.     if (PVector.angleBetween(proj, seg) >= 3.14) {
  31.       return PVector.sub(c.location, s.a);
  32.     } else if (magSq(proj) > magSq(seg)) {
  33.       return PVector.sub(c.location, s.b);
  34.     } else {
  35.       return PVector.sub(c.location, PVector.add(s.a, proj));
  36.     }
  37.   }
  38.   
  39.   PVector project(PVector v, PVector onto) {
  40.     PVector proj = onto.get();
  41.     proj.normalize();
  42.     proj.mult(PVector.dot(v, proj));
  43.     return proj;
  44.   }

Replies(3)

So... it works fine when all the line segments involved are orthogonal. When they are even slightly diagonal, however, things collide with them as if the line segments extend beyond the end points. This despite the fact that when these same line segments are drawn on the screen, they don't behave this way. Is this perhaps a problem with the conversion to Javascript or a problem with processing.js itself? (The PVector code looks okay in processing.js, but I'm not a javascript expert.)
I finally figured it out by rewriting each PVector function myself, one by one. The problem is with the way Processing.js handles PVector.angleBetween().

Old version:
Copy code
  1. if (PVector.angleBetween(proj, seg) >= PI)

New version:
Copy code
  1. if (abs(heading2D(proj) - heading2D(seg)) >= PI)

Where:
Copy code
  1. float heading2D(PVector v) {
  2.   return atan2(v.y, v.x);
  3. }

So that's why things collided beyond the endpoints of the line segments: angleBetween wasn't returning the value that the sketch needed to determine if the projected point vector was in the same direction or the opposite direction as the line segment vector.
I had a similar problem to convert Java to JS due to bugged PVector's methods too!
Only that time was rotate() and sub() w/ 3 arguments.

You can see my post using rotate() and 3-parameter sub() in Java below:

And "fixed" for working in online JS here. Using cos() + sin() instead of rotate() & 2-parameter sub():