当前位置: 首页 > 图文教程 > Flash动画 > ActionScript > Flash AS3教程:Motion类

ActionScript
FLASH 3D相册之利用BitmapData类制作
Flash 脚本游戏开发教程 第一课
Flash 脚本游戏开发教程第二课
Flash 脚本游戏开发教程第三课
Flash 脚本游戏开发教程第四课
Flash 脚本游戏开发教程第五课
Flash 脚本游戏开发教程第六课
Flash 脚本游戏开发教程第七课
Flash 脚本游戏开发教程第八课
Flash AS实现的蝌蚪摆尾动画的教程
从基础开始深入学Flash AS3教程(4)(译文)
从基础开始深入学Flash AS3教程(5)(译文)
从基础开始深入Flash AS3教程(2)(译文)
从基础开始深入学Flash AS3教程(3)(译文)
Flash AS3对单个图片进行角色动作化处理
从基础开始深入Flash AS3教程(1)(译文)
Flash教程:if条件语句的用法
Flash AS教程:_visible属性的详细讲解
Flash AS教程:图片环绕旋转效
Flash教程:trace()的使用

ActionScript 中的 Flash AS3教程:Motion类


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-16   浏览: 74 ::
收藏到网摘: n/a

前面教程学习了Flash AS3教程:Random类,这篇我们一起来学习Motion类的使用方法和实例。
先来一个例子展示:
/upload/tech/20090916/20090916063204_8c6744c9d42ec2cb9e8885b54ff744d0.swf

这个类貌似是多余的,反正就是Tween类,但是解决了动画可能播到一半就停止了等问题,Tween播放到一半就停止了原因是因为类中的侦听EnterFrame事件的时候,使用的是弱引用侦听方式,在播放的途中,被内存自动回收了,因此播放到一半就夭折了,解决办法嘛,除了自己写一个,也可以去包中改一下Tween,把侦听改成强引用就行了
我个人是不太习惯使用Tween的,因此我就写了这个类,自己使用嘛,大家觉得还不错就拿去用吧
缓动的算法还是使用ADOBE自带的那个easing包
这个类属性和方法比较多。。耐心看吧,跟Tween差不了太多的

类讲解:
index.base.animation.Motion类:
代码:public class Motion extends EventDispatcher
提供给程序员使用的动画类

构造函数:
public function Motion(target_:*,_attribute:String,_algorithm:Function,_begin:Number,_end:Number,_duration:uint = 10)
与Tween一模一样,只不过最后少了个属性是是否以时间计算缓动,而该类只有以帧频计算缓动

play方法:
public function play():void
开始播放,并触发播放事件
如果正在播放,调用该方法不会有什么变化,只不过会触发播放事件

back方法:
public function back():void
同于play方法,不同的是该方法是让动画反过来播放

resume方法:
public function resume():void
继续播放,依然会触发播放事件

stop方法:
public function stop():void
停止播放,触发停止事件
如果是播放完毕了,即还会触发播放完毕事件
停止事件永远比播放完毕事件提前调度

reset方法:
public function reset():void
重置动画,还原到刚开始实例化的状态
无论是否正在播放,都会触发停止事件

forward方法:
public function forward():void
快进到最后

rewind方法:
public function rewind():void
倒带到最前

next方法:
public function next():void
向前播放一帧
如果是在播放中使用该方法,效果不是太明显

prev方法:
public function prev():void
向前播放一帧
如果是在播放中使用该方法,效果不是太明显

clear方法:
public function clear():void
清除类中的引用,事件等

isBack属性(只读):
public function get isBack():Boolean
是否在回放状态

target属性(只读):
public function get target():*
获取当前操作的对象

current属性(只读):
public function get current():uint
获取当前播放的位置

playing属性(只读):
public function get playing():Boolean
是否正在播放

attribute属性:
public var attribute:String;
设置操作的对象属性,没必要的情况下最好不要修改

begin属性:
public var begin:Number;
设置操作的对象初始属性,没必要的情况下最好不要修改

end属性:
public var end:Number;
设置操作的对象结束属性,没必要的情况下最好不要修改

duration属性:
public var duration:uint;
设置对象从初始值,经过多少帧,才运动到结束值

algorithm属性:
public var algorithm:Function;
设置对象从初始值到结束值是以什么算法进行运动

受保护的属性:
protected var _current:uint = 0;
protected function updata(isInit:Boolean = false):void
如果继承该类,则可以访问_current属性和updata方法,可以直接修改当前帧和强制更新屏幕

举例:(上面那个展示flash的源代码)
对于各种不同的算法,进行效果展示,小小的偷了一下懒,使用的flash自带组件。。

CODE:
import fl.transitions.easing.*;
import index.base.animation.Motion;
import index.base.events.MotionEvent;

//算法数组
var classAr:Array = [Back,Bounce,Elastic,None,Regular,Strong];

//初始小方块
var mc:MC = new MC;
mc.y = 150;
addChild(mc);

//动画声明
var motion:Motion = new Motion(mc,"x",Back.easeIn,50,350,40);
motion.addEventListener(MotionEvent.MOTION_UPDATA,motionUpdataFun);
motion.addEventListener(MotionEvent.MOTION_STOP,motionStopFun);
motion.addEventListener(MotionEvent.MOTION_PLAY,motionPlayFun);
motion.addEventListener(MotionEvent.MOTION_FINISH,motionFinishFun);
motion.play();

//动画播放完毕
function motionFinishFun(e:MotionEvent){
    traceText.appendText("播放完毕\n");
    motion.isBack ? motion.play() : motion.back();
    traceText.scrollV = traceText.maxScrollV;
}

