Thursday, August 30, 2012

More Physijs Collisions

‹prev | My Chain | next›

I need to focus more on writing Gaming JavaScript for the next two nights. So the hope is that I can keep these posts relatively short. That's the hope anyway.

I finally came to an understanding with Physijs last night. I was able to use relative frames of reference to mark obstacles in my Three.js game. A second step then places the actual obstacles in the Physijs scene.

Tonight, I undertake a bit of code cleaning (I hope to include this game in the beta release tomorrow). While doing so for a bit, I notice that I am no longer seeing collisions. What could I possibly have done to cause this?

I am able to figure this out with a well-placed console.log() in my obstacle drawing function:
function drawObstacles() {
  markers.forEach(function(marker) {
    var position = marker.matrixWorld.multiplyVector3(new THREE.Vector3());

    var obstacle = new Physijs.BoxMesh(
      new THREE.CubeGeometry(
        40, 20, 40
      ),
      Physijs.createMaterial(
        new THREE.MeshNormalMaterial()
      )
    );
    obstacle.position.y = 21;
    obstacle.position.x = position.x;
    obstacle.position.z = position.z;
    scene.add(obstacle);

    obstacle.addEventListener('collision', function(object) {
      if (object == raft) console.log("Game Over!!!!")
      else {
        console.log(object);
      }
    });
  });
}
On the off chance that something else is happening, I have the else block to identify unexpected collisions with my obstacles. The happy path here should be that, when my raft collides with an obstacle, I ought to see the "game over" message.

Only I see no collision:


Well, I see lots of collisions, but not the "game over" kind. These are with plane objects that comprise the river. And they all happen within a second or so of loading the page.

What I suspect is happening is that the obstacle, whose height is 20, is falling from its height of 21 onto the water and colliding with the river. And once collided, Physijs is not registering subsequent collisions.

Based on a comment from Chandler Prall, I had expected no further collisions if the obstacle was colliding with the same object (or a different part of the same compound shape). But it seems that subsequent collision events are not fired if any object is mid-collision with any object.

Fortunately, this does not cause me much hardship. I can prevent the obstacle from colliding with the water object by making it static (zero mass):
function drawObstacles() {
  markers.forEach(function(marker) {
    // ...
    var obstacle = new Physijs.BoxMesh(
      new THREE.CubeGeometry(
        40, 20, 40
      ),
      Physijs.createMaterial(
        new THREE.MeshNormalMaterial()
      ),
      0
    );
    // ...

    obstacle.addEventListener('collision', function(object) {
      if (object == raft) console.log("Game Over!!!!")
      else {
        console.log(object);
      }
    });
  });
}
With that, I see no else collisions logged, but do see the desired "game over":


That will work fine for me in this case. Plane collisions are a bit weird anyway, so avoiding it entirely works. Waiiit....

That is what I changed that caused my problems in the first place. I had converted the obstacle markers from boxes to planes thinking that this would prevent the raft from bouncing over the markers accidentally. I also figured that I only needed to mark position and that a plane could do just as easily as a box could.

I think I'll ultimately stick with static obstacles. The less the physijs engine needs to do the better—20 new obstacles added to 20 river segments taxes the CPU momentarily at the game outset.

Day #494

No comments:

Post a Comment