貌似现在学习AS3的人越来越少了,空闲的时候写了一个根据位图或者位图数据,并且切割变成帧动画的类。
写的时候没有考虑位图加载以后的缓存,可以在此基础上缓存位图数据,如果下次再有相同路径的话,可以直接调用位图数据的那个函数,这样效率可以高一点。
写的时候没有考虑位图加载以后的缓存,可以在此基础上缓存位图数据,如果下次再有相同路径的话,可以直接调用位图数据的那个函数,这样效率可以高一点。
这个类基本用到了AS3里面的各种基础知识,包括load加载,消息监听,位图数据的处理,函数的回调,TIME的使用等,欢迎大家吐槽。
/**
* 单张多帧动画
* @author JiExsprite
* @time 2014/8/12
*/
</pre><pre name="code" class="java">package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.TimerEvent;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.utils.Timer;
public class SinFrameAni extends Sprite
{
/**加载器*/
private var m_Loader:Loader;
private var m_nRow:int;
private var m_nCol:int;
/**是否下载完成*/
private var m_bLoadOver:Boolean = false;
/**是否等待播放*/
private var m_bWaitPlayAni:Boolean = false;
/**存放所有动画帧*/
private var m_szFrame:Vector.<Bitmap>;
/**播放控制时间*/
private var m_PlayTime:Timer;
/**每帧间隔*/
private var m_nInterval:int = 100;
/**开始帧*/
private var m_nBeginFrame:int = 0;
/**结束帧*/
private var m_nEndFrame:int = -1;
/**最大帧*/
private var m_nMaxFrame:int = -1;
/**当前帧*/
private var m_nCurFrame:int = 0;
/**当前的动画*/
private var m_CurAni:Bitmap = null;
/**是否播放1次*/
private var m_bPlayOnce:Boolean = false;
/**回调函数*/
private var m_CallBackFun:Function;
/**回调函数参数*/
private var m_CallParams:Array = [];
/**单张多帧动画类*/
public function SinFrameAni()
{
super();
m_Loader = new Loader();
m_szFrame = new Vector.<Bitmap>;
m_PlayTime = new Timer(m_nInterval);
}
/**通过图片路径创建
* filename 图片路径
* row 行
* col 列
* */
public function SetFile(filename:String = "",row:int=0,col:int=0):void
{
if(filename=="")
return;
m_nRow = row;
m_nCol = col;
if(m_nRow==0)
m_nRow = 1;
if(m_nCol==0)
m_nCol = 1;
m_bLoadOver = false;
m_Loader.load(new URLRequest(filename));
m_Loader.contentLoaderInfo.addEventListener(Event.COMPLETE,OnDownImgOk);
m_Loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,OnDownImgErr);
}
/**
* 通过bitmapdata创建
* srcdata 源位图数据
* row 行
* col 列
* */
public function SetBitMapData(srcdata:BitmapData = null,row:int=0,col:int=0):void
{
if(srcdata==null)
return;
m_nRow = row;
m_nCol = col;
if(m_nRow==0)
m_nRow = 1;
if(m_nCol==0)
m_nCol = 1;
m_bLoadOver = false;
inciseBmp(srcdata);
}
/**播放一次动画
* beginIdx 开始帧
* endIdx 结束帧
* intervalTimes 每帧间隔毫秒数
* callback 回调函数
* callParams 回调函数参数
* */
public function PlayAndStop(beginIdx:int = 0,endIdx:int = -1,intervalTimes:int = 100,callback:Function=null,callParams:Array=null):void
{
m_CallBackFun = callback;
m_CallParams = callParams;
m_nInterval = intervalTimes;
m_bPlayOnce = true;
m_nCurFrame = beginIdx;
m_nEndFrame = endIdx;
if(m_szFrame.length==0)
return;
if(!m_bLoadOver)
return;
if(m_nCurFrame<0||m_nCurFrame>m_nMaxFrame - 1)
m_nCurFrame = 0;
if(m_nEndFrame<0||m_nEndFrame>m_nMaxFrame - 1)
m_nEndFrame = m_nMaxFrame - 1;
if(m_CurAni!=null)
m_CurAni.visible = false;
m_PlayTime.stop();
m_PlayTime.removeEventListener(TimerEvent.TIMER,OnTime);
m_CurAni = m_szFrame[m_nCurFrame];
m_CurAni.visible = true;
if(m_nCurFrame==m_nEndFrame)
{
CallBackFun();
return;
}
m_PlayTime.delay = intervalTimes;
m_PlayTime.reset();
m_PlayTime.start();
m_PlayTime.addEventListener(TimerEvent.TIMER,OnTime);
}
/**无限循环播放
* intervalTimes 每帧间隔毫秒数
* */
public function PlayAni(intervalTimes:int = 100):void
{
m_bWaitPlayAni = true;
m_nInterval = intervalTimes;
if(!m_bLoadOver)
return;
if(m_szFrame.length==0)
return;
m_bPlayOnce = false;
m_PlayTime.stop();
m_PlayTime.removeEventListener(TimerEvent.TIMER,OnTime);
m_nCurFrame = 0;
m_nEndFrame = m_nMaxFrame - 1;
if(m_CurAni!=null)
m_CurAni.visible = false;
m_PlayTime.repeatCount = 0;
m_PlayTime.delay = m_nInterval;
m_PlayTime.reset();
m_PlayTime.start();
m_PlayTime.addEventListener(TimerEvent.TIMER,OnTime);
m_CurAni = m_szFrame[m_nCurFrame];
m_CurAni.visible = true;
}
/**停止播放*/
public function StopAni():void
{
m_PlayTime.stop();
m_PlayTime.removeEventListener(TimerEvent.TIMER,OnTime);
m_bWaitPlayAni = false;
m_bPlayOnce = false;
}
/**设置位置*/
public function SetPos(xpos:int,ypos:int):void
{
this.x = xpos;
this.y = ypos;
}
/**帧切换*/
private function OnTime(evt:TimerEvent):void
{
if(m_nBeginFrame==m_nEndFrame&&m_nBeginFrame==0)
return;
//trace("当前帧:"+m_nCurFrame);
m_CurAni.visible = false;
m_nCurFrame++;
if(m_nCurFrame>m_nEndFrame)
{
if(m_bPlayOnce)
{
m_CurAni.visible = true;
CallBackFun();
StopAni();
return;
}
m_nCurFrame = m_nBeginFrame;
}
m_CurAni = m_szFrame[m_nCurFrame];
m_CurAni.visible = true;
}
/**加载完毕*/
private function OnDownImgOk(evt:Event):void
{
inciseBmp(evt.target.content.bitmapData);
}
/**输出加载错误*/
private function OnDownImgErr(evt:Event):void
{
var str:String = "IOERROR : Please check your image path and try again!It is said that this relatively high-end !";
trace(str);
}
/**切割图片*/
private function inciseBmp(srcdata:BitmapData):void
{
m_szFrame.length = 0;
var bigdata:BitmapData = srcdata;
var width:int = srcdata.width;
var height:int = srcdata.height;
var frameW:int = width/m_nCol;
var frameH:int = height/m_nRow;
var tempdata:BitmapData;
var szRect:Vector.<Rectangle> = new Vector.<Rectangle>;
for(var i:int=0;i<m_nRow;i++)
{
for(var j:int=0;j<m_nCol;j++)
{
var rectangle:Rectangle = new Rectangle();
rectangle = new Rectangle();
rectangle.x = j * frameW;
rectangle.y = i * frameH;
rectangle.width = frameW;
rectangle.height = frameH;
//trace("矩形大小:"+rectangle);
szRect.push(rectangle);
}
}
var len:int = szRect.length;
for(i=0;i<len;i++)
{
rectangle = szRect[i];
var newBMP:Bitmap = new Bitmap();
tempdata = drawBmp(bigdata,rectangle.x,rectangle.y,rectangle.width,rectangle.height);
newBMP.bitmapData = tempdata;
newBMP.visible = false;
m_szFrame.push(newBMP);
this.addChild(newBMP);
}
m_nMaxFrame = m_szFrame.length;
m_bLoadOver = true;
if(m_bWaitPlayAni)
PlayAni(m_nInterval);
else
PlayAndStop(m_nCurFrame,m_nEndFrame,m_nInterval,m_CallBackFun,m_CallParams);
}
/**返回一张图片的某个矩形区域BitmapData*/
private function drawBmp(sourceBmp:BitmapData, x:Number, y:Number, w:Number, h:Number):BitmapData
{
var newBmp:BitmapData = new BitmapData(w, h, true, 0xff);
newBmp.draw(sourceBmp, new Matrix(1, 0, 0, 1, -x, -y));
return newBmp;
}
/**得到当前动画的帧总数,使用时需要-1*/
public function get maxframe():int
{
return m_nMaxFrame;
}
/**得到当前帧*/
public function get curframe():int
{
return m_nCurFrame;
}
/**得到当前BitmapData*/
public function get curbmpdata():BitmapData
{
return m_CurAni.bitmapData;
}
/**CallBack函数执行*/
private function CallBackFun():void
{
if(m_CallBackFun!=null)
m_CallBackFun(m_CallParams);
m_CallParams = [];
m_CallBackFun = null;
}
/**清空动画*/
public function Clear():void
{
StopAni();
if(m_CurAni!=null)
{
m_CurAni.bitmapData = null;
m_CurAni = null;
}
m_Loader.close();
m_Loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,OnDownImgOk);
m_Loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,OnDownImgErr);
var bmp:Bitmap;
for each(bmp in m_szFrame)
{
this.removeChild(bmp);
bmp.bitmapData = null;
bmp = null;
}
m_szFrame.length = 0;
}
}
}