Tuesday, June 15, 2010

Initial Bounce

‹prev | My Chain | next›

Up tonight in my (fab) game: fixing a bug in the client-side, raphaël.js collision code.

When players first enter a room, they always start in the middle. If a player is already in the room but has yet to move when I enter, then I am already in collision. I would expect one of two things to happen in this situation: (1) I bounce away immediately or (2) I move through the other player as if it is not there. Right now, (2) happens, but subsequent collisions fail to register.

I have a hard time tracking this one down because I clearly stop() the animation before bouncing away from the collision:
    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) {
self.stop();
self.bounce_away();
}
And in bouce_away(), I set mid_bounce so that collision detection does not fire until the bounce is done:
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;
};
My problem is that the finish bounce callback never fires leaving the player mid-bounce eternally.

Initially, I try to resolve this problem in the collision detection by moving the mid_bounce boolean in there. This has no effect, however, and I eventually conclude that the onAnimation callback in raphaël fires before the animation starts. This causes a problem because I stop the animation and try to bounce, but then immediately start the first frame of my animation. This has the effect of completely ignoring the bounce away method, aside from setting mid_bounce to be perpetually true.

My resolution is a bit of a hack. The bounce animation never concludes, but I need to be sure that mid_bounce gets set to false. So I add a simple setTimeout that will fire after the bounce:
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;});
setTimeout(function(){ self.mid_bounce = false; }, 1000);

this.x = x;
this.y = y;
};
With that, I can enter the room, move about, and still get my bouncy collisions:

video

Day #135

2 comments:

  1. Chris, what are you using to record your desktop?

    ReplyDelete
  2. I pretty much follow this: http://remi.org/2009/04/16/how-i-record-my-screencasts (though I've been using the gtk-recordMyDesktop more recently).

    ReplyDelete