| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 | using UnityEngine;namespace FairyGUI{    /// <summary>    ///     /// </summary>    public class MovieClip : Image    {        /// <summary>        ///         /// </summary>        public class Frame        {            public NTexture texture;            public float addDelay;        }        /// <summary>        ///         /// </summary>        public float interval;        /// <summary>        ///         /// </summary>        public bool swing;        /// <summary>        ///         /// </summary>        public float repeatDelay;        /// <summary>        ///         /// </summary>        public float timeScale;        /// <summary>        /// Whether to ignore Unity time scale.        /// </summary>        public bool ignoreEngineTimeScale;        Frame[] _frames;        int _frameCount;        int _frame;        bool _playing;        int _start;        int _end;        int _times;        int _endAt;        int _status; //0-none, 1-next loop, 2-ending, 3-ended        float _frameElapsed; //当前帧延迟        bool _reversed;        int _repeatedCount;        TimerCallback _timerDelegate;        EventListener _onPlayEnd;        /// <summary>        ///         /// </summary>        public MovieClip()        {            interval = 0.1f;            _playing = true;            _timerDelegate = OnTimer;            timeScale = 1;            ignoreEngineTimeScale = false;            if (Application.isPlaying)            {                onAddedToStage.Add(OnAddedToStage);                onRemovedFromStage.Add(OnRemoveFromStage);            }            SetPlaySettings();        }        /// <summary>        ///         /// </summary>        public EventListener onPlayEnd        {            get { return _onPlayEnd ?? (_onPlayEnd = new EventListener(this, "onPlayEnd")); }        }        /// <summary>        ///         /// </summary>        public Frame[] frames        {            get            {                return _frames;            }            set            {                _frames = value;                _scale9Grid = null;                _scaleByTile = false;                                if (_frames == null)                {                    _frameCount = 0;                    graphics.texture = null;                    CheckTimer();                    return;                }                _frameCount = frames.Length;                if (_end == -1 || _end > _frameCount - 1)                    _end = _frameCount - 1;                if (_endAt == -1 || _endAt > _frameCount - 1)                    _endAt = _frameCount - 1;                if (_frame < 0 || _frame > _frameCount - 1)                    _frame = _frameCount - 1;                InvalidateBatchingState();                _frameElapsed = 0;                _repeatedCount = 0;                _reversed = false;                DrawFrame();                CheckTimer();            }        }        /// <summary>        ///         /// </summary>        public bool playing        {            get { return _playing; }            set            {                if (_playing != value)                {                    _playing = value;                    CheckTimer();                }            }        }        /// <summary>        ///         /// </summary>        public int frame        {            get { return _frame; }            set            {                if (_frame != value)                {                    if (_frames != null && value >= _frameCount)                        value = _frameCount - 1;                    _frame = value;                    _frameElapsed = 0;                    DrawFrame();                }            }        }        /// <summary>        ///         /// </summary>        public void Rewind()        {            _frame = 0;            _frameElapsed = 0;            _reversed = false;            _repeatedCount = 0;            DrawFrame();        }        /// <summary>        ///         /// </summary>        /// <param name="anotherMc"></param>        public void SyncStatus(MovieClip anotherMc)        {            _frame = anotherMc._frame;            _frameElapsed = anotherMc._frameElapsed;            _reversed = anotherMc._reversed;            _repeatedCount = anotherMc._repeatedCount;            DrawFrame();        }        /// <summary>        ///         /// </summary>        /// <param name="time"></param>        public void Advance(float time)        {            int beginFrame = _frame;            bool beginReversed = _reversed;            float backupTime = time;            while (true)            {                float tt = interval + _frames[_frame].addDelay;                if (_frame == 0 && _repeatedCount > 0)                    tt += repeatDelay;                if (time < tt)                {                    _frameElapsed = 0;                    break;                }                time -= tt;                if (swing)                {                    if (_reversed)                    {                        _frame--;                        if (_frame <= 0)                        {                            _frame = 0;                            _repeatedCount++;                            _reversed = !_reversed;                        }                    }                    else                    {                        _frame++;                        if (_frame > _frameCount - 1)                        {                            _frame = Mathf.Max(0, _frameCount - 2);                            _repeatedCount++;                            _reversed = !_reversed;                        }                    }                }                else                {                    _frame++;                    if (_frame > _frameCount - 1)                    {                        _frame = 0;                        _repeatedCount++;                    }                }                if (_frame == beginFrame && _reversed == beginReversed) //走了一轮了                {                    float roundTime = backupTime - time; //这就是一轮需要的时间                    time -= Mathf.FloorToInt(time / roundTime) * roundTime; //跳过                }            }            DrawFrame();        }        /// <summary>        ///         /// </summary>        public void SetPlaySettings()        {            SetPlaySettings(0, -1, 0, -1);        }        /// <summary>        /// 从start帧开始,播放到end帧(-1表示结尾),重复times次(0表示无限循环),循环结束后,停止在endAt帧(-1表示参数end)        /// </summary>        /// <param name="start"></param>        /// <param name="end"></param>        /// <param name="times"></param>        /// <param name="endAt"></param>        public void SetPlaySettings(int start, int end, int times, int endAt)        {            _start = start;            _end = end;            if (_end == -1 || _end > _frameCount - 1)                _end = _frameCount - 1;            _times = times;            _endAt = endAt;            if (_endAt == -1)                _endAt = _end;            _status = 0;            this.frame = start;        }        void OnAddedToStage()        {            if (_playing && _frameCount > 0)                Timers.inst.AddUpdate(_timerDelegate);        }        void OnRemoveFromStage()        {            Timers.inst.Remove(_timerDelegate);        }        void CheckTimer()        {            if (!Application.isPlaying)                return;            if (_playing && _frameCount > 0 && this.stage != null)                Timers.inst.AddUpdate(_timerDelegate);            else                Timers.inst.Remove(_timerDelegate);        }        void OnTimer(object param)        {            if (!_playing || _frameCount == 0 || _status == 3)                return;            float dt;            if (ignoreEngineTimeScale)            {                dt = Time.unscaledDeltaTime;                if (dt > 0.1f)                    dt = 0.1f;            }            else                dt = Time.deltaTime;            if (timeScale != 1)                dt *= timeScale;            _frameElapsed += dt;            float tt = interval + _frames[_frame].addDelay;            if (_frame == 0 && _repeatedCount > 0)                tt += repeatDelay;            if (_frameElapsed < tt)                return;            _frameElapsed -= tt;            if (_frameElapsed > interval)                _frameElapsed = interval;            if (swing)            {                if (_reversed)                {                    _frame--;                    if (_frame <= 0)                    {                        _frame = 0;                        _repeatedCount++;                        _reversed = !_reversed;                    }                }                else                {                    _frame++;                    if (_frame > _frameCount - 1)                    {                        _frame = Mathf.Max(0, _frameCount - 2);                        _repeatedCount++;                        _reversed = !_reversed;                    }                }            }            else            {                _frame++;                if (_frame > _frameCount - 1)                {                    _frame = 0;                    _repeatedCount++;                }            }            if (_status == 1) //new loop            {                _frame = _start;                _frameElapsed = 0;                _status = 0;                DrawFrame();            }            else if (_status == 2) //ending            {                _frame = _endAt;                _frameElapsed = 0;                _status = 3; //ended                DrawFrame();                DispatchEvent("onPlayEnd", null);            }            else            {                DrawFrame();                if (_frame == _end)                {                    if (_times > 0)                    {                        _times--;                        if (_times == 0)                            _status = 2;  //ending                        else                            _status = 1; //new loop                    }                    else if (_start != 0)                        _status = 1; //new loop                }            }        }        void DrawFrame()        {            if (_frameCount > 0)            {                Frame frame = _frames[_frame];                graphics.texture = frame.texture;            }        }    }}
 |