Sunday, June 13, 2010

Bouncy Collisions

‹prev | My Chain | next›

I left off last night with collision detection in my (fab) game stopping the player in motion mid-collision. The problem with that is that the player continues to overlap the collision item making it impossible to move.

First up, I add a call to a newly defined bounce_away method in the collision detection code:
//...
var c_el = document.elementFromPoint(avatar.attr("cx") + 8,
avatar.attr("cy") + 8);

if (c_el != self.avatar.node &&
c_el != self.avatar.paper) {
console.debug(c_el);
console.debug(self.avatar);
self.stop();
self.bounce_away();
}
//...
I can then define the bounce_away() method such that it jumps twice the radius of a player's avatar away from the collision. Eventually, I need to bounce away in the opposite direction of the collision. For now, I just jump to the right:
Player.prototype.bounce_away = function() {
this.mid_bounce = true;
var x = this.x + 2*Player.radius,
y = this.y;

var self = this;
this.avatar.animate({cx: x, cy: y}, 500, "bounce");

this.x = x;
this.y = y;
};
I use the "bounce" easement baked into raphaël.js to hopefully give it a legitimate bouncing feel.

Unfortunately, nothing happens on collision. What's worse, the browser completely freezes. The bounce_away method is fighting against the collision detection code that is trying stop movement. The player tries to bounce away, the collision detection code stops the player and then tries to bounce away again, and so on. Bleh.

So I disable the collision detection code if the player is mid-bounce:
    var c_el = document.elementFromPoint(avatar.attr("cx") + 8,
avatar.attr("cy") + 8);

if (!self.mid_bounce &&
c_el != self.avatar.node &&
c_el != self.avatar.paper) {
console.debug(c_el);
console.debug(self.avatar);
self.stop();
self.bounce_away();
}
});
I then signal the end of the bounce in bounce_away with the callback provided by raphaël.js:
Player.prototype.bounce_away = function() {
this.mid_bounce = true;
var x = this.x + 2*Player.radius,
y = this.y;

var self = this;
this.avatar.animate({cx: x, cy: y}, 500, "bounce",
function(){self.mid_bounce = false;});

this.x = x;
this.y = y;
};
With that, I have some nice, bouncy collisions:

video

Day #133

No comments:

Post a Comment