Chapter 4, Exercise 3 – Bouncing Bubbles

The kaboom jQuery plug-in drops the bubbles off the bottom of the screen, but what would happen if you made the bubbles bounce when they hit the bottom? Amend kaboom.jquery.js so the bubbles bounce instead of drop off the screen. You’ll need to reverse their dy values and scale them down each time they bounce to mimic some of the bounce energy being absorbed; otherwise, they’ll just bounce back to the same height. The bubbles should be removed from the DOM only when they’ve bounced off either the left or the right edge of the screen, so you’ll also need to ensure that the value of dx isn’t close to zero, or they’ll never disappear.

We’ll adjust how gravity works inside jquery.kaboom.js to simulate a bounce effect. We’re going to set a floor of the game at 230 pixels above the maximum height at which we stop moving objects inside the moveAll function, and also configure a maximum number of bounces. Then, when we detect a bubble has moved below the floor, if it hasn’t exceeded a bounce counter, we’ll move it back above that base and change its vertical speed. We’ll also add in some damping so that bubbles don’t bounce back to exactly the same height from which they fell:

jQuery.fn.kaboom = function(settings){
  var config = $.extend({}, defaults, settings);
  if(toMove.length == 0){
    setTimeout(moveAll,40);
  };
  var dx = Math.round(Math.random() * 10) - 5;
  var dy = Math.round(Math.random() * 5) + 5;
  toMove.push({
    elm : this,
    dx : dx,
    dy : dy,
    x : this.position().left,
    y : this.position().top,
    config : config,
    numBounces : 0
  });
};
var moveAll = function(){
  var frameProportion = 1;
  var stillToMove = [];
  for(var i=0;i<toMove.length;i++){
    var obj = toMove[i];
    obj.x += obj.dx * frameProportion;
    obj.y -= obj.dy * frameProportion;
    obj.dy -= obj.config.gravity * frameProportion;
    if(obj.y < obj.config.maxY - 230 && obj.numBounces++ < 3) {
      var distOver = obj.y - obj.config.maxY + 230;
      obj.y -= 2*distOver;
      obj.dy *= -.5;
    }
    if(obj.y < obj.config.maxY){
      obj.elm.css({
        top : Math.round(obj.y),
        left : Math.round(obj.x)
      });
      stillToMove.push(obj);
    }else if(obj.config.callback){
      obj.config.callback();
    }
  };
  toMove = stillToMove;
  if(toMove.length < 0)
    setTimeout(moveAll,40);
};

Leave a Reply