소스 검색

Moved firing complete event to apply. Fixed missing keys on last frame when animation changes.

NathanSweet 12 년 전
부모
커밋
dbd6ae87ad

+ 15 - 16
spine-as3/spine-as3/src/spine/animation/AnimationState.as

@@ -54,26 +54,16 @@ public class AnimationState {
 			var current:TrackEntry = _tracks[i];
 			var current:TrackEntry = _tracks[i];
 			if (!current) continue;
 			if (!current) continue;
 			
 			
-			var trackDelta:Number = delta * current.timeScale;
-			var time:Number = current.time + trackDelta;
-			var endTime:Number = current.endTime;
-			
-			current.time = time;
+			var trackDelta:Number = delta * current.timeScale;		
+			current.time += trackDelta;
 			if (current.previous) {
 			if (current.previous) {
 				current.previous.time += trackDelta;
 				current.previous.time += trackDelta;
 				current.mixTime += trackDelta;
 				current.mixTime += trackDelta;
 			}
 			}
-			
-			// Check if completed the animation or a loop iteration.
-			if (current.loop ? (current.lastTime % endTime > time % endTime) : (current.lastTime < endTime && time >= endTime)) {
-				var count:int = (int)(time / endTime);
-				if (current.onComplete != null) current.onComplete(i, count);
-				if (onComplete != null) onComplete(i, count);
-			}
-			
+
 			var next:TrackEntry = current.next;
 			var next:TrackEntry = current.next;
 			if (next) {
 			if (next) {
-				if (time - trackDelta > next.delay) setCurrent(i, next);
+				if (current.lastTime >= 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);
@@ -89,8 +79,10 @@ public class AnimationState {
 			_events.length = 0;
 			_events.length = 0;
 			
 			
 			var time:Number = current.time;
 			var time:Number = current.time;
+			var lastTime:Number = current.lastTime;
+			var endTime:Number = current.endTime;
 			var loop:Boolean = current.loop;
 			var loop:Boolean = current.loop;
-			if (!loop && time > current.endTime) time = current.endTime;
+			if (!loop && time > endTime) time = endTime;
 			
 			
 			var previous:TrackEntry = current.previous;
 			var previous:TrackEntry = current.previous;
 			if (!previous)
 			if (!previous)
@@ -112,7 +104,14 @@ public class AnimationState {
 				if (current.onEvent != null) current.onEvent(i, event);
 				if (current.onEvent != null) current.onEvent(i, event);
 				if (onEvent != null) onEvent(i, event);
 				if (onEvent != null) onEvent(i, event);
 			}
 			}
-			
+
+			// Check if completed the animation or a loop iteration.
+			if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
+				var count:int = (int)(time / endTime);
+				if (current.onComplete != null) current.onComplete(i, count);
+				if (onComplete != null) onComplete(i, count);
+			}
+
 			current.lastTime = current.time;
 			current.lastTime = current.time;
 		}
 		}
 	}
 	}

+ 21 - 23
spine-c/src/spine/AnimationState.c

