In a place where your fantasy can roam free, there won't be any boundaries to what your imagination can create.
Misha’s Tech Playground
graphics, fun and code play
I'm crazy - but who cares? My ideas are constantly dwelling and this is the place for them to pour out and form into something good. Only active participation will ultimately make this place come to life.
Animating with Scroll Properties, A view on Performance
Having had some time to polish up the AnimSprite Object of the game engine I had a chance to make a small performance test. I decided to give some insights on ow this style of animation works and to post the code that goes along with it for your personal joy.
The following html is generated by the script for each sprite that is placed on the stage.
Of course there is a stylesheet having defined the sprite class:
-
.CGE_sprite {
-
overflow: hidden;
-
position: absolute;
-
}
Utilizing the ScrollTop and ScrollLeft properties of the sprite box (the surrounding div) I can display 50 animated sprites @ 25fps on a page using Firefox 3 Beta 4 with a processor load of about 98% on my MBP 2.16GHz Core Duo.
Safari on the other hand is quite fast and has only 19% processor load for 50 sprites.

Having 100 sprites lets Firefox peak out at 100.9% load and slows down the animation to about 50% speed.
I'd say this is still not optimum, but it's quite a good start.
Here's my JS code for the sprites.
-
var CGE = {
-
// globals attributes
-
LEFT: 3,
-
TOP: 0,
-
RIGHT: 1,
-
BOTTOM: 2,
-
-
HEIGHT: 1,
-
WIDTH: 0,
-
-
X: 0,
-
Y: 1,
-
Z: 2,
-
-
STYLE_SPRITE: "CGE_sprite",
-
-
// the game instance if needed
-
game: null,
-
};
-
-
CGE.Game = new AJS.Class({
-
animSprites: [],
-
init: function (keys) {
-
for (var i=0; i <50; i++) {
-
this.animSprites[i] = new CGE.MirroredAnimSprite("_img/jumping_shadow.png", [Math.random()*300,Math.random()*250], [32,32], AJS.$("map"), true);
-
};
-
-
this.run(this);
-
},
-
-
run: function (game) {
-
game.hero.move(CGE.moveDir);
-
for(var i = 0; i <game.animSprites.length; ++i) {
-
game.animSprites[i].next();
-
}
-
game.mainLoop = window.setTimeout(function(){game.run(game)}, 40); //25fps
-
}
-
});
-
-
CGE.Sprite = new AJS.Class({
-
box: null, // for tiles this is the tile container, pos is relative to it
-
img: null,
-
spriteH: 0,
-
spriteW: 0,
-
// get x and y directly from object, faster for anim
-
z: 0,
-
-
frames: null,
-
-
init: function(url, pos, size, parent, useBox) {
-
this.img = AJS.IMG({src: url});
-
if(useBox)
-
this.box = AJS.DIV({className: CGE.STYLE_SPRITE}, this.img);
-
-
if(pos)
-
this.setPos(pos);
-
-
if(size)
-
this.setSize(size);
-
-
if(parent)
-
AJS.ACN(parent, this.box);
-
},
-
-
get: function() {
-
return this.img.src;
-
},
-
-
set: function(url, size) {
-
this.img.src = url;
-
},
-
-
getPos: function() {
-
return [this.box.offsetLeft, this.box.offsetTop];
-
},
-
-
setFrame: function(name, n) {
-
this.box.scrollTop = this.frames[name][n][CGE.Y];
-
this.box.scrollLeft = this.frames[name][n][CGE.X];
-
},
-
-
setPos: function(pos) {
-
AJS.setLeft(this.box, pos[CGE.X]);
-
AJS.setTop(this.box, pos[CGE.Y]);
-
},
-
-
setSize: function(size) {
-
this.spriteH = size[CGE.HEIGHT];
-
this.spriteW = size[CGE.WIDTH];
-
AJS.setHeight(this.box, this.spriteH);
-
AJS.setWidth(this.box, this.spriteW);
-
}
-
});
-
-
CGE.AnimSprite = CGE.Sprite.extend({
-
isPlaying: false,
-
isMirrored: true,
-
sign: true, // true=add, false = substract
-
-
frames: null,
-
key: null,
-
-
init: function(url, pos, size, parent, isPlaying) {
-
this.parent(url, pos, size, parent, true);
-
this.key = {name: "base",num: 0}
-
this.isPlaying = (isPlaying);
-
-
this.frames = {base: [[0,0],[32,0],[64,0],[96,0],[128,0],[160,0]]};
-
},
-
-
getFrame: function() {
-
return this.key;
-
},
-
-
setFrame: function(name, n) {
-
if(n>= this.frames[name].length)
-
n = 0;
-
this.parent(name, n)
-
this.key = {name: name, num: n};
-
},
-
-
next: function() {
-
if(this.isPlaying)
-
this.setFrame(this.key.name, ++this.key.num);
-
},
-
-
pause: function() {
-
this.isPlaying = false;
-
},
-
play: function(name) {
-
if(name)
-
this.key.name = name;
-
-
this.isPlaying = true;
-
},
-
stop: function() {
-
this.pause();
-
this.setFrame("base", 0);
-
}
-
});
-
-
CGE.MirroredAnimSprite = CGE.AnimSprite.extend({
-
sign: true, // true=add, false = substract
-
-
setFrame: function(name, n) {
-
switch(n) {
-
case this.frames[name].length-1:
-
this.sign = false;
-
break;
-
case 0:
-
this.sign = true;
-
};
-
(this.sign) ? ++n : --n;
-
-
this.parent(name, n);
-
},
-
-
next: function() {
-
if(this.isPlaying)
-
this.setFrame(this.key.name, this.key.num);
-
},
-
});
-
-
function init() {
-
CGE.game = new CGE.Game();
-
}
-
-
AJS.AEV(window, 'load', init);
As you can see, I make extensive use of AJS. You can get the stock version of it at the official website: AJS JavaScript Library.
The code shown here should be fully functional. I just removed the methods and members which aren't used in this example. And as a little caveat, there is no depth management as of yet.
The image I used in my code is the same as in the Javascript Sprite Animation post.
The classes to use would be:
- CGE.Sprite - which is a single not animated sprite
- CGE.AnimSprite - which is an animated sprite running in a loop
- CGE.MirroredAnimSprite - which is an animated sprite that plays in reverse when it's last/first frame is reached
- CGE.Game - which coordinates the loop in which all animations are run
Have fun ![]()
Tags: code performance, Firefox, Games, JavaScript Library, pbbg, Safari, tile graphics
2 Responses to “Animating with Scroll Properties, A view on Performance”
Leave a Reply
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Performance comparison between HTML, SVG and Canvas...
After posting my code to animate sprites via a containers scroll properties I thought hey, why not just check if there’s anything better. The following article provides a short overview and a sample for each technique. There is a zip file contain...
Scripted Image Mosaics...
Here's another useful tidbit.
I already wrote a lot of posts about Javascript Sprites, how to animate them and how they perform. What I neglected so far is how they actually get on the stage or the page to use the correct term. Another fact is also th...