Up tonight, I need to fix a bug when multiple players are in the room. When I first log in as a new player, my avatar has wandered off:
If I click to move in the room, my player zips up from the bottom right corner. Oddly enough, the first player to enter the room, and hence the first player broadcast by the server, is drawn correctly. All other players wander off. Again, oddly, their labels, which should be tied to their positions are where they are supposed to be.
After much searching I track the problem down to the
Player.walk_to
client side method. I suspect that the distance calculation that I added recently is throwing off the timing of various callbacks, resulting in an incorrect value:Player.prototype.walk_to = function(x, y) {To try to prove it, I add some console debugging to see what the
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;
};
Player
thinks its x-y coordinates are and what the raphaël.js circle / avatar thinks the center x-y coordinates are:Player.prototype.walk_to = function(x, y) {Unfortunately, this tells me nothing of use. The
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 );
console.debug("id: " + this.id + ", x : " + x + ", y: " + y);
console.debug("id: " + this.id + ", x : " + this.x + ", y: " + this.y);
console.debug("id: " + this.id + ", cx : " + this.avatar.attrs.cx + ", cy: " + this.avatar.attrs.cy);
console.debug("id: " + this.id + ", x_diff : " + x_diff + ", y_diff: " + y_diff);
console.debug("walk: " + p + ", distance: " + distance + ", time: " + time);
this.avatar.animateAlong(p, time);
this.x = x;
this.y = y;
};
Player
and raphaël coordinates always match up.I struggle with for a long time (the sheer number of debug statements already in there should be a indicator for that) before realizing that the coordinates might align when the code is first evaluated, but could change very shortly thereafter. So I add a
setTimeout
to evaluate the same debugging after 100 milliseconds:Player.prototype.walk_to = function(x, y) {With that, I finally find my discrepancy. That is one of the troubles with heavily functional code, sometimes problems are not immediately evident. I do think I will add the
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 );
console.debug("id: " + this.id + ", x : " + x + ", y: " + y);
console.debug("id: " + this.id + ", x : " + this.x + ", y: " + this.y);
console.debug("id: " + this.id + ", cx : " + this.avatar.attrs.cx + ", cy: " + this.avatar.attrs.cy);
console.debug("id: " + this.id + ", x_diff : " + x_diff + ", y_diff: " + y_diff);
console.debug("walk: " + p + ", distance: " + distance + ", time: " + time);
this.avatar.animateAlong(p, time);
var self = this;
setTimeout(function() {
console.debug("id: " + self.id + ", x : " + x + ", y: " + y);
console.debug("id: " + self.id + ", x : " + self.x + ", y: " + self.y);
console.debug("id: " + self.id + ", cx : " + self.avatar.attrs.cx + ", cy: " + self.avatar.attrs.cy);
console.debug("id: " + self.id + ", x_diff : " + x_diff + ", y_diff: " + y_diff);
console.debug("walk: " + p + ", distance: " + distance + ", time: " + time);
}, 100);
this.x = x;
this.y = y;
};
setTimeout
debug statement to my bag of Javascript tricks.I devise a simple hack to resolve this issue, but I think a bit of refactoring is in order to make the code less susceptible to woes like this in the future. I will pick up with that tomorrow.
Day #130
No comments:
Post a Comment