canvas精灵封装

在做canvas动画时,精灵封装的优劣,直接影响后续的编程体验。

下文的封装要领来自《HTML5 Canvas核心技术 图形、动画与游戏开辟》,完成了精灵与绘制对象的解耦,很好用,日常平凡本身也用这类写法。

一个完全的Sprite包括两部分:

  1. Sprite的基础封装

  2. Sprite Painter完成

拆开Sprite和Painter,完成相识耦,能够随便调解Painter功用。Pinter对象只需要完成: void paint(sprite, context)要领即可。这彷佛也叫战略形式。

Sprite 基础封装:


// name:精灵名字
// painter: 绘制器,需别的封装
// behaviors: 行动,精灵行动
var Sprite = function(name, painter, behaviors){
    this.left = 0,
       this.top = 0,
       this.width = 10,
       this.height = 10,
      this.velocityX = 0,
      this.velocityY = 0,
       this.visible = true,
       this.animating = false,
       this.painter = undefined, // object with paint(sprite, context)
       this.behaviors = [], // objects with execute(sprite, context, time)
       
       if(name){
        this.name = name;
    }
    if(painter){
        this.painter = painter;
    }
}

Sprite.prototype = {
    // painter属性是一个指向Painter对象的援用,运用paint(sprite, context)要领来绘制精灵。
    // behaviors属性指向一个对象数组,数组的每一个对象都以execute(sprite, context, time)要领来对精灵举行操纵
    paint: function(context){
        if(this.painter.paint !== undefined && this.visible){
            this.painter.paint(this, context);
        }
    },
    
    update: function(context, time){
        for(var i = this.behaviors.length; i > 0; --i){
            this.behaviors[i-1].execute(this, context, time);
        }
    }
}

behavior一开始有些难明白。书上的诠释是:精灵的行动。

什么叫行动呢?

个人以为,改变了Sprite基础属性的行动,都叫精灵的行动,改变了top、width、velocityX等balabala的都叫行动。

behavior里面会完成一个excute要领 void excute(sprite, context, time){}。在要领里面会修正各种的值。到Pianter绘制的时刻,会完成修正后的结果。也就完成了精灵的多种行动。

精灵绘制器

即提供给Sprite对象的Painter对象,和Sprite解耦。

现在Painter对象分为三类:

<li>描边及添补绘制器</li>
<li>图象绘制器</li>
<li>精灵图绘制器</li>

描边绘制器能够随便掌握,只需完成了 void paint(sprite, context)就能够了。

1.图象绘制器

var ImagePainter = function(imgUrl){
    this.image = new Image();
    this.image.src = imgUrl;
}

ImagePainter.prototype = {
    paint: function(sprite, context){
        if(this.image.complete){
            context.drawImage(this.image, sprite.left, sprite.top, sprite.width, sprite.height);
        } else{
            this.iamge.onload = function(e){
                context.drawImage(this.image, sprite.left, sprite.top, sprite.width, sprite.height);
            }
        }
    }
}

2.精灵绘制器

var SpriteSheetPainter = function(cells){
    this.cells = cells;
};

SpriteSheetPainter.prototype = {
    cells: [],
    cellIndex: 0,
    
    advance: function(){
        if(this.cellInde === this.cells.length -1 ){
            this.cellIndex = 0;
        } else{
            this.cellIndex++;
        }
    },
    paint: function(sprite, context){
        var cell = this.cells[this.cellIndex];
        context.drawImage(spritesheet, cell.x, cell.y, cell.w, cell.h,
                            sprite.left, sprite.top, cell.w, cell.h);
    }
}

精灵动画制作器

SpriteAnimator包括两个参数,Painter数组和回调函数。


var SpriteAnimator = function(painters, elapsedCallback){
    this.painters = painters;
    if(elapsedCallback){
        this.elapsedCallback = elapsedCallback;
    }
};

SpriteAnimator.prototype = {
    painters: [],
    duration: 1000,
    startTime: 0,
    index: 0,
    elapsedCallback: undefined,
    
    end: function(sprite, originalPainter){
        sprite.animating = false;
        if(this.elapsedCallback){
            this.elapsedCallback(sprite);
        } else{
            sprite.painter = originalPainter;
        }
    },
    
    start: function(sprite, duration){
        var endTime = +new Date() + duration,
            period = duration / (this.painters.length),
              interval = undefined,
              animator = this, // for setInterval() function
              originalPainter = sprite.painter;
              
          this.index = 0;
          sprite.animating = true;
          sprite.painter = this.painter[this.index];
          
          interval = setInterval(){
              if(+new Date() < endTime){
                  sprite.painter = animator.painters[++animator.index];
              } else{
                  animator.end(sprite, originalPainter);
                  clearIntercal(interval);
              }
          }, period);
    }
}
    原文作者:别天
    原文地址: https://segmentfault.com/a/1190000006764998
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