//屏幕更新
function motionUpdataFun(e:MotionEvent){
    currentText.text = motion.current.toString();
    traceText.appendText("屏幕更新,当前帧 "   motion.current   ",X属性:"   mc.x   "\n");
    traceText.scrollV = traceText.maxScrollV;
}

//动画播放
function motionPlayFun(e:MotionEvent){
    traceText.appendText("开始播放\n");
    traceText.scrollV = traceText.maxScrollV;
}

//动画停止
function motionStopFun(e:MotionEvent){
    traceText.appendText("停止播放\n");
    traceText.scrollV = traceText.maxScrollV;
}

//侦听各个面板的change事件
classList.addEventListener("change",changeFun);
funcList.addEventListener("change",changeFun);
durationBar.addEventListener("change",changeFun);
playButton.addEventListener("click",clickFun);

//当属性面板发生数值改变,即触发
function changeFun(e:Event){
    motion.rewind();
    motion.algorithm = classAr[classList.selectedItem.data][funcList.selectedItem.data];
    motion.duration = durationBar.value;
   
    durationText.text = durationBar.value.toString();
}

//播放按钮
function clickFun(e:Event){
    if(playButton.selected) motion.resume();
    else motion.stop();
}

//4个倒带前进等按钮事件
prevButton.addEventListener(MouseEvent.CLICK,function(){motion.prev()});
nextButton.addEventListener(MouseEvent.CLICK,function(){motion.next()});
forwardButton.addEventListener(MouseEvent.CLICK,function(){motion.forward()});
rewindButton.addEventListener(MouseEvent.CLICK,function(){motion.rewind()});



类源代码:

CODE:
package index.base.animation{
   
    import flash.events.Event;
    import flash.events.EventDispatcher;
   
    import index.base.events.MotionEvent;
   
    public class Motion extends EventDispatcher{
        
        //公共属性
        public var attribute:String;
        public var begin:Number;
        public var end:Number;
        public var duration:uint;
        public var algorithm:Function;
        
        //受保护的属性
        protected var _current:uint = 0;
        
        //私有属性
        private var _target:*;
        private var _playing:Boolean = false;
        private var _append:int = 1;
        
        public function Motion(target_:*,_attribute:String,_algorithm:Function,_begin:Number,_end:Number,_duration:uint = 10){
            _target = target_;
            attribute = _attribute;
            begin = _begin;
            end = _end;
            duration = _duration;
            algorithm = _algorithm;
        }
        
        //开始播放
        public function play():void{
            _append = 1;
            resume();
        }
        
        //回放
        public function back():void{
            _append = -1;
            resume();
        }
        
        //继续播放
        public function resume():void{
            if(_playing) _target.removeEventListener(Event.ENTER_FRAME,enterFrameFun);
            _playing = true;
            _target.addEventListener(Event.ENTER_FRAME,enterFrameFun);
            
            //触发开始播放事件
            dispatchEvent(new MotionEvent(MotionEvent.MOTION_PLAY));
        }
        
        //帧频执行事件
        private function enterFrameFun(e:Event):void{
            if((_append == 1 && _current >= duration) || (_append == -1 && _current <= 0)){
                stop();
            }else{
                _current  = _append;
                updata();
            }
        }
        
        //停止播放
        public function stop():void{
            _playing = false;
            _target.removeEventListener(Event.ENTER_FRAME,enterFrameFun);
            
            //触发停止事件
            dispatchEvent(new MotionEvent(MotionEvent.MOTION_STOP));
            //触发播放完毕事件
            if(_current == duration || _current == 0) dispatchEvent(new MotionEvent(MotionEvent.MOTION_FINISH));
        }
        
        //更新动画
        protected function updata(isInit:Boolean = false):void{
            if(isInit) _current = 0;
            _target[attribute] = algorithm(_current,begin,end - begin,duration);
            
            //触发屏幕更新事件
            dispatchEvent(new MotionEvent(MotionEvent.MOTION_UPDATA));
        }
        
        //重置
        public function reset():void{
            stop();
            updata(true);
            _append = 1;
        }
        
        //前进到最后
        public function forward():void{
            _current = duration;
            updata();
        }
        
        //倒带到最前
        public function rewind():void{
            _current = 0;
            updata();
        }
        
        //快进一帧
        public function next():void{
            if(_current < duration){
                _current  = 1;
                updata();
            }
        }
        
        //后退一帧
        public function prev():void{
            if(_current > 0){
                _current -= 1;
                updata();
            }
        }
        
        //清除
        public function clear():void{
            _target.removeEventListener(Event.ENTER_FRAME,enterFrameFun);
            _target = null;
            algorithm = null;
        }
        
        //获取是否为回放状态
        public function get isBack():Boolean{
            return Boolean(_append - 1);
        }
        
        //获取缓动目标
        public function get target():*{
            return _target;
        }
        
        //获取当前运行帧数
        public function get current():uint{
            return _current;
        }
        
        //获取当前是否在运行
        public function get playing():Boolean{
            return _playing;
        }
        
    }
   
}
事件类源代码:

CODE:
package index.base.events{
   
    import flash.events.Event;
   
    public class MotionEvent extends Event{
        
        public static const MOTION_STOP:String = "motionStop";//播放停止
        public static const MOTION_FINISH:String = "motionFinish";//播放完毕
        public static const MOTION_PLAY:String = "motionPlay";//开始播放
        public static const MOTION_UPDATA:String = "motionUpdata";//画面更新
        
        public function MotionEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false){
            super(type,bubbles,cancelable);
        }
    }
}