Saturday, May 22, 2010

Hitting the Raphaël.js Target

‹prev | My Chain | next›

Last night, I teased out a chat system in my (fab) game. I left a tracer bullet, in the form of a javascript alert(), in place. Tonight, I need to finish that off.

The tracer bullet was left in the PlayerList, which is where the fab.js backend interfaces with clients via comet. In this case, the backend makes a call to player_say method:
PlayerList.prototype.player_say = function(attrs) {
alert(attrs.id + " says " + attrs.say);
};
Removing the tracer bullet, the target that I really want to hit is the say method on the Player itself:
PlayerList.prototype.player_say = function(attrs) {
this.get_player(attrs.id).say(attrs.say);
};
I define the say method as:
Player.prototype.say = function(message) {
this.balloon = this.drawable.paper.text(this.x, this.y - 10, message);
};
With that, I have a speech balloon 10 pixels above the drawable version of the player. I'm not quite done yet because I need that speech balloon to move along with the drawable version of the player as it moves about the room.

Shadowing the drawable player is the responsibility of the the attach_drawable method, which makes use of the onAnimation method from raphaël.js:
Player.prototype.attach_drawable = function(drawable) {
var self = this;
this.drawable = drawable;
this.label = drawable.paper.text(this.x, this.y + 10, this.id);

drawable.onAnimation(function(){
self.label.attr({x: drawable.attr("cx"), y: drawable.attr("cy") + 10});
});

};
Right now, I am shadowing the player with its name. To shadow with the speech balloon (if present), I add:
Player.prototype.attach_drawable = function(drawable) {
var self = this;
this.drawable = drawable;
this.label = drawable.paper.text(this.x, this.y + 10, this.id);

drawable.onAnimation(function(){
self.label.attr({x: drawable.attr("cx"), y: drawable.attr("cy") + 10});

if (self.balloon) {
self.balloon.attr({x: drawable.attr("cx"), y: drawable.attr("cy") - 10});
}

});
};
I do not want the speech balloon to stick around indefinitely, so, back in the say method, I add a timer to remove it after 10 seconds:
Player.prototype.say = function(message) {
var self = this;

this.balloon = this.drawable.paper.text(this.x, this.y - 10, message);
setTimeout(function(){self.balloon.remove();}, 10*1000);
};
Lastly, I need to remove a previous speech balloon if a new message is sent:
Player.prototype.say = function(message) {
var self = this;

if (this.balloon) this.balloon.remove();

this.balloon = this.drawable.paper.text(this.x, this.y - 10, message);
setTimeout(function(){self.balloon.remove();}, 10*1000);
};
With that, I do believe that my chat system is more or less complete:



Up tomorrow: maybe a tweak or two, but I heard tell of Cucumber integration with v8 (the javascript engine on top of which fab.js and node.js are built). I do believe that will prove irresistible for me.

Day #111

No comments:

Post a Comment