stage3D 搭建2d图形引擎 (七) 简单纹理动画
在硬件渲染的基础之上实现动画的方案应该很多,但比较普遍也是很基础的一种做法就是纹理动画,即通过每一帧改变纹理坐标来在同一张纹理上实现画面的切换。
如下的一张精灵图序列,如果我们每一帧将纹理坐标(四个点)向前推进一步,那么就可以让人物动起来:
实现这种动画其实并不难,但前提是你已经实现了静态的纹理贴图,在静态纹理贴图的基础之上我们需要做的就是将每一帧的纹理坐标数据计算并存储起来,然后在每一帧的迭代中,根据当前帧的计数,取得相应的纹理坐标即可。
我们通过扩展之前的Image类来实现这种动画:
1 package psw2d.display 2 { 3 import flash.display.Bitmap; 4 import flash.display.BitmapData; 5 import flash.geom.Point; 6 import flash.geom.Rectangle; 7 8 import psw2d.Sparrow; 9 import psw2d.core.Context2D; 10 import psw2d.display.animation.IAnimation; 11 import psw2d.render.RenderMaster; 12 import psw2d.texture.BitmapTexture; 13 import psw2d.texture.Texture; 14 15 public class SimpleImagePlayer extends Image implements IAnimation 16 { 17 private var totalFrames:int; 18 private var _frames:Vector.<Number>; 19 private var _curentFrame:int; 20 private var _frameWidth:Number; 21 private var _frameHeight:Number; 22 23 public function SimpleImagePlayer(texture:Texture,w:Number,h:Number,numFrames:int) 24 { 25 super(texture); 26 width = w; height = h; 27 totalFrames = numFrames; 28 29 setCoords(0,0,0); 30 setCoords(1,width,0); 31 setCoords(2,width,height); 32 setCoords(3,0,height); 33 34 var numX:int = texture.width /w ; 35 var numY:int = texture.height / h ; 36 var unitX:Number = 1/numX; 37 var unitY:Number = 1/numY; 38 var curFrame:int; 39 _frames = new <Number>[]; 40 for(var i:int=0;i<numY;i++) 41 { 42 for(var j:int=0;j<numX;j++) 43 { 44 curFrame = i * numY +j; 45 _frames.push( 46 unitX * j,unitY * i, 47 unitX * (j+1),unitY * i, 48 unitX * (j+1),unitY * (i+1), 49 unitX * j,unitY * (i+1) 50 ); 51 } 52 } 53 gotoFrame(0); 54 } 55 56 public function addvanceTime(time:Number):void 57 { 58 gotoFrame(_curentFrame); 59 60 if(_curentFrame < totalFrames) 61 { 62 _curentFrame++; 63 } 64 else 65 { 66 _curentFrame=0; 67 } 68 69 } 70 71 private function gotoFrame(frameNum:int):void 72 { 73 var offset:int = frameNum * 8; 74 for(var i:int=0;i<4;++i) 75 { 76 _vertexData.setTexCoords(i,_frames[offset+2*i],_frames[offset+2*i+1]); 77 } 78 } 79 80 } 81 }
在这个类中我们需要知道的是总的帧数,帧动画的宽和高,这样我们就可以根据纹理的尺寸计算出每一帧的纹理坐标数据,并将它存放在_frames字段中。在每一帧到来时(即调用advanceTime()时),我们取出当前帧的纹理坐标更新顶点数据,并累加帧数。
下面是我们得到的动画: