Changed when events are fired.

Events are now fired from lastTime (exclusive) to time (inclusive). This allows an event at the end of an animation to be fired before the next animation starts. The "complete" callback will happen before the event though, because "complete" happens in update() and events are triggered in apply().

Note events are not fired for the previous animation during mixing (crossfading).
This commit is contained in:
NathanSweet 2013-09-29 23:22:55 +02:00
parent 308e18b376
commit af5aca8b66
6 changed files with 31 additions and 44 deletions

View File

@ -518,29 +518,24 @@ void _EventTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float l
EventTimeline* self = (EventTimeline*)timeline; EventTimeline* self = (EventTimeline*)timeline;
int frameIndex; int frameIndex;
if (lastTime <= self->frames[0] || self->framesLength == 1) if (lastTime > time) {
/* Fire events after last time for looped animations. */
_EventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventCount, alpha);
lastTime = 0;
} else if (lastTime >= self->frames[self->framesLength - 1]) return; /* Last time is after last frame. */
if (lastTime < self->frames[0] || self->framesLength == 1)
frameIndex = 0; frameIndex = 0;
else { else {
float frame; float frame;
if (lastTime >= self->frames[self->framesLength - 1]) return; /* Last time is after last frame. */
if (lastTime > time) {
/* Fire events after last time for looped animations. */
_EventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventCount, alpha);
lastTime = 0;
}
frameIndex = binarySearch(self->frames, self->framesLength, lastTime, 1); frameIndex = binarySearch(self->frames, self->framesLength, lastTime, 1);
frame = self->frames[frameIndex]; frame = self->frames[frameIndex];
while (frameIndex > 0) { while (frameIndex > 0) { /* Fire multiple events with the same frame. */
float lastFrame = self->frames[frameIndex - 1]; if (self->frames[frameIndex - 1] != frame) break;
/* Fire multiple events with the same frame and events that occurred at lastTime. */
if (lastFrame != frame && lastFrame != lastTime) break;
frameIndex--; frameIndex--;
} }
} }
for (; frameIndex < self->framesLength && time > self->frames[frameIndex]; frameIndex++) { for (; frameIndex < self->framesLength && time >= self->frames[frameIndex]; frameIndex++) {
firedEvents[*eventCount] = self->events[frameIndex]; firedEvents[*eventCount] = self->events[frameIndex];
(*eventCount)++; (*eventCount)++;
} }

View File

@ -110,7 +110,7 @@ void AnimationState_update (AnimationState* self, float delta) {
} }
if (current->next) { if (current->next) {
if (time >= current->next->delay) _AnimationState_setCurrent(self, i, current->next); if (time - trackDelta >= current->next->delay) _AnimationState_setCurrent(self, i, current->next);
} else { } else {
/* End non-looping animation when it reaches its end time and there is no next entry. */ /* End non-looping animation when it reaches its end time and there is no next entry. */
if (!current->loop && current->lastTime >= current->endTime) AnimationState_clearTrack(self, i); if (!current->loop && current->lastTime >= current->endTime) AnimationState_clearTrack(self, i);

View File

@ -473,27 +473,23 @@ namespace Spine {
float[] frames = this.frames; float[] frames = this.frames;
int frameCount = frames.Length; int frameCount = frames.Length;
if (lastTime > time) { // Fire events after last time for looped animations.
Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha);
lastTime = 0;
} else if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
int frameIndex; int frameIndex;
if (lastTime <= frames[0] || frameCount == 1) if (lastTime < frames[0] || frameCount == 1)
frameIndex = 0; frameIndex = 0;
else { else {
if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
if (lastTime > time) { // Fire events after last time for looped animations.
Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha);
lastTime = 0;
}
frameIndex = Animation.binarySearch(frames, lastTime, 1); frameIndex = Animation.binarySearch(frames, lastTime, 1);
float frame = frames[frameIndex]; float frame = frames[frameIndex];
while (frameIndex > 0) { while (frameIndex > 0) { // Fire multiple events with the same frame.
float lastFrame = frames[frameIndex - 1]; if (frames[frameIndex - 1] != frame) break;
// Fire multiple events with same frame and events that occurred at lastTime.
if (lastFrame != frame && lastFrame != lastTime) break;
frameIndex--; frameIndex--;
} }
} }
for (; frameIndex < frameCount && time > frames[frameIndex]; frameIndex++) for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++)
firedEvents.Add(events[frameIndex]); firedEvents.Add(events[frameIndex]);
} }
} }

View File

@ -80,7 +80,7 @@ namespace Spine {
TrackEntry next = current.next; TrackEntry next = current.next;
if (next != null) { if (next != null) {
if (time >= next.delay) SetCurrent(i, next); if (time - trackDelta >= next.delay) SetCurrent(i, next);
} else { } else {
// End non-looping animation when it reaches its end time and there is no next entry. // End non-looping animation when it reaches its end time and there is no next entry.
if (!current.loop && current.lastTime >= current.endTime) ClearTrack(i); if (!current.loop && current.lastTime >= current.endTime) ClearTrack(i);

View File

@ -547,27 +547,23 @@ public class Animation {
float[] frames = this.frames; float[] frames = this.frames;
int frameCount = frames.length; int frameCount = frames.length;
if (lastTime > time) { // Fire events after last time for looped animations.
apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha);
lastTime = 0;
} else if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
int frameIndex; int frameIndex;
if (lastTime <= frames[0] || frameCount == 1) if (lastTime < frames[0] || frameCount == 1)
frameIndex = 0; frameIndex = 0;
else { else {
if (lastTime >= frames[frameCount - 1]) return; // Last time is after last frame.
if (lastTime > time) { // Fire events after last time for looped animations.
apply(skeleton, lastTime, Integer.MAX_VALUE, firedEvents, alpha);
lastTime = 0;
}
frameIndex = binarySearch(frames, lastTime, 1); frameIndex = binarySearch(frames, lastTime, 1);
float frame = frames[frameIndex]; float frame = frames[frameIndex];
while (frameIndex > 0) { while (frameIndex > 0) { // Fire multiple events with the same frame.
float lastFrame = frames[frameIndex - 1]; if (frames[frameIndex - 1] != frame) break;
// Fire multiple events with the same frame and events that occurred at lastTime.
if (lastFrame != frame && lastFrame != lastTime) break;
frameIndex--; frameIndex--;
} }
} }
for (; frameIndex < frameCount && time > frames[frameIndex]; frameIndex++) for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++)
firedEvents.add(events[frameIndex]); firedEvents.add(events[frameIndex]);
} }
} }

View File

@ -76,7 +76,7 @@ public class AnimationState {
TrackEntry next = current.next; TrackEntry next = current.next;
if (next != null) { if (next != null) {
if (time >= next.delay) setCurrent(i, next); if (time - trackDelta > next.delay) setCurrent(i, next);
} else { } else {
// End non-looping animation when it reaches its end time and there is no next entry. // End non-looping animation when it reaches its end time and there is no next entry.
if (!current.loop && current.lastTime >= current.endTime) clearTrack(i); if (!current.loop && current.lastTime >= current.endTime) clearTrack(i);