@@ -85,33 +85,21 @@ void spAnimationState_dispose (spAnimationState* self) {
 
 
 void spAnimationState_update (spAnimationState* self, float delta) {
 void spAnimationState_update (spAnimationState* self, float delta) {
 	int i;
 	int i;
-	float time, endTime, trackDelta;
+	float trackDelta;
 	delta *= self->timeScale;
 	delta *= self->timeScale;
 	for (i = 0; i < self->trackCount; i++) {
 	for (i = 0; i < self->trackCount; i++) {
 		spTrackEntry* current = self->tracks[i];
 		spTrackEntry* current = self->tracks[i];
 		if (!current) continue;
 		if (!current) continue;
 
 
 		trackDelta = delta * current->timeScale;
 		trackDelta = delta * current->timeScale;
-		time = current->time + trackDelta;
-		endTime = current->endTime;
-
-		current->time = time;
+		current->time += trackDelta;
 		if (current->previous) {
 		if (current->previous) {
 			current->previous->time += trackDelta;
 			current->previous->time += trackDelta;
 			current->mixTime += trackDelta;
 			current->mixTime += trackDelta;
 		}
 		}
 
 
-		/* Check if completed the animation or a loop iteration. */
-		if (current->loop ?
-				(FMOD(current->lastTime, endTime) > FMOD(time, endTime)) : (current->lastTime < endTime && time >= endTime)) {
-			int count = (int)(time / endTime);
-			if (current->listener) current->listener(self, i, ANIMATION_COMPLETE, 0, count);
-			if (self->listener) self->listener(self, i, ANIMATION_COMPLETE, 0, count);
-			if (i >= self->trackCount || self->tracks[i] != current) continue;
-		}
-
 		if (current->next) {
 		if (current->next) {
-			if (time - trackDelta >= current->next->delay) _spAnimationState_setCurrent(self, i, current->next);
+			if (current->lastTime >= current->next->delay) _spAnimationState_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) spAnimationState_clearTrack(self, i);
 			if (!current->loop && current->lastTime >= current->endTime) spAnimationState_clearTrack(self, i);
@@ -137,8 +125,7 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
 
 
 		previous = current->previous;
 		previous = current->previous;
 		if (!previous) {
 		if (!previous) {
-			spAnimation_apply(current->animation, skeleton, current->lastTime, time, current->loop, internal->events,
-					&eventCount);
+			spAnimation_apply(current->animation, skeleton, current->lastTime, time, current->loop, internal->events, &eventCount);
 		} else {
 		} else {
 			float alpha = current->mixTime / current->mixDuration;
 			float alpha = current->mixTime / current->mixDuration;
 
 
@@ -151,8 +138,8 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
 				_spTrackEntry_dispose(current->previous);
 				_spTrackEntry_dispose(current->previous);
 				current->previous = 0;
 				current->previous = 0;
 			}
 			}
-			spAnimation_mix(current->animation, skeleton, current->lastTime, time, current->loop, internal->events,
-					&eventCount, alpha);
+			spAnimation_mix(current->animation, skeleton, current->lastTime, time, current->loop, internal->events, &eventCount,
+					alpha);
 		}
 		}
 
 
 		for (ii = 0; ii < eventCount; ii++) {
 		for (ii = 0; ii < eventCount; ii++) {
@@ -161,6 +148,15 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
 			if (self->listener) self->listener(self, i, ANIMATION_EVENT, event, 0);
 			if (self->listener) self->listener(self, i, ANIMATION_EVENT, event, 0);
 		}
 		}
 
 
+		/* Check if completed the animation or a loop iteration. */
+		if (current->loop ? (FMOD(current->lastTime, current->endTime) > FMOD(time, current->endTime)) //
+				: (current->lastTime < current->endTime && time >= current->endTime)) {
+			int count = (int)(time / current->endTime);
+			if (current->listener) current->listener(self, i, ANIMATION_COMPLETE, 0, count);
+			if (self->listener) self->listener(self, i, ANIMATION_COMPLETE, 0, count);
+			if (i >= self->trackCount || self->tracks[i] != current) continue;
+		}
+
 		if (i >= self->trackCount || self->tracks[i] != current) continue;
 		if (i >= self->trackCount || self->tracks[i] != current) continue;
 		current->lastTime = current->time;
 		current->lastTime = current->time;
 	}
 	}
@@ -222,7 +218,8 @@ void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEnt
 	if (self->listener) self->listener(self, index, ANIMATION_START, 0, 0);
 	if (self->listener) self->listener(self, index, ANIMATION_START, 0, 0);
 }
 }
 
 
-spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName, int/*bool*/loop) {
+spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
+		int/*bool*/loop) {
 	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
 	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
 	return spAnimationState_setAnimation(self, trackIndex, animation, loop);
 	return spAnimationState_setAnimation(self, trackIndex, animation, loop);
 }
 }
@@ -241,13 +238,14 @@ spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIn
 	return entry;
 	return entry;
 }
 }
 
 
-spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName, int/*bool*/loop,
-		float delay) {
+spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
+		int/*bool*/loop, float delay) {
 	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
 	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
 	return spAnimationState_addAnimation(self, trackIndex, animation, loop, delay);
 	return spAnimationState_addAnimation(self, trackIndex, animation, loop, delay);
 }
 }
 
 
-spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop, float delay) {
+spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop,
+		float delay) {
 	spTrackEntry* last;
 	spTrackEntry* last;
 
 
 	spTrackEntry* entry = _spTrackEntry_create();
 	spTrackEntry* entry = _spTrackEntry_create();

+ 32 - 33
spine-js/spine.js

@@ -142,7 +142,7 @@ spine.Slot.prototype = {
 		this.g = data.g;
 		this.g = data.g;
 		this.b = data.b;
 		this.b = data.b;
 		this.a = data.a;
 		this.a = data.a;
-		
+
 		var slotDatas = this.skeleton.data.slots;
 		var slotDatas = this.skeleton.data.slots;
 		for (var i = 0, n = slotDatas.length; i < n; i++) {
 		for (var i = 0, n = slotDatas.length; i < n; i++) {
 			if (slotDatas[i] == data) {
 			if (slotDatas[i] == data) {
@@ -969,27 +969,17 @@ spine.AnimationState.prototype = {
 		for (var i = 0; i < this.tracks.length; i++) {
 		for (var i = 0; i < this.tracks.length; i++) {
 			var current = this.tracks[i];
 			var current = this.tracks[i];
 			if (!current) continue;
 			if (!current) continue;
-			
+
 			var trackDelta = delta * current.timeScale;
 			var trackDelta = delta * current.timeScale;
-			var time = current.time + trackDelta;
-			var endTime = current.endTime;
-			
-			current.time = time;
+			current.time += trackDelta;
 			if (current.previous) {
 			if (current.previous) {
 				current.previous.time += trackDelta;
 				current.previous.time += trackDelta;
 				current.mixTime += trackDelta;
 				current.mixTime += trackDelta;
 			}
 			}
-			
-			// Check if completed the animation or a loop iteration.
-			if (current.loop ? (current.lastTime % endTime > time % endTime) : (current.lastTime < endTime && time >= endTime)) {
-				var count = Math.floor(time / endTime);
-				if (current.onComplete) current.onComplete(i, count);
-				if (this.onComplete) this.onComplete(i, count);
-			}
-			
+
 			var next = current.next;
 			var next = current.next;
 			if (next) {
 			if (next) {
-				if (time - trackDelta > next.delay) this.setCurrent(i, next);
+				if (current.lastTime >= next.delay) this.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) this.clearTrack(i);
 				if (!current.loop && current.lastTime >= current.endTime) this.clearTrack(i);
@@ -1000,13 +990,15 @@ spine.AnimationState.prototype = {
 		for (var i = 0; i < this.tracks.length; i++) {
 		for (var i = 0; i < this.tracks.length; i++) {
 			var current = this.tracks[i];
 			var current = this.tracks[i];
 			if (!current) continue;
 			if (!current) continue;
-			
+
 			this.events.length = 0;
 			this.events.length = 0;
-			
+
 			var time = current.time;
 			var time = current.time;
+			var lastTime = current.lastTime;
+			var endTime = current.endTime;
 			var loop = current.loop;
 			var loop = current.loop;
-			if (!loop && time > current.endTime) time = current.endTime;
-			
+			if (!loop && time > endTime) time = endTime;
+
 			var previous = current.previous;
 			var previous = current.previous;
 			if (!previous)
 			if (!previous)
 				current.animation.apply(skeleton, current.lastTime, time, loop, this.events);
 				current.animation.apply(skeleton, current.lastTime, time, loop, this.events);
@@ -1014,7 +1006,7 @@ spine.AnimationState.prototype = {
 				var previousTime = previous.time;
 				var previousTime = previous.time;
 				if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
 				if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
 				previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
 				previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
-				
+
 				var alpha = current.mixTime / current.mixDuration;
 				var alpha = current.mixTime / current.mixDuration;
 				if (alpha >= 1) {
 				if (alpha >= 1) {
 					alpha = 1;
 					alpha = 1;
@@ -1022,17 +1014,24 @@ spine.AnimationState.prototype = {
 				}
 				}
 				current.animation.mix(skeleton, current.lastTime, time, loop, this.events, alpha);
 				current.animation.mix(skeleton, current.lastTime, time, loop, this.events, alpha);
 			}
 			}
-			
+
 			for (var ii = 0, nn = this.events.length; ii < nn; ii++) {
 			for (var ii = 0, nn = this.events.length; ii < nn; ii++) {
 				var event = this.events[ii];
 				var event = this.events[ii];
 				if (current.onEvent != null) current.onEvent(i, event);
 				if (current.onEvent != null) current.onEvent(i, event);
 				if (this.onEvent != null) this.onEvent(i, event);
 				if (this.onEvent != null) this.onEvent(i, event);
 			}
 			}
-			
+
+			// Check if completed the animation or a loop iteration.
+			if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
+				var count = Math.floor(time / endTime);
+				if (current.onComplete) current.onComplete(i, count);
+				if (this.onComplete) this.onComplete(i, count);
+			}
+
 			current.lastTime = current.time;
 			current.lastTime = current.time;
 		}
 		}
 	},
 	},
-	clearTracks: function () {	
+	clearTracks: function () {
 		for (var i = 0, n = this.tracks.length; i < n; i++)
 		for (var i = 0, n = this.tracks.length; i < n; i++)
 			this.clearTrack(i);
 			this.clearTrack(i);
 		this.tracks.length = 0; 
 		this.tracks.length = 0; 
@@ -1057,19 +1056,19 @@ spine.AnimationState.prototype = {
 		var current = this._expandToIndex(index);
 		var current = this._expandToIndex(index);
 		if (current) {
 		if (current) {
 			current.previous = null;
 			current.previous = null;
-			
+
 			if (current.onEnd != null) current.onEnd(index);
 			if (current.onEnd != null) current.onEnd(index);
 			if (this.onEnd != null) this.onEnd(index);
 			if (this.onEnd != null) this.onEnd(index);
-			
+
 			entry.mixDuration = this.data.getMix(current.animation, entry.animation);
 			entry.mixDuration = this.data.getMix(current.animation, entry.animation);
 			if (entry.mixDuration > 0) {
 			if (entry.mixDuration > 0) {
 				entry.mixTime = 0;
 				entry.mixTime = 0;
 				entry.previous = current;
 				entry.previous = current;
 			}
 			}
 		}
 		}
-		
+
 		this.tracks[index] = entry;
 		this.tracks[index] = entry;
-		
+
 		if (entry.onStart != null) entry.onStart(index);
 		if (entry.onStart != null) entry.onStart(index);
 		if (this.onStart != null) this.onStart(index);
 		if (this.onStart != null) this.onStart(index);
 	},
 	},
@@ -1099,7 +1098,7 @@ spine.AnimationState.prototype = {
 		entry.animation = animation;
 		entry.animation = animation;
 		entry.loop = loop;
 		entry.loop = loop;
 		entry.endTime = animation.duration;
 		entry.endTime = animation.duration;
-		
+
 		var last = this._expandToIndex(trackIndex);
 		var last = this._expandToIndex(trackIndex);
 		if (last) {
 		if (last) {
 			while (last.next)
 			while (last.next)
@@ -1107,7 +1106,7 @@ spine.AnimationState.prototype = {
 			last.next = entry;
 			last.next = entry;
 		} else
 		} else
 			this.tracks[trackIndex] = entry;
 			this.tracks[trackIndex] = entry;
-		
+
 		if (delay <= 0) {
 		if (delay <= 0) {
 			if (last) {
 			if (last) {
 				if (last.time < last.endTime) delay += last.endTime - last.time;
 				if (last.time < last.endTime) delay += last.endTime - last.time;
@@ -1116,9 +1115,9 @@ spine.AnimationState.prototype = {
 				delay = 0;
 				delay = 0;
 		}
 		}
 		entry.delay = delay;
 		entry.delay = delay;
-		
+
 		return entry;
 		return entry;
-	},	
+	},
 	/** May be null. */
 	/** May be null. */
 	getCurrent: function (trackIndex) {
 	getCurrent: function (trackIndex) {
 		if (trackIndex >= this.tracks.length) return null;
 		if (trackIndex >= this.tracks.length) return null;
@@ -1669,7 +1668,7 @@ spine.SkeletonBounds.prototype = {
 		var boundingBoxes = this.boundingBoxes;
 		var boundingBoxes = this.boundingBoxes;
 		var polygonPool = this.polygonPool;
 		var polygonPool = this.polygonPool;
 		var polygons = this.polygons;
 		var polygons = this.polygons;
-		
+
 		boundingBoxes.length = 0;
 		boundingBoxes.length = 0;
 		for (var i = 0, n = polygons.length; i < n; i++)
 		for (var i = 0, n = polygons.length; i < n; i++)
 			polygonPool.push(polygons[i]);
 			polygonPool.push(polygons[i]);
@@ -1756,7 +1755,7 @@ spine.SkeletonBounds.prototype = {
 	},
 	},
 	/** Returns true if the polygon contains the point. */
 	/** Returns true if the polygon contains the point. */
 	polygonContainsPoint: function (polygon, x, y) {
 	polygonContainsPoint: function (polygon, x, y) {
-		var nn = polygon.length;		
+		var nn = polygon.length;
 		var prevIndex = nn - 2;
 		var prevIndex = nn - 2;
 		var inside = false;
 		var inside = false;
 		for (var ii = 0; ii < nn; ii += 2) {
 		for (var ii = 0; ii < nn; ii += 2) {

+ 15 - 16
spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java

@@ -57,26 +57,15 @@ public class AnimationState {
 			if (current == null) continue;
 			if (current == null) continue;
 
 
 			float trackDelta = delta * current.timeScale;
 			float trackDelta = delta * current.timeScale;
-			float time = current.time + trackDelta;
-			float endTime = current.endTime;
-
-			current.time = time;
+			current.time += trackDelta;
 			if (current.previous != null) {
 			if (current.previous != null) {
 				current.previous.time += trackDelta;
 				current.previous.time += trackDelta;
 				current.mixTime += trackDelta;
 				current.mixTime += trackDelta;
 			}
 			}
 
 
-			// Check if completed the animation or a loop iteration.
-			if (current.loop ? (current.lastTime % endTime > time % endTime) : (current.lastTime < endTime && time >= endTime)) {
-				int count = (int)(time / endTime);
-				if (current.listener != null) current.listener.complete(i, count);
-				for (int ii = 0, nn = listeners.size; ii < nn; ii++)
-					listeners.get(ii).complete(i, count);
-			}
-
 			TrackEntry next = current.next;
 			TrackEntry next = current.next;
 			if (next != null) {
 			if (next != null) {
-				if (time - trackDelta > next.delay) setCurrent(i, next);
+				if (current.lastTime >= 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);
@@ -95,12 +84,14 @@ public class AnimationState {
 			events.size = 0;
 			events.size = 0;
 
 
 			float time = current.time;
 			float time = current.time;
+			float lastTime = current.lastTime;
+			float endTime = current.endTime;
 			boolean loop = current.loop;
 			boolean loop = current.loop;
-			if (!loop && time > current.endTime) time = current.endTime;
+			if (!loop && time > endTime) time = endTime;
 
 
 			TrackEntry previous = current.previous;
 			TrackEntry previous = current.previous;
 			if (previous == null)
 			if (previous == null)
-				current.animation.apply(skeleton, current.lastTime, time, loop, events);
+				current.animation.apply(skeleton, lastTime, time, loop, events);
 			else {
 			else {
 				float previousTime = previous.time;
 				float previousTime = previous.time;
 				if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
 				if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
@@ -112,7 +103,7 @@ public class AnimationState {
 					Pools.free(previous);
 					Pools.free(previous);
 					current.previous = null;
 					current.previous = null;
 				}
 				}
-				current.animation.mix(skeleton, current.lastTime, time, loop, events, alpha);
+				current.animation.mix(skeleton, lastTime, time, loop, events, alpha);
 			}
 			}
 
 
 			for (int ii = 0, nn = events.size; ii < nn; ii++) {
 			for (int ii = 0, nn = events.size; ii < nn; ii++) {
@@ -122,6 +113,14 @@ public class AnimationState {
 					listeners.get(iii).event(i, event);
 					listeners.get(iii).event(i, event);
 			}
 			}
 
 
+			// Check if completed the animation or a loop iteration.
+			if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
+				int count = (int)(time / endTime);
+				if (current.listener != null) current.listener.complete(i, count);
+				for (int ii = 0, nn = listeners.size; ii < nn; ii++)
+					listeners.get(ii).complete(i, count);
+			}
+
 			current.lastTime = current.time;
 			current.lastTime = current.time;
 		}
 		}
 	}
 	}

+ 33 - 34
spine-lua/AnimationState.lua

@@ -48,10 +48,10 @@ function AnimationState.new (data)
 		local current = self.tracks[index]
 		local current = self.tracks[index]
 		if current then
 		if current then
 			current.previous = nil
 			current.previous = nil
-			
+
 			if current.onEnd then current.onEnd(index) end
 			if current.onEnd then current.onEnd(index) end
 			if self.onEnd then self.onEnd(index) end
 			if self.onEnd then self.onEnd(index) end
-			
+
 			entry.mixDuration = self.data:getMix(current.animation.name, entry.animation.name)
 			entry.mixDuration = self.data:getMix(current.animation.name, entry.animation.name)
 			if entry.mixDuration > 0 then
 			if entry.mixDuration > 0 then
 				entry.mixTime = 0
 				entry.mixTime = 0
@@ -70,31 +70,15 @@ function AnimationState.new (data)
 		for i,current in pairs(self.tracks) do
 		for i,current in pairs(self.tracks) do
 			if current then
 			if current then
 				local trackDelta = delta * current.timeScale
 				local trackDelta = delta * current.timeScale
-				local time = current.time + trackDelta
-				local endTime = current.endTime
-				
-				current.time = time
+				current.time = current.time + trackDelta
 				if current.previous then
 				if current.previous then
 					current.previous.time = current.previous.time + trackDelta
 					current.previous.time = current.previous.time + trackDelta
 					current.mixTime = current.mixTime + trackDelta
 					current.mixTime = current.mixTime + trackDelta
 				end
 				end
-				
-				-- Check if completed the animation or a loop iteration.
-				local complete
-				if current.loop then
-					complete = current.lastTime % endTime > time % endTime
-				else
-					complete = current.lastTime < endTime and time >= endTime
-				end
-				if complete then 
-					local count = math.floor(time / endTime)
-					if current.onComplete then current.onComplete(i, count) end
-					if self.onComplete then self.onComplete(i, count) end
-				end
-				
+
 				local next = current.next
 				local next = current.next
 				if next then
 				if next then
-					if time - trackDelta > next.delay then setCurrent(i, next) end
+					if current.lastTime >= next.delay then setCurrent(i, next) end
 				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 not current.loop and current.lastTime >= current.endTime then self:clearTrack(i) end
 					if not current.loop and current.lastTime >= current.endTime then self:clearTrack(i) end
@@ -102,14 +86,16 @@ function AnimationState.new (data)
 			end
 			end
 		end
 		end
 	end
 	end
-	
+
 	function self:apply(skeleton)
 	function self:apply(skeleton)
 		for i,current in pairs(self.tracks) do
 		for i,current in pairs(self.tracks) do
-			if current then			
+			if current then
 				local time = current.time
 				local time = current.time
+				local lastTime = current.lastTime
+				local endTime = current.endTime
 				local loop = current.loop
 				local loop = current.loop
-				if not loop and time > current.endTime then time = current.endTime end
-				
+				if not loop and time > endTime then time = endTime end
+
 				local previous = current.previous
 				local previous = current.previous
 				if not previous then
 				if not previous then
 					current.animation:apply(skeleton, current.lastTime, time, loop, self.events)
 					current.animation:apply(skeleton, current.lastTime, time, loop, self.events)
@@ -117,7 +103,7 @@ function AnimationState.new (data)
 					local previousTime = previous.time
 					local previousTime = previous.time
 					if not previous.loop and previousTime > previous.endTime then previousTime = previous.endTime end
 					if not previous.loop and previousTime > previous.endTime then previousTime = previous.endTime end
 					previous.animation:apply(skeleton, previousTime, previousTime, previous.loop, nil)
 					previous.animation:apply(skeleton, previousTime, previousTime, previous.loop, nil)
-					
+
 					local alpha = current.mixTime / current.mixDuration
 					local alpha = current.mixTime / current.mixDuration
 					if alpha >= 1 then
 					if alpha >= 1 then
 						alpha = 1
 						alpha = 1
@@ -125,7 +111,7 @@ function AnimationState.new (data)
 					end
 					end
 					current.animation:mix(skeleton, current.lastTime, time, loop, self.events, alpha)
 					current.animation:mix(skeleton, current.lastTime, time, loop, self.events, alpha)
 				end
 				end
-				
+
 				local eventCount = #self.events
 				local eventCount = #self.events
 				for ii = 1, eventCount, 1 do
 				for ii = 1, eventCount, 1 do
 					local event = self.events[ii]
 					local event = self.events[ii]
@@ -136,18 +122,31 @@ function AnimationState.new (data)
 					table.remove(self.events)
 					table.remove(self.events)
 				end
 				end
 
 
+				-- Check if completed the animation or a loop iteration.
+				local complete
+				if current.loop then
+					complete = lastTime % endTime > time % endTime
+				else
+					complete = lastTime < endTime and time >= endTime
+				end
+				if complete then 
+					local count = math.floor(time / endTime)
+					if current.onComplete then current.onComplete(i, count) end
+					if self.onComplete then self.onComplete(i, count) end
+				end
+
 				current.lastTime = current.time
 				current.lastTime = current.time
 			end
 			end
 		end
 		end
 	end
 	end
-	
+
 	function self:clearTracks ()
 	function self:clearTracks ()
 		for i,current in pairs(self.tracks) do
 		for i,current in pairs(self.tracks) do
 			self.clearTrack(i)
 			self.clearTrack(i)
 		end
 		end
 		self.tracks = {}
 		self.tracks = {}
 	end
 	end
-	
+
 	function self:clearTrack (trackIndex)
 	function self:clearTrack (trackIndex)
 		local current = self.tracks[trackIndex]
 		local current = self.tracks[trackIndex]
 		if not current then return end
 		if not current then return end
@@ -157,7 +156,7 @@ function AnimationState.new (data)
 
 
 		self.tracks[trackIndex] = nil
 		self.tracks[trackIndex] = nil
 	end
 	end
-	
+
 	function self:setAnimationByName (trackIndex, animationName, loop)
 	function self:setAnimationByName (trackIndex, animationName, loop)
 		local animation = self.data.skeletonData:findAnimation(animationName)
 		local animation = self.data.skeletonData:findAnimation(animationName)
 		if not animation then error("Animation not found: " + animationName) end
 		if not animation then error("Animation not found: " + animationName) end
@@ -173,7 +172,7 @@ function AnimationState.new (data)
 		setCurrent(trackIndex, entry)
 		setCurrent(trackIndex, entry)
 		return entry
 		return entry
 	end
 	end
-	
+
 	function self:addAnimationByName (trackIndex, animationName, loop, delay)
 	function self:addAnimationByName (trackIndex, animationName, loop, delay)
 		local animation = self.data.skeletonData:findAnimation(animationName)
 		local animation = self.data.skeletonData:findAnimation(animationName)
 		if not animation then error("Animation not found: " + animationName) end
 		if not animation then error("Animation not found: " + animationName) end
@@ -187,7 +186,7 @@ function AnimationState.new (data)
 		entry.animation = animation
 		entry.animation = animation
 		entry.loop = loop
 		entry.loop = loop
 		entry.endTime = animation.duration
 		entry.endTime = animation.duration
-		
+
 		local last = self.tracks[trackIndex]
 		local last = self.tracks[trackIndex]
 		if last then
 		if last then
 			while (last.next) do
 			while (last.next) do
@@ -197,7 +196,7 @@ function AnimationState.new (data)
 		else
 		else
 			self.tracks[trackIndex] = entry
 			self.tracks[trackIndex] = entry
 		end
 		end
-		
+
 		delay = delay or 0
 		delay = delay or 0
 		if delay <= 0 then
 		if delay <= 0 then
 			if last then
 			if last then
@@ -208,7 +207,7 @@ function AnimationState.new (data)
 			end
 			end
 		end
 		end
 		entry.delay = delay
 		entry.delay = delay
-		
+
 		return entry
 		return entry
 	end
 	end