Tonight, I continue working through a new feature in animate-frames plugin for raphaël.js. This plugin iterates through a series of raphaël/SVG frames as the frames move about the paper. I am using this in my (fab) game to draw and animate players as they move about the game room:
I found last night that it is not possible to animate position changes of elements drawn from the
path()
method (which my players are). I would like to animate collisions between elements.My plan tonight is to hide all of the frames, then draw a replacement circle that bounces. At the end of the bounce, I will remove the bounced circle and re-show one of the frames. To accomplish this, I add a third parameter to the
animate()
method in animate-frames—the same parameter that is in core raphaël describing the easing:animate: function(new_attrs, ms, easing) {If that argument is not present, I will fallback to the old behavior (strict translation of coordinates). If that argument is present, then I do as I describe above:
}
animate: function(new_attrs, ms, easing) {That almost works.
if (new_attrs.cx || new_attrs.cy) {
var x = new_attrs.cx || this.getCenter().x
,y = new_attrs.cy || this.getCenter().y;
if (easing) {
this.hide_all_frames();
// replace the frames with a circle at the same location
var c = this.paper.circle(this.getCenter().x,
this.getCenter().y,
20);
var self = this;
c.animate({cx: x, cy: y}, ms, easing, function () {
// when the animation of the circle is done, remove
// the circle, move the frames to the end point and show
// the first frame again
c.remove();
self.translate(x, y);
self.show_frame(self.list[0]);
});
}
else {
this.translate(x, y, ms);
}
}
}
The circle appears, but the frames do not disappear. They stick around and keep moving.
After a bit of a search, I track the problem down to the
stop()
method in the Player
class. Specifically, when a player stops (e.g. when it is about to bounce), the raphael object is not being told to stop:Player.prototype.stop = function () {Hunh. That's weird. I wonder why it is disabled....
//TODO -- re-enable
// this.avatar.stop();
this.x = this.avatar.getBBox().x;
this.y = this.avatar.getBBox().y;
};
After re-enabling, I find out why it was disabled—there is no
stop()
method in animate-frames. So I add one:stop: function() {I really need to break down and create a
var frames = this.list;
for (var i=0; i<frames.length; i++) {
for (var j=0; j<frames[i].length; j++) {
frames[i][j].stop()
}
}
Frame
class. I iterate over frames and frame elements far too often.I will leave refactoring for another night. For now, I would be happy just to get things working.
Happily, that was the last change needed:
I could definitely make that animation a little nicer, but, for a proof of concept it will suffice. Tomorrow, I will prettyfy things a bit—both the animation and the code.
Day #241
No comments:
Post a Comment