The players in my (fab) game are suffering some serious injuries:
Loss of limbs is not occurring immediately or even after a long time roaming about the game room. No, the player's legs are becoming detached after bouncing into each other repeatedly:
Crazy. Where does one even start to track down a problem like that?
Well, since I have made changes to it recently and since it is controlling the player walking animation, I start with animate-frames, my animation plugin for raphaël.js.
In there, I add an
offsets()
method to the individual frames making up the animation. The offsets calculate the x-y differences between the various strokes of the pen that comprise the frame (e.g. a pen stroke for a foot, leg, body, etc). The x-y differences are between each of the elements and the last element.Frame.prototype.offsets = function() {The individual offsets should always remain the same—a player's foot should stay 16 pixels away from the body if it was first drawn 16 pixels away. Looking at the first offset when the player first enters the room, I find:
var diffs = []
,main = this.getBBox();
for (var i=0; i<this.elements.length-1; i++) {
var box = this.elements[i].getBBox();
diffs.push([main.x - box.x, main.y - box.y]);
}
return diffs;
};
[After moving the player about the room for a bit, I find:
0: -6.787272029958575
1: -16.76693459682566
]
[Almost exactly the same. I am not sure about the differences (in the 10,000ths decimal place). Is that caused by simple rounding errors? Maybe timing differences between
0: -6.787412453957089
1: -16.766913780265497
]
stop()
calls of individual elements is sufficient to cause that problem? Is that small a change even a problem?Before investigating further, I try colliding my player with another player in the room. Then, I check the offsets again:
[That is a much more dramatic change. Banging players together some more furthers the offset change:
0: -6.039369453957079
1: -16.56494217026568
]
[Whatever the problem, it seems that the bouncing of players is the best place to continue my investigation.
0: -5.144486633957058
1: -16.511516330265806
]
But wait...
If I know the expected offset of the individual elements in a frame, can I use them to sync the frame back up to where it is supposed to be?
I think that I can run through each offset, calculate the difference between the current and original offset, then
translate
the affected frame element by the tiny offset it needs to get back to the right place:Frame.prototype.tighten = function() {Yay! That works just as expected. A player falling to pieces gets put back together (tightened up) with a single call.
var offsets = this.offsets();
for (var i=0; i<offsets.length; i++) {
var x_diff = offsets[i][0] - this.original_offsets[i][0]
,y_diff = offsets[i][1] - this.original_offsets[i][1];
this.elements[i].translate(x_diff, y_diff);
}
};
To put that to practical use, I call it at the end of the
translate()
method of each Frame
object. And, just like that, my players keep all of their limbs.That is not an entirely satisfactory solution—I never did solve why limbs were flying away in the first place. Rounding errors seems a reasonable explanation, but reasonable explanations do not elicit learning the way that digging deep does. Something to investigate another day.
Day #244
No comments:
Post a Comment