--首先请有一定的基础再看这篇文章
另外这篇文章应用了某教程的一个例子,我进行了一下修改和整理
我们想想flash的工作原理吧,flash中最基本的两个东西,一个是帧,一个是精灵(Sprite).下面我们就给我们的动画程序添加这两个概念.
首先是帧,我们通过一个定时器,每隔一段时间就重画一下画布,在这段时间里我们改变画布上的元素的位置,这样就是最基本的帧了.
然后现在问题就是如何控制画布上元素的属性呢?我们把画布上所有要用到的动画元素都抽象出来,每个元素都抽象成一个对象,这个对象拥有位置和大小,速度等信息.然后在每一帧重画画布的时候,我们遍历这些对象,调用它们自己的draw方法,让它们根据自己的属性把自己画到画布上.我们将这些元素统称为Sprite,也就是动画精灵.
现在,我们就可以控制这些动画元素了,因为它们都被抽象成了对象,可以有自己的属性和方法,他们都要实现一个接口.虽然在js中不存在接口的概念,但是我们要自己去衡量在每个扩展的精灵里是否都实现了接口的方法.因为这些方法都是必须的.我们把这个接口定义成如下的样子:
var Sprite = function(){
this.speed = {
x : 1,
y : 1
}
;
}
Sprite.prototype = {
draw :function(){
}
,
move : function(){
this.x += this.speed.x;
this.y += this.speed.y;
if( this.childs != null &&this.childs.length > 0 ){
for( var i = 0; i < this.childs.length; i ++){
this.childs[i].speed = this.speed;
this.childs[i].move();
}
}
}
,
a : function( sprite ){
if( this.childs == null ) this.childs = []
this.childs.push( sprite )
}
,
drawChild : function(){
if( this.childs != null &&this.childs.length > 0 ){
for( var i = 0; i < this.childs.length; i ++){
this.childs[i].draw();
}
}
}
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
var Canvas = function(){
this.begin_interval =null;
this.action_interval =null;
this.timer_interval =null;
//精灵对象数组
this.sprites = [];
this.timer_ = 0;
// 时间间隔 需重写
this.interval_num = 25;
// 动画持续时间 需重写
this.duration = 5;
// context对象 需重写
this.ctx = null;
//重写!
this.x=0;
this.y=0;
this.width=0;
this.height=0;
}
Canvas.prototype = {
begin : function(){
this.timer();
this.begin_interval = setInterval( ( function( param ){
return function(){
param.render();
}
}
)( this ), this.interval_num );
}
,
timer : function(){
this.timer_interval = setInterval( ( function( ts ){
return function(){
if( ( ++ts.timer_ ) >= ts.duration ){
ts.stop();
}
}
}
)( this ), 1000 );
}
,
render : function(){
// M.trace(this.sprites.length )
this.ctx.clearRect( this.x, this.x, this.width,this.height );
for( var i in this.sprites ){
if( typeof( this.sprites[i] ) == "function" ) continue;
this.sprites[i].draw();
}
}
,
action : function(){
this.action_interval = setInterval( ( function( can ){
return function(){
for( var i in can.sprites ){
if( typeof( can.sprites[i] ) == "function" ) continue;
can.sprites[i].move()
}