Files
2020-08-24 23:16:53 +07:00

548 lines
14 KiB
JavaScript
Vendored

gaf.TimeLine = gaf.Object.extend
({
_className: "GAFTimeLine",
_objects: null,
_container: null,
_animationStartedNextLoopDelegate: null,
_animationFinishedPlayDelegate: null,
_framePlayedDelegate: null,
_sequenceDelegate: null,
_fps: 60,
_frameTime: 1/60,
_currentSequenceStart: gaf.FIRST_FRAME_INDEX,
_currentSequenceEnd: gaf.FIRST_FRAME_INDEX,
_totalFrameCount: 0,
_isRunning: false,
_isLooped: false,
_isReversed: false,
_timeDelta: 0,
_animationsSelectorScheduled: false,
_currentFrame: gaf.FIRST_FRAME_INDEX,
setAnimationStartedNextLoopDelegate: function (delegate)
{
this._animationStartedNextLoopDelegate = delegate;
},
setAnimationFinishedPlayDelegate: function (delegate)
{
this._animationFinishedPlayDelegate = delegate;
},
setLooped: function (looped, recursively)
{
this._isLooped = looped;
if (recursively)
{
this._objects.forEach(function (item)
{
item.setLooped(looped, recursively);
});
}
},
getBoundingBoxForCurrentFrame: function ()
{
var result = null;//cc.rect();
var isFirstObj = true;
this._objects.forEach(function (item) {
if(item.isVisibleInCurrentFrame() && item.isVisible())
{
var bb = item.getBoundingBoxForCurrentFrame();
if(!bb)
{
bb = item.getBoundingBox();
}
if (isFirstObj)
{
isFirstObj = false;
result = bb;
}
else
{
result = cc.rectUnion(result, bb);
}
}
});
return cc._rectApplyAffineTransformIn(result, this._container.getNodeToParentTransform());
},
setFps: function (fps)
{
cc.assert(fps !== 0, 'Error! Fps is set to zero.');
this._fps = fps;
this._frameTime = 1/fps;
},
getObjectByName: function (name)
{
var elements = name.split('.');
var result = null;
var retId = -1;
var timeLine = this;
var BreakException = {};
try
{
elements.forEach(function(element)
{
var parts = timeLine._gafproto.getNamedParts();
if(parts.hasOwnProperty(element))
{
retId = parts[element];
}
else
{
// Sequence is incorrect
BreakException.lastElement = element;
throw BreakException;
}
result = timeLine._objects[retId];
timeLine = result;
});
}
catch (e)
{
if (e!==BreakException)
{
throw e;
}
cc.log("Sequence incorrect: `" + name + "` At: `" + BreakException.lastElement + "`");
return null;
}
return result;
},
clearSequence: function ()
{
this._currentSequenceStart = gaf.FIRST_FRAME_INDEX;
this._currentSequenceEnd = this._gafproto.getTotalFrames();
},
getIsAnimationRunning: function ()
{
return this._isRunning;
},
gotoAndStop: function (value)
{
var frame = 0;
if (typeof value === 'string')
{
frame = this.getStartFrame(value);
}
else
{
frame = value;
}
if (this.setFrame(frame))
{
this.setAnimationRunning(false, false);
return true;
}
return false;
},
gotoAndPlay: function (value)
{
var frame = 0;
if (typeof value === 'string')
{
frame = this.getStartFrame(value);
}
else
{
frame = value;
}
if (this.setFrame(frame))
{
this.setAnimationRunning(true, false);
return true;
}
return false;
},
getStartFrame: function (frameLabel)
{
var seq = this._gafproto.getSequences()[frameLabel];
if (seq)
{
return seq.start;
}
return gaf.IDNONE;
},
getEndFrame: function (frameLabel)
{
var seq = this._gafproto.getSequences()[frameLabel];
if (seq)
{
return seq.end;
}
return gaf.IDNONE;
},
setFramePlayedDelegate: function (delegate)
{
this._framePlayedDelegate = delegate;
},
getCurrentFrameIndex: function ()
{
return this._showingFrame;
},
getTotalFrameCount: function ()
{
return this._gafproto.getTotalFrames();
},
start: function ()
{
this._enableTick(true);
if (!this._isRunning)
{
this._currentFrame = gaf.FIRST_FRAME_INDEX;
this.setAnimationRunning(true, true);
}
},
stop: function ()
{
this._enableTick(false);
if (this._isRunning)
{
this._currentFrame = gaf.FIRST_FRAME_INDEX;
this.setAnimationRunning(false, true);
}
},
isDone: function ()
{
if (this._isLooped)
{
return false;
}
else
{
if (!this._isReversed)
{
return this._currentFrame > this._totalFrameCount;
}
else
{
return this._currentFrame < gaf.FIRST_FRAME_INDEX - 1;
}
}
},
getSequences: function()
{
return this._gafproto.getSequences();
},
playSequence: function (name, looped)
{
var s = this.getStartFrame(name);
var e = this.getEndFrame(name);
if (gaf.IDNONE === s || gaf.IDNONE === e)
{
return false;
}
this._currentSequenceStart = s;
this._currentSequenceEnd = e;
if (this._currentFrame < this._currentSequenceStart || this._currentFrame > this._currentSequenceEnd)
{
this._currentFrame = this._currentSequenceStart;
}
else
{
this._currentFrame = this._currentSequenceStart;
}
this.setLooped(looped, false);
this.resumeAnimation();
return true;
},
isReversed: function ()
{
return this._isReversed;
},
setSequenceDelegate: function (delegate)
{
this._sequenceDelegate = delegate;
},
setFrame: function (index)
{
if (index >= gaf.FIRST_FRAME_INDEX && index < this._totalFrameCount)
{
this._showingFrame = index;
this._currentFrame = index;
this._processAnimation();
return true;
}
return false;
},
pauseAnimation: function ()
{
if (this._isRunning)
{
this.setAnimationRunning(false, false);
}
},
isLooped: function ()
{
return this._isLooped;
},
resumeAnimation: function ()
{
if (!this._isRunning)
{
this.setAnimationRunning(true, false);
}
},
setReversed: function (reversed)
{
this._isReversed = reversed;
},
hasSequences: function ()
{
return this._gafproto.getSequences().length > 0;
},
getFps: function ()
{
return this._fps;
},
// Private
ctor: function(gafTimeLineProto, scale)
{
this._super(scale);
this._objects = [];
cc.assert(gafTimeLineProto, "Error! Missing mandatory parameter.");
this._gafproto = gafTimeLineProto;
},
setExternalTransform: function(affineTransform)
{
if(!cc.affineTransformEqualToTransform(this._container._additionalTransform, affineTransform))
{
this._container.setAdditionalTransform(affineTransform);
}
},
_init: function()
{
this.setContentSize(this._gafproto.getBoundingBox());
this._currentSequenceEnd = this._gafproto.getTotalFrames();
this._totalFrameCount = this._currentSequenceEnd;
this.setFps(this._gafproto.getFps());
this._container = new cc.Node();
this.addChild(this._container);
var self = this;
var asset = this._gafproto.getAsset();
// Construct objects for current time line
this._gafproto.getObjects().forEach(function(object)
{
var objectProto = asset._getProtos()[object];
cc.assert(objectProto, "Error. GAF proto for type: " + object.type + " and reference id: " + object + " not found.");
self._objects[object] = objectProto._gafConstruct();
});
},
_enableTick: function(val)
{
if (!this._animationsSelectorScheduled && val)
{
this.schedule(this._processAnimations);
this._animationsSelectorScheduled = true;
}
else if (this._animationsSelectorScheduled && !val)
{
this.unschedule(this._processAnimations);
this._animationsSelectorScheduled = false;
}
},
_processAnimations: function (dt)
{
this._timeDelta += dt;
while (this._timeDelta >= this._frameTime)
{
this._timeDelta -= this._frameTime;
this._step();
}
},
_step: function ()
{
this._showingFrame = this._currentFrame;
if(!this.getIsAnimationRunning())
{
this._processAnimation();
return;
}
if(this._sequenceDelegate)
{
var seq;
if(!this._isReversed)
{
seq = this._getSequenceByLastFrame(this._currentFrame);
}
else
{
seq = this._getSequenceByFirstFrame(this._currentFrame + 1);
}
if (seq)
{
this._sequenceDelegate(this, seq);
}
}
if (this._isCurrentFrameLastInSequence())
{
if(this._isLooped)
{
if(this._animationStartedNextLoopDelegate)
this._animationStartedNextLoopDelegate(this);
}
else
{
this.setAnimationRunning(false, false);
if(this._animationFinishedPlayDelegate)
this._animationFinishedPlayDelegate(this);
}
}
this._processAnimation();
this._currentFrame = this._nextFrame();
},
_isCurrentFrameLastInSequence: function()
{
if (this._isReversed)
return this._currentFrame == this._currentSequenceStart;
return this._currentFrame == this._currentSequenceEnd - 1;
},
_nextFrame: function()
{
if (this._isCurrentFrameLastInSequence())
{
if (!this._isLooped)
return this._currentFrame;
if (this._isReversed)
return this._currentSequenceEnd - 1;
else
return this._currentSequenceStart;
}
return this._currentFrame + (this._isReversed ? -1 : 1);
},
_processAnimation: function ()
{
//var id = this._gafproto.getId();
this._realizeFrame(this._container, this._currentFrame);
if (this._framePlayedDelegate)
{
this._framePlayedDelegate(this, this._currentFrame);
}
},
_realizeFrame: function(out, frameIndex)
{
var self = this;
var objects = self._objects;
var frames = self._gafproto.getFrames();
if(frameIndex > frames.length)
{
return;
}
var currentFrame = frames[frameIndex];
if(!currentFrame)
{
return;
}
var states = currentFrame.states;
for(var stateIdx = 0, total = states.length; stateIdx < total; ++stateIdx)
{
var state = states[stateIdx];
var object = objects[state.objectIdRef];
if(!object)
{
return;
}
if(state.alpha < 0)
{
object._resetState();
}
object._updateVisibility(state, self);
if(!object.isVisible())
{
continue;
}
object._applyState(state, self);
var parent = out;
if(state.hasMask)
{
parent = objects[state.maskObjectIdRef]._getNode();
cc.assert(parent, "Error! Mask not found.");
}
object._lastVisibleInFrame = 1 + frameIndex;
gaf.TimeLine.rearrangeSubobject(parent, object, state.depth);
if(object._step)
{
object._step();
}
}
},
setAnimationRunning: function (value, recursively)
{
this._isRunning = value;
if(recursively)
{
this._objects.forEach(function (obj)
{
if (obj && obj.setAnimationRunning)
{
obj.setAnimationRunning(value, recursively);
}
});
}
},
_getSequenceByLastFrame: function(){
var sequences = this._gafproto.getSequences();
for(var item in sequences){
if(sequences.hasOwnProperty(item)){
if(sequences[item].end === frame + 1)
{
return item;
}
}
}
return "";
},
_resetState : function()
{
this._super();
this._currentFrame = this._currentSequenceStart;
},
_getSequenceByFirstFrame: function(){
var sequences = this._gafproto.getSequences();
for(var item in sequences){
if(sequences.hasOwnProperty(item)){
if(sequences[item].start === frame)
{
return item;
}
}
}
return "";
}
});
gaf.TimeLine.rearrangeSubobject = function(out, object, depth)
{
var parent = object.getParent();
if (parent !== out)
{
object.removeFromParent(false);
out.addChild(object, depth);
}
else
{
object.setLocalZOrder(depth);
}
};