让位图动起来!

这个主要是把一张绘制有几个图像,并且有连续关系的位图利用BitmapData类的copyPixels实例方法截取位图上面的部分图像,然后利用ENTER_FRAME事件或者Timer事件制作动画!

在这个方法里面有好几个重要参数

copyPixels(sourceBitmapData:BitmapData, sourceRect:Rectangle, destPoint:Point, alphaBitmapData:BitmapData = null, alphaPoint:Point = null, mergeAlpha:Boolean = false)
sourceBitmapData:要制作动画的图片源
sourceRect:这个参数是一个Rectangle,它表示在源位图上开始切割的坐标,宽,高
destPoint:这个表示把切割好的位图作为Bitmap类的源的时候,左上角所在的坐标(我知道这样解析很难明白,但是我想不到其他的解析方式了)

其他参数请看帮助,因为我也没有去具体了解过,也很少用到!

要想你的位图动起来,还需要在制作位图的时候注意每一个图像之间要有一定的间隔,而且最好都在一个固定大小的矩形内。

好了现在把整个类的代码贴出来~!

因为我想用在项目中,所以也写了它的一个父类和一个支持多帧的类

所以工有三个类(DisplaySuper,BmpMovieClip,MultiFrameBmpMovieClip)

DisplaySuper类的代码(很简单):

package kongfu 
 {
     import flash.display.DisplayObject;
     import flash.display.DisplayObjectContainer;
     import flash.display.Sprite;
     /**
      * ...
      * @author kongfuzhou
 
      */
     public class DisplaySuper extends Sprite
     {
         public var parentDpl:DisplayObjectContainer;
         
         public function DisplaySuper(self:DisplaySuper) 
         {
             if (self!=this) 
             {
                 throw new Error("abstract class can't new a instance!");
             }
         }
         /**
          * 设置显示对象的坐标
          * @param    xp
          * @param    yp
          * @param    basePro 居于某个宽高居中显示  {w:500,h:500}
          * @example 
          */
         public function setPosOrCenter(xp:Number=0,yp:Number=0,basePro:Object=null):void 
         {
             if (basePro && basePro.w && basePro.h) 
             {
                 this.x = (basePro.w - this.width) / 2;
                 this.y = (basePro.h - this.height) / 2;
             }else
             {
                 this.x = xp;
                 this.y = yp;
             }
             
         }
         protected function removeMySelf():void 
         {
             if (this.parent) 
             {
                 this.parent.removeChild(this);
             }
         }
         
     }
 
 }
