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;
- }
- }
- }
- }
|