Monday, July 26, 2010

Players Shouldn't Explode

‹prev | My Chain | next›

Thanks to my awesome javascript debugging skills, I solved one problem with raphael-animate-frames, my plugin for raphaël.js that animates SVG frames. Today, I hope to get my player walking properly in reaction to clicks. Last I left it, my player was blowing up in response to clicks:



In the Player.walk_to() method, I am calling the raphael-svg-frames translate() method to walk the player about:
Player.prototype.walk_to = function(x, y) {
// calculate time
this.avatar.translate(x, y, time);

this.x = x;
this.y = y;
};
So my first tactic in resolving the player blow-out is to try calling translate() in the console:



Dang it! I hate it when things works when I expected them to fail.

Next up, I try calling walk_to directly. That still fails. So the error must be something that I am doing in my game code, not in the raphael-svg-frames code.

Through clever use of console.debug, I track this down to the lack of an attrs property on the frames object. The walk_to method is using an invalid this.x valid. This bit of debug code:
Player.prototype.walk_to = function(x, y) {
this.stop();

console.debug("x_o: " + this.x + ", y_o: " + this.y );
console.debug(" x: " + x + ", y: " + 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 );

console.debug("[walk_to] calling translate on avatar " + time);
this.avatar.translate(x, y, time);

this.x = x;
this.y = y;
};
Produces undefined x-y output in the console:
x_o: undefined, y_o: undefined
x: 124, y: 103
That ultimately produces an invalid time local variable. The question is, where does this.x and this.y get set to undefined? Besides walk_to(), that is.

The answer is the stop() method called at the very start of walk_to():
Player.prototype.stop = function () {
this.avatar.stop();

this.x = this.avatar.attrs.cx;
this.y = this.avatar.attrs.cy;
};
The attrs attribute is undefined on the raphael-svg-frames object. It is hard keeping a property in sync with movement. For now, I simply switch to a call to the get bounding box:
Player.prototype.stop = function () {
this.avatar.stop();

this.x = this.avatar.getBBox().x;
this.y = this.avatar.getBBox().y;
};
That finally resolves my exploding player issue:



I am happy to stop there for the night. I likely removed bunches of code tracking this down, so tomorrow, I will see about putting it all back together.


Day #176

No comments:

Post a Comment