制作动画的主要类BmpMovieClip:
package kongfu
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.utils.Timer;
    
    /**
     * 实现将连续位图转换成动画的类
     * @author kongfuzhou
     */
    public class BmpMovieClip extends DisplaySuper
    {
        /**
         * 各种属性
         *
         * @example var obj:Object = {
         * startXY:{startX:Number,startY:Number},
           sizeDiff: { xDiff:106, yDiff:119 }, xDiff:左右两张图的x坐标间隔,yDiff:上下两张图的y坐标间隔
           sizePos: { w:80, h:60},
           control: { len:12, col:8, row:2 }
           };
        
         */
        private var vars:Object;
        /**
         * 最终显示的位图
         */
        private var bmp_mc:Bitmap;
        /**
         * 源位图数据
         */
        public var bmpdResouce:BitmapData;
        /**
         * 最终位图数据
         */
        private var bmpMcData:BitmapData;
        private var index:int = 0;
        private var startPoint:Point;
        private var rectDataArr:Array;
        private var frameRate:int;
        public var firstIsEnd:Boolean = false;
        private var frameTimer:Timer;
        private var transParent:Boolean = true;
        private var color:uint = 0x00ffffff;
        private var resBmpdObj:Object;
        private var boolObj:Object;
        public var isStop:Boolean = true;
        public var oneTimesFunc:Function;
        
        /**
         *  构造函数
         * 
         * @param    vars 调用动画的各种属性
         * @param    resBmpdObj {bmpdRes:BitmapData,bmpdCs:Class}
         * @param    parentDpl 父层
         * @param    boolObj 该对像的属性是boolean类型的{opentFrameEvent:Boolean=true,useTimer:Boolean=false,autoPlay:Boolean=false}
         * @param    frameRate 使用timer来进行切割位图做动画时的虚拟帧频
         * @param    startPoint  destPoint参数
         * @param    rectDataArr  BitmapData实例的copyPixels函数里面的Rectangle参数的参数(当你想每一个图片的宽、高、切割的X和Y坐标是自己随意定义的时传该参数)
         */
        public function BmpMovieClip(vars:Object, resBmpdObj:Object, parentDpl:DisplayObjectContainer, boolObj:Object = null, frameRate:int = 0, startPoint:Point = null, rectDataArr:Array = null)
        {
            super(this);
            this.boolObj = boolObj;
            this.boolObj == null ? this.boolObj = {opentFrameEvent: true, useTimer: false, autoPlay: true} : "";
            this.boolObj.opentFrameEvent == null ? this.boolObj.opentFrameEvent = true : "";
            this.boolObj.useTimer == null ? this.boolObj.useTimer = false : "";
            this.boolObj.autoPlay == null ? this.boolObj.autoPlay = true : "";
            this.resBmpdObj = resBmpdObj;
            this.frameRate = frameRate;
            this.rectDataArr = rectDataArr;
            this.startPoint = startPoint;
            this.startPoint == null ? this.startPoint = new Point(0, 0) : "";
            this.parentDpl = parentDpl;
            this.vars = vars;
            init();
        }
        
        private function init():void
        {
            if (this.vars.control == null || this.vars.startXY == null || this.vars.sizeDiff == null || this.vars.sizePos == null)
            {
                throw new Error("vars's property must four or more!");
            }
            this.rectDataArr ? this.vars.control.len = this.rectDataArr.length : "";
            
            this.bmp_mc = new Bitmap();
            this.vars.transParent ? this.transParent = this.vars.transParent : "";
            this.vars.color ? this.color = this.vars.color : "";
            this.bmpMcData = new BitmapData(this.vars.sizePos.w, this.vars.sizePos.h, this.transParent, this.color);
            
            if (this.resBmpdObj.bmpdRes)
            {
                this.bmpdResouce = this.resBmpdObj.bmpdRes;
            }
            else if (this.resBmpdObj.bmpdCs)
            {
                this.bmpdResouce = new this.resBmpdObj.bmpdCs();
            }
            if (this.resBmpdObj.bmpdRes == null && this.resBmpdObj.bmpdCs == null)
            {
                throw new Error("resBmpdObj must be not null!");
            }
            if (this.bmpdResouce)
            {
                this.bmp_mc.bitmapData = this.bmpMcData;
                this.addChild(this.bmp_mc);
                this.parentDpl ? this.parentDpl.addChild(this) : "";
                if (this.boolObj.useTimer == true)
                {
                    addTimerEvent();
                }
            }
            if (this.boolObj.autoPlay == true)
            {
                play();
            }
            else
            {
                letItMove();
            }
        
        }
        
        private function addTimerEvent():void
        {
            this.boolObj.opentFrameEvent = false;
            this.frameRate == 0 ? this.frameRate = 30 : "";
            this.frameTimer = new Timer(int(1000 / this.frameRate));
            this.frameTimer.addEventListener(TimerEvent.TIMER, timerHandler);
        }
        
        /**
         * 播放
         */
        public function play():void
        {
            if (this.boolObj.useTimer == true)
            {
                if (this.frameTimer.hasEventListener(TimerEvent.TIMER))
                {
                    this.frameTimer.start();
                }
                else
                {
                    addTimerEvent();
                    this.frameTimer.start();
                }
                
            }
            else if (this.boolObj.opentFrameEvent == true)
            {
                this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            }
        }
        
        /**
         * 停止在第一个画面
         */
        public function stop():void
        {
            this.removeEvent();
            this.index = 0;
            letItMove();
        }
        
        private function timerHandler(e:TimerEvent):void
        {
            letItMove();
        }
        
        private function onEnterFrame(e:Event):void
        {
            letItMove();
        }
        
        /**
         * 截取bitmapdata上面的图像生成动画
         */
        public function letItMove():void
        {
            if (this.index < this.vars.control.len)
            {
                if (this.rectDataArr)
                {
                    var obj:Object = this.rectDataArr[this.index];
                    if (obj==null || obj.xp==null || obj.yp==null || obj.w==null || obj.h==null) 
                    {
                        throw new Error(" bitmapData.copyPixels() args of Rectangle got a unable args!");
                    }
                    this.bmpMcData.copyPixels(this.bmpdResouce, new Rectangle(obj.xp, obj.yp, obj.w, obj.h), new Point((this.width - obj.w) / 2, 0))
                }
                else
                {
                    var xp:Number = this.vars.startXY.startX + (this.index % this.vars.control.col) * this.vars.sizeDiff.xDiff;
                    var yp:Number = this.vars.startXY.startY + int(this.index / this.vars.control.col) * this.vars.sizeDiff.yDiff;
                    this.bmpMcData.copyPixels(this.bmpdResouce, new Rectangle(xp, yp, this.vars.sizePos.w, this.vars.sizePos.h), this.startPoint);
                }
                this.index++;
            }
            else if (this.oneTimesFunc != null)
            {
                this.firstIsEnd = true;
                this.oneTimesFunc();
            }
            else
            {
                this.index = 0;
            }
        }
        
        /**
         * 把自己从显示列表中删除并且删除事件侦听器
         */
        public function remove():void
        {
            this.removeMySelf();
            removeEvent();
        }
        
        /**
         * 删除事件侦听器
         */
        public function removeEvent():void
        {
            if (this.boolObj.opentFrameEvent == true)
            {
                this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            }
            if (this.boolObj.useTimer == true)
            {
                this.frameTimer.removeEventListener(TimerEvent.TIMER, timerHandler);
            }
        }
    
    }

}

