/// <summary> /// Adds a frame with a certain texture and duration. /// </summary> public void AddFrame(int frameId, Texture texture, float duration = -1f) { if (frameId < 0 || frameId > NumFrames) { throw new ArgumentException("Invalid frame id"); } if (duration < 0) { duration = _defaultFrameDuration; } MovieClipFrame frame = new MovieClipFrame(texture, duration); //frame.sound = sound; _frames.Insert(frameId, frame); if (frameId == NumFrames) { float prevStartTime = frameId > 0 ? _frames[frameId - 1].StartTime : 0.0f; float prevDuration = frameId > 0 ? _frames[frameId - 1].Duration : 0.0f; frame.StartTime = prevStartTime + prevDuration; } else { UpdateStartTimes(); } }
// helpers private void UpdateStartTimes() { int numFrames = NumFrames; MovieClipFrame prevFrame = _frames[0]; prevFrame.StartTime = 0; for (int i = 1; i < numFrames; ++i) { _frames[i].StartTime = prevFrame.StartTime + prevFrame.Duration; prevFrame = _frames[i]; } }
// IAnimatable public void AdvanceTime(float passedTime) { if (!_playing) { return; } // The tricky part in this method is that whenever a callback is executed // (a frame action or a 'COMPLETE' event handler), that callback might modify the clip. // Thus, we have to start over with the remaining time whenever that happens. MovieClipFrame frame = _frames[_currentFrameId]; if (_wasStopped) { // if the clip was stopped and started again, // sound and action of this frame need to be repeated. _wasStopped = false; //frame.playSound(_soundTransform); /* * if (frame.action != null) * { * frame.executeAction(this, _currentFrameID); * advanceTime(passedTime); * return; * }*/ } if (_currentTime == TotalTime) { if (Loop) { _currentTime = 0.0f; _currentFrameId = 0; frame = _frames[0]; //frame.playSound(_soundTransform); Texture = frame.Texture; /* * if (frame.action != null) * { * frame.executeAction(this, _currentFrameID); * advanceTime(passedTime); * return; * }*/ } else { return; } } int finalFrameId = _frames.Count - 1; float restTimeInFrame = frame.Duration - _currentTime + frame.StartTime; bool dispatchCompleteEvent = false; //Function frameAction = null; int previousFrameId = _currentFrameId; //bool changedFrame; while (passedTime >= restTimeInFrame) { //changedFrame = false; passedTime -= restTimeInFrame; _currentTime = frame.StartTime + frame.Duration; if (_currentFrameId == finalFrameId) { if (OnComplete != null) { dispatchCompleteEvent = true; } else if (Loop) { _currentTime = 0; _currentFrameId = 0; //changedFrame = true; } else { return; } } else { _currentFrameId += 1; //changedFrame = true; } frame = _frames[_currentFrameId]; //frameAction = frame.action; //if (changedFrame) // frame.playSound(_soundTransform); if (dispatchCompleteEvent) { Texture = frame.Texture; OnComplete(); AdvanceTime(passedTime); return; } /*else if (frameAction != null) * { * texture = frame.texture; * frame.executeAction(this, _currentFrameID); * advanceTime(passedTime); * return; * }*/ restTimeInFrame = frame.Duration; // prevent a mean floating point problem (issue #851) if (passedTime + 0.0001f > restTimeInFrame && passedTime - 0.0001f < restTimeInFrame) { passedTime = restTimeInFrame; } } if (previousFrameId != _currentFrameId) { Texture = _frames[_currentFrameId].Texture; } _currentTime += passedTime; }