mirror of
https://github.com/tiennm99/fbird.git
synced 2026-06-17 20:48:05 +00:00
548 lines
14 KiB
JavaScript
Vendored
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);
|
|
}
|
|
};
|