Esta noche escribí esta código que permite hacer animaciones utilizando sprite sheets.
Un sprite sheet es una simple tira de imágenes.
/**
* @author Felipe Alfonso.
* www.shin.cl
*/
var game = new Object();
var e = document.getElementById("canv");
var canvas = e.getContext("2d");
var bgColor = "#000000";
var pool = new Array();
var s = new Sprite("data/sprite.png",0,0)
var mouseX = 0;
var mouseY = 0;
//array of animated sprites
var anim = new Array();
window.onload = function()
{
game.Init();
}
document.onmousemove = function(e)
{
mouseX = e.clientX;
mouseY = e.clientY;
}
function print(msg)
{
console.log(msg);
}
game.Init = function()
{
game.gameLoop(60);
game.Background();
game.Create();
};
game.Create = function()
{
game.addChild(s);
for(var i=0;i<100;i++)
{
var spr = new Sprite("data/sprite.png",Math.random()*e.width,Math.random()*e.height,0);
game.addChild(spr);
anim.push(spr);
}
}
game.gameLoop = function(fps)
{
var t = setTimeout("game.gameLoop("+fps+")",fps);
game.Background();
game.Update();
game.Draw();
};
game.Background = function()
{
canvas.fillStyle = bgColor;
canvas.fillRect(0,0,e.width,e.height);
};
game.Draw = function()
{
for(var i=0;i<pool.length;i++)
{
canvas.drawImage(pool[i].image,pool[i].rectX,pool[i].rectY,pool[i].width,pool[i].height,pool[i].x,pool[i].y,pool[i].width,pool[i].height);
}
};
game.Update = function()
{
s.x = mouseX;
s.y = mouseY;
s.Animate(26,30,[0,1,2,1,0,3,4,3],0);
for(var i=0;i<anim.length;i++)
{
anim[i].Animate(26,30,[0,1,2,1,0,3,4,3],0);
}
};
game.addChild = function(spr)
{
pool.push(spr);
return spr
};
function Sprite(path,x,y)
{
this.path = path;
this.x = x;
this.y = y;
this.image = new Image();
this.image.src = path;
this.width = this.image.width;
this.height = this.image.height;
this.rectW = this.width;
this.rectH = this.height;
this.rectX = 0;
this.rectY = 0;
this.delayCount = 0;
this.currentFrame = 0;
this.frameCount = 0;
}
Sprite.prototype.SetRect = function(rwidth,rheight,rx,ry)
{
this.width = rwidth;
this.height = rheight;
this.rectW = rwidth;
this.rectH = rheight;
this.rectX = rx;
this.rectY = ry;
}
Sprite.prototype.Animate = function(width,height,frames,delay)
{
if(this.delayCount<delay)
{
this.delayCount+=1;
this.currentFrame = frames[this.frameCount];
this.SetRect(width,height,this.currentFrame*width,0);
}
else
{
if(this.frameCount<frames.length-1)
{
this.currentFrame = frames[this.frameCount];
this.frameCount+=1;
}
else
{
this.currentFrame = frames[this.frameCount];
this.frameCount = 0;
}
this.SetRect(width,height,this.currentFrame*width,0);
this.delayCount = 0;
}
}
La parte que se encarga de la animación es esta:
Sprite.prototype.Animate = function(width,height,frames,delay)
{
if(this.delayCount<delay)
{
this.delayCount+=1;
this.currentFrame = frames[this.frameCount];
this.SetRect(width,height,this.currentFrame*width,0);
}
else
{
if(this.frameCount<frames.length-1)
{
this.currentFrame = frames[this.frameCount];
this.frameCount+=1;
}
else
{
this.currentFrame = frames[this.frameCount];
this.frameCount = 0;
}
this.SetRect(width,height,this.currentFrame*width,0);
this.delayCount = 0;
}
}
En el fondo esto se puede reducir en una función mas simple como esta:
/**
* @author Felipe Alfonso.
* www.shin.cl
*/
//Get canvas
var e = document.getElementById("canv");
var canvas = e.getContext("2d");
//Variables para la animación
var frameCount = 0;
var currentFrame = 0;
var delayCount = 0;
var delay = 0;
var frames = new Array(0,1,2,1,0,3,4,3);
var img = new Image();
var frameWidth = 26;
var frameHeight = 30;
img.src = "data/sprite.png";
function loop()
{
var t = setTimeout("loop()",17);
canvas.fillStyle="#000000";
canvas.fillRect(0,0,e.width,e.height);
if(delayCount<delay)
{
delayCount+=1;
currentFrame = frames[frameCount];
canvas.drawImage(img,currentFrame*frameWidth,0,frameWidth,frameHeight,100,100,frameWidth,frameHeight);
}
else
{
if(frameCount<frames.length-1)
{
currentFrame = frames[frameCount];
frameCount+=1;
}
else
{
currentFrame = frames[frameCount];
frameCount = 0;
}
canvas.drawImage(img,currentFrame*frameWidth,0,frameWidth,frameHeight,100,100,frameWidth,frameHeight);
delayCount = 0;
}
}
window.onload = loop();
Espero que les sirva.
Acá esta la demo:
http://shin.cl/anim/Saludos!