制作多帧动画的类MultiFrameBmpMovieClip:
package kongfu
 {
     import flash.display.DisplayObjectContainer;
     import flash.events.Event;
     import flash.utils.Dictionary;
     
     /**
      * 多帧位图mc
      * ...
      * @author kongfuzhou
     
      */
     public class MultiFrameBmpMovieClip extends DisplaySuper
     {
         private var framesObj:Object = new Object();
         private var framesArr:Array;
         public var curFrameBmp_mc:BmpMovieClip;
         public var totalFrames:int;
         public var curFrameLabel:String;
         public var curFrame:int;
         private var framesDict:Dictionary = new Dictionary();
         private var frameLabelsDict:Dictionary = new Dictionary();
         private var curIndex:int = 1;
         
         /**
          * @param    framesObj 每一帧的
          * @param    parentDlp 父层
          */
         public function MultiFrameBmpMovieClip(framesArr:Array, parentDlp:DisplayObjectContainer = null)
         {
             super(this);
             this.parentDpl = parentDlp;
             this.framesArr = framesArr;
             init();
         
         }
         
         private function init():void
         {
             if (this.framesArr)
             {
                 var index:int = 0;
                 for (var i in this.framesArr)
                 {
                     index++;
                     if (i is Number)
                     {
                         var str:String = "frame" + (i + 1);
                         this.framesObj[str] = this.framesArr[i];
                         this.frameLabelsDict[this.framesObj[str]] = str;
                     }
                     else if (i is String)
                     {
                         this.framesObj[i] = this.framesArr[i];
                         this.frameLabelsDict[this.framesObj[i]] = i;
                     }
                     this.framesDict[this.framesArr[i]] = index;
                     if (index == 1)
                     {
                         setCurFrame(this.framesArr[i]);
                     }
                     
                 }
                 setTotalFrame();
                 gotoPlay();
             }
             else
             {
                 this.framesArr = new Array();
             }
             if (this.parentDpl)
             {
                 this.parentDpl.addChild(this);
             }
         
         }
         
         /**
          * 播放某帧
          * @param    frame 帧名字符串,数字也可以直接输入
          */
         public function gotoStop(frame:String):void
         {
             var fm:Number = Number(frame);
             if (isNaN(fm))
             {
                 //不是数字
                 if (this.framesObj[frame])
                 {
                     setShow(this.framesObj[frame]);
                 }
             }
             else
             {
                 //是数字
                 if (this.framesArr[fm - 1])
                 {
                     setShow(this.framesArr[fm - 1]);
                 }
             }
         }
         
         /**
          * 播放所有帧
          */
         public function gotoPlay():void
         {
             //trace("gotoPlay: curIndex = "+this.curIndex+" totalFrames = "+this.totalFrames);
             if (this.curIndex < this.totalFrames)
             {
                 (this.framesArr[this.curIndex - 1] as BmpMovieClip).oneTimesFunc = playAll;
                 (this.framesArr[this.curIndex - 1] as BmpMovieClip).play();
             }
         
         }
         
         /**
          * 控制播放所有帧
          */
         private function playAll():void
         {
             if (this.curIndex > this.totalFrames)
             {
                 for each (var item:BmpMovieClip in this.framesObj)
                 {
                     item.removeEvent();
                 }
                 return;
             }
             if (this.framesArr[this.curIndex - 1])
             {
                 if ((this.framesArr[this.curIndex - 1] as BmpMovieClip).firstIsEnd)
                 {
                     this.curIndex++;
                 }
                 else
                 {
                     if (this.numChildren > 1)
                     {
                         while (this.numChildren > 0)
                         {
                             this.removeChildAt(0);
                         }
                         this.addChild(this.framesArr[this.curIndex - 1]);
                         setCurFrame(this.framesArr[this.curIndex - 1]);
                     }
                     else if (this.numChildren == 1)
                     {
                         var child:BmpMovieClip = (this.getChildAt(0) as BmpMovieClip);
                         if (child != this.framesArr[this.curIndex - 1])
                         {
                             this.removeChildAt(0);
                             this.addChild(this.framesArr[this.curIndex - 1]);
                             setCurFrame(this.framesArr[this.curIndex - 1]);
                         }
                         else
                         {
                             (this.framesArr[this.curIndex - 1] as BmpMovieClip).oneTimesFunc = playAll;
                             (this.framesArr[this.curIndex - 1] as BmpMovieClip).play();
                         }
                     }
                     else
                     {
                         this.addChild(this.framesArr[this.curIndex - 1]);
                         setCurFrame(this.framesArr[this.curIndex - 1]);
                     }
                 }
             }
         }
         
         private function setCurFrame(bmp_mc:BmpMovieClip):void
         {
             if (this.framesDict[bmp_mc])
             {
                 this.curFrame = this.framesDict[bmp_mc];
             }
             if (this.frameLabelsDict[bmp_mc])
             {
                 this.curFrameLabel = this.frameLabelsDict[bmp_mc];
             }
             this.curFrameBmp_mc = bmp_mc;
             this.curFrameBmp_mc.play();
             this.addChild(this.curFrameBmp_mc);
         
         }
         
         /**
          * 增加帧
          * @param    frame 帧标签
          * @param    addBmpMc 该帧的动画
          */
         public function addFrame(frame:String, addBmpMc:BmpMovieClip):void
         {
             var fm:Number = Number(frame);
             if (isNaN(fm))
             {
                 //不是数字
                 if (this.framesObj[frame])
                 {
                     throw new Error("this framlabel is exit!");
                 }
                 else
                 {
                     this.framesObj[frame] = addBmpMc;
                     this.frameLabelsDict[addBmpMc] = frame;
                 }
                 
             }
             else
             {
                 //是数字
                 if (this.framesArr[fm - 1] || (fm - 1) < 0)
                 {
                     throw new Error("this framlabel is not exit!");
                 }
                 else
                 {
                     var str:String = "frame" + (this.framesArr.length + 1);
                     this.framesObj[str] = addBmpMc;
                     this.frameLabelsDict[addBmpMc] = str;
                 }
                 
             }
             this.framesArr.push(addBmpMc);
             this.framesDict[addBmpMc] = this.framesArr.length;
             this.setTotalFrame();
         
         }
         
         /**
          * 删除帧
          * @param    frame
          */
         public function removeFrame(frame:String):void
         {
             var fm:Number = Number(frame);
             if (isNaN(fm))
             {
                 //不是数字                
                 for (var i in this.framesArr)
                 {
                     if (this.framesArr[i] == this.framesObj[frame])
                     {
                         this.framesArr.splice(i, 1);
                         break;
                     }
                 }
                 (this.framesObj[frame] as BmpMovieClip).remove();
                 this.framesObj[frame] = null;
             }
             else
             {
                 //是数字
                 var j:int = int(frame);
                 if (this.framesArr[j - 1])
                 {
                     for (var frameName in this.framesObj)
                     {
                         if (this.framesObj[frameName] == this.framesArr[j - 1])
                         {
                             this.framesObj[frameName] = null;
                             break;
                         }
                     }
                     (this.framesArr[j - 1] as BmpMovieClip).remove();
                     this.framesArr.splice(j - 1, 1);
                     
                 }
                 
             }
             this.setTotalFrame();
             setFrameDict();
         
         }
         
         /**
          * 显示某帧内容
          * @param    showBmp_mc 该帧上的动画
          */
         private function setShow(showBmp_mc:BmpMovieClip):void
         {
             while (this.numChildren > 0)
             {
                 this.removeChildAt(0);
             }
             setCurFrame(showBmp_mc);
         }
         
         /**
          * 设置总帧数
          */
         private function setTotalFrame():void
         {
             this.totalFrames = this.framesArr.length;
         }
         
         /**
          * 设置每个对象对应的帧
          */
         private function setFrameDict():void
         {
             var index:int = 0;
             for (var i in this.framesObj)
             {
                 index++;
                 this.framesDict[this.framesObj[i]] = index;
                 this.frameLabelsDict[this.framesObj[i]] = i;
             }
         
         }
         
         public function remove():void
         {
             this.removeMySelf();
         }
     
     }
 
 }

可以到我的微盘下载完整的测试程序和图片素材!

地址: http://vdisk.weibo.com/s/jH3tR






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值