## Monday, June 14, 2010

### Reflective Collisions

‹prev | My Chain | next›

I added initial "bouncy" collisions into my (fab) game yesterday. The "bounce" easing baked into raphaël.js made it fairly easy. One thing missing, however, was bouncing from any direction. The collision bouncing only worked when colliding into something from the right.

To get this working, I need to record the direction in which the player is walking. Bah! I have grown to hate calculating angles from browser coordinates. Calculating angles is hard enough, but add in the complexity of doing so when the y-coordinates increase down the page and, well, bah!

I am already calculating the distance a player is walking along with the differences in x and y position:
`Player.prototype.walk_to = function(x, y) {  var p = "M"+ Math.floor(this.x) + " " + Math.floor(this.y) +          " L" +     x + " " +      y;  var x_diff = x - this.x;  var y_diff = y - this.y;  var distance = Math.sqrt(x_diff * x_diff + y_diff * y_diff);  var time = Player.time_to_max_walk * ( distance / Player.max_walk );  this.avatar.animateAlong(p, time);  this.x = x;  this.y = y;};`
With that information, I can calculate the the x and y changes if the distance were a single pixel:
`Player.prototype.walk_to = function(x, y) {  var p = "M"+ Math.floor(this.x) + " " + Math.floor(this.y) +          " L" +     x + " " +      y;  var x_diff = x - this.x;  var y_diff = y - this.y;  var distance = Math.sqrt(x_diff * x_diff + y_diff * y_diff);  this.direction = {x: x_diff/distance, y: y_diff/distance};  var time = Player.time_to_max_walk * ( distance / Player.max_walk );  this.avatar.animateAlong(p, time);  this.x = x;  this.y = y;};`
Hopefully, that will be enough to reverse direction on collision. Could it be as easy as moving in the opposite direction with a multiplier that assures that I move beyond an avatar's boundary?
`Player.prototype.bounce_away = function() {  this.mid_bounce = true;  var x = this.x - 2*Player.radius*this.direction.x,      y = this.y - 2*Player.radius*this.direction.y;  var self = this;  this.avatar.animate({cx: x, cy: y}, 500, "bounce",                      function(){self.mid_bounce = false;});  this.x = x;  this.y = y;};`
Indeed, that does the trick. I have nice bouncy collisions no matter the direction of approach:

Best of all: no `atan2` calculations required!

Day #134