Saturday, May 8, 2010

Keeping the Investors Happy with Firefox Support

‹prev | My Chain | next›

Tonight I need to to obtain buy-in from my investors... my kids. Unfortunately, they still use Firefox. I have developed so far on Chrome exclusively. When I tried to show my kids how things are working so far... well, I was a bit embarrassed.

After refactoring a bit, I get to the point that can fix things for Firefox. The view-only version works (the right window below):



The problem only shows up when I try to control the the game from Firefox. So the problem is not with the <canvas> rendering, rather with the handling of the mouse events. Happily, I still have console.debug output that Firebug picks up:
x_diff: NaN, y_diffNaN, angle: NaN        player.js (line 32)
Tracing that back, I find the source of the trouble is in the event handling of my Player:
Player.prototype.notify = function(evt) {
switch(evt.type) {
case "click":
this.stop();
this.walk_to(evt.offsetX, evt.offsetY);
this.notify_server({id:this.id,x:evt.offsetX, y:evt.offsetY});
break;
}
};
The trouble in there is the use of offsetX/offsetY, which varies between browser implementations. jQuery normalizes the location of events on the page in event.pageX and event.pageY. That is not quite what I need. Instead what I want is the coordinate of the event inside my <canvas> room.

To get that, I need the offset() of the <canvas> element relative to the page. If that is offset 8 pixels from the top and 8 pixels from the side of the page, then I can subtract 8 pixels from the event's pageX and pageY to get the <canvas> coordinate.

My worry here is that I do not want to couple the Player and the Room more than necessary. If possible, I want to notify the Player of an event such that the Player need only pull the x-y coordinate from the event in order to act. Given that reasoning, it sounds as if the best place to put this is in the Room:
Room.prototype.decorate_event = function(evt) {
return {
type: evt.type,
x: evt.pageX - $(this.canvas).offset().left,
y: evt.pageY - $(this.canvas).offset().top
};
};
I can then pass that "decorated" event to the Player, who is a subscriber to events on the <canvas> board:
Room.prototype.init_events = function() {
var self = this;
$(this.canvas).click(function(evt) {
var decorated_event = self.decorate_event(evt);
self.subscribers.forEach(
function(subscriber) { subscriber.notify(decorated_event); }
);
});
};
After updating Player to get the x-y coordinate from event.x and event.y, I have the code working in Firefox and Chrome. Hopefully my investors will be pleased.

Day #97

No comments:

Post a Comment