Tuesday, September 11, 2012

Asploding and Regenerating Fruit

‹prev | My Chain | next›

Today I switch back to my simple jumping game in Three.js / Physijs. So far, I have simple movement and scoring implemented. I need to generalize the goal (to jump on fruit) and implement a game over scenario (hit the ground).

I start by copying the single fruit code into a launchFruit() function:
function launchFruit() {
  var fruit = new Physijs.ConvexMesh(
    new THREE.CylinderGeometry(20, 20, 1, 24),
    new THREE.MeshNormalMaterial({color: 0xB22222})
  );
  fruit.rotation.x = Math.PI/2;
  fruit.position.x = 200;
  fruit.position.y = 20;
  fruit.is_fruit = true;
  scene.add(fruit);
  fruit.setLinearVelocity(
    new THREE.Vector3(-1e2, 0, 0)
  );
}
New in there is the initial linear velocity from right to left (toward the player), but everything is unchanged. Next, I add a call to gameStep() after the animate() function is started:
document.addEventListener("DOMContentLoaded", function() {
  init();
  // ...

  animate();
  gameStep();
});
In gameStep(), I throw a new fruit at the player every 3 seconds (eventually, I need to add some randomization):
var step = 0;
function gameStep() {
  if ((step % (3*60)) == 0) {
    launchFruit();
  }
  
  step++;  
  setTimeout(gameStep, 1000 / 60); // process the game logic
                                   // at a target 60 FPS.    
}
That works, but after the game has been running for a while, I notice that things start to slow down in the game. The slowness is because I am tasking the game to keep track of hundreds of fruits that are no longer needed after they have rolled well off the screen.

So I include a reapFruit() call along with launchFruit():
var step = 0;
function gameStep() {
  if ((step % (3*60)) == 0) {
    launchFruit();
    reapFruit();
  }
  // ...
}
Fruit are removed from the simulation whenever a fruit is found well to the left of the screen:
function reapFruit() {
  scene.children.forEach(function (object) {
    if (object.is_fruit && object.position.x < -250) {
      console.log("removing old fruit");
      scene.remove(object); 
    }
  });
}
Last up tonight, I need to modify the player to react to collecting fruit. I also need a game-over mechanism. I can apply both as Physijs events on the game player:
  player.addEventListener('collision', function(object) {
    if (object.is_fruit) {
      console.log(object);
      score += 10;
      writeScoreBoard("Score: " + score);
      player.setLinearVelocity(new THREE.Vector3(0, 100, 0));
      scene.remove(object);
    }
    if (object == ground) {
      game_over = true;
      writeScoreBoard(
       "Game Over!<br><br>" +
        "Score: " + score
      );
    }
  });
If the player hits a fruit, my score increases, I bounce straight up, and the fruit is removed from the scene. If my player hits the ground, the game is over.

With that, I have the game more or less working. I collect points whenever I strike fruit. The game is over when I hit the ground:


I do not want to make the game overly complex, so that should about do it. If you have any suggestions for improvement, please fix and share: source code editor.


Up tomorrow, I will replace the box and circles with something a little more player and fruit like.


Day #506

No comments:

Post a Comment