public void Update (Skeleton skeleton, bool updateAabb) {
			List<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
			List<Polygon> polygons = Polygons;
			List<Slot> slots = skeleton.slots;
			int slotCount = slots.Count;
			float x = skeleton.x, y = skeleton.y;

			boundingBoxes.Clear();
			foreach (Polygon polygon in polygons)
				polygonPool.Add(polygon);
			polygons.Clear();

			for (int i = 0; i < slotCount; i++) {
				Slot slot = slots[i];
				BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment;
				if (boundingBox == null) continue;
				boundingBoxes.Add(boundingBox);

				Polygon polygon = null;
				int poolCount = polygonPool.Count;
				if (poolCount > 0) {
					polygon = polygonPool[poolCount - 1];
					polygonPool.RemoveAt(poolCount - 1);
				} else
					polygon = new Polygon();
				polygons.Add(polygon);

				int count = boundingBox.Vertices.Length;
				polygon.Count = count;
				if (polygon.Vertices.Length < count) polygon.Vertices = new float[count];
				boundingBox.ComputeWorldVertices(x, y, slot.bone, polygon.Vertices);
			}

			if (updateAabb) aabbCompute();
		}
		public Slot (SlotData data, Skeleton skeleton, Bone bone) {
			if (data == null) throw new ArgumentNullException("data cannot be null.");
			if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
			if (bone == null) throw new ArgumentNullException("bone cannot be null.");
			this.data = data;
			this.skeleton = skeleton;
			this.bone = bone;
			SetToSetupPose();
		}
		public void Draw (Skeleton skeleton) {
			List<Slot> drawOrder = skeleton.DrawOrder;
			float x = skeleton.X, y = skeleton.Y;
			float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A;
			for (int i = 0, n = drawOrder.Count; i < n; i++) {
				Slot slot = drawOrder[i];
				RegionAttachment regionAttachment = slot.Attachment as RegionAttachment;
				if (regionAttachment != null) {
					BlendState blend = slot.Data.AdditiveBlending ? BlendState.Additive : defaultBlendState;
					if (device.BlendState != blend) {
						End();
						device.BlendState = blend;
					}

					SpriteBatchItem item = batcher.CreateBatchItem();
					AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
					item.Texture = (Texture2D)region.page.rendererObject;

					Color color;
					float a = skeletonA * slot.A;
					if (premultipliedAlpha)
						color = new Color(skeletonR * slot.R * a, skeletonG * slot.G * a, skeletonB * slot.B * a, a);
					else
						color = new Color(skeletonR * slot.R, skeletonG * slot.G, skeletonB * slot.B, a);
					item.vertexTL.Color = color;
					item.vertexBL.Color = color;
					item.vertexBR.Color = color;
					item.vertexTR.Color = color;

					float[] vertices = this.vertices;
					regionAttachment.ComputeWorldVertices(x, y, slot.Bone, vertices);
					item.vertexTL.Position.X = vertices[RegionAttachment.X1];
					item.vertexTL.Position.Y = vertices[RegionAttachment.Y1];
					item.vertexTL.Position.Z = 0;
					item.vertexBL.Position.X = vertices[RegionAttachment.X2];
					item.vertexBL.Position.Y = vertices[RegionAttachment.Y2];
					item.vertexBL.Position.Z = 0;
					item.vertexBR.Position.X = vertices[RegionAttachment.X3];
					item.vertexBR.Position.Y = vertices[RegionAttachment.Y3];
					item.vertexBR.Position.Z = 0;
					item.vertexTR.Position.X = vertices[RegionAttachment.X4];
					item.vertexTR.Position.Y = vertices[RegionAttachment.Y4];
					item.vertexTR.Position.Z = 0;

					float[] uvs = regionAttachment.UVs;
					item.vertexTL.TextureCoordinate.X = uvs[RegionAttachment.X1];
					item.vertexTL.TextureCoordinate.Y = uvs[RegionAttachment.Y1];
					item.vertexBL.TextureCoordinate.X = uvs[RegionAttachment.X2];
					item.vertexBL.TextureCoordinate.Y = uvs[RegionAttachment.Y2];
					item.vertexBR.TextureCoordinate.X = uvs[RegionAttachment.X3];
					item.vertexBR.TextureCoordinate.Y = uvs[RegionAttachment.Y3];
					item.vertexTR.TextureCoordinate.X = uvs[RegionAttachment.X4];
					item.vertexTR.TextureCoordinate.Y = uvs[RegionAttachment.Y4];
				}
			}
		}
		/// <summary>Poses the skeleton at the specified time for this animation mixed with the current pose.</summary>
		/// <param name="lastTime">The last time the animation was applied.</param>
		/// <param name="events">Any triggered events are added.</param>
		/// <param name="alpha">The amount of this animation that affects the current pose.</param>
		public void Mix (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events, float alpha) {
			if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");

			if (loop && duration != 0) {
				time %= duration;
				lastTime %= duration;
			}

			List<Timeline> timelines = this.timelines;
			for (int i = 0, n = timelines.Count; i < n; i++)
				timelines[i].Apply(skeleton, lastTime, time, events, alpha);
		}
		public void Apply (Skeleton skeleton) {
			List<Event> events = this.events;

			for (int i = 0; i < tracks.Count; i++) {
				TrackEntry current = tracks[i];
				if (current == null) continue;

				events.Clear();

				float time = current.time;
				bool loop = current.loop;
				if (!loop && time > current.endTime) time = current.endTime;

				TrackEntry previous = current.previous;
				if (previous == null)
					current.animation.Apply(skeleton, current.lastTime, time, loop, events);
				else {
					float previousTime = previous.time;
					if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
					previous.animation.Apply(skeleton, previousTime, previousTime, previous.loop, null);

					float alpha = current.mixTime / current.mixDuration;
					if (alpha >= 1) {
						alpha = 1;
						current.previous = null;
					}
					current.animation.Mix(skeleton, current.lastTime, time, loop, events, alpha);
				}

				for (int ii = 0, nn = events.Count; ii < nn; ii++) {
					Event e = events[ii];
					current.OnEvent(this, i, e);
					if (Event != null) Event(this, new EventTriggeredArgs(i, e));
				}

				current.lastTime = current.time;
			}
		}
		public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
			float[] frames = this.frames;
			if (time < frames[0]) return; // Time is before first frame.

			int frameIndex;
			if (time >= frames[frames.Length - 1]) // Time is after last frame.
				frameIndex = frames.Length - 1;
			else
				frameIndex = Animation.binarySearch(frames, time, 1) - 1;

			List<Slot> drawOrder = skeleton.drawOrder;
			List<Slot> slots = skeleton.slots;
			int[] drawOrderToSetupIndex = drawOrders[frameIndex];
			if (drawOrderToSetupIndex == null) {
				drawOrder.Clear();
				drawOrder.AddRange(slots);
			} else {
				for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++)
					drawOrder[i] = slots[drawOrderToSetupIndex[i]];
			}
		}
		/// <summary>Fires events for frames > lastTime and <= time.</summary>
		public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
			if (firedEvents == null) return;
			float[] frames = this.frames;
			int frameCount = frames.Length;

			if (lastTime > time) { // Fire events after last time for looped animations.
				Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha);
				lastTime = -1f;
			} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
				return;
			if (time < frames[0]) return; // Time is before first frame.

			int frameIndex;
			if (lastTime < frames[0])
				frameIndex = 0;
			else {
				frameIndex = Animation.binarySearch(frames, lastTime, 1);
				float frame = frames[frameIndex];
				while (frameIndex > 0) { // Fire multiple events with the same frame.
					if (frames[frameIndex - 1] != frame) break;
					frameIndex--;
				}
			}
			for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++)
				firedEvents.Add(events[frameIndex]);
		}
		public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
			float[] frames = this.frames;
			if (time < frames[0]) return; // Time is before first frame.

			int frameIndex;
			if (time >= frames[frames.Length - 1]) // Time is after last frame.
				frameIndex = frames.Length - 1;
			else
				frameIndex = Animation.binarySearch(frames, time, 1) - 1;

			String attachmentName = attachmentNames[frameIndex];
			skeleton.slots[slotIndex].Attachment =
				 attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName);
		}
		override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
			float[] frames = this.frames;
			if (time < frames[0]) return; // Time is before first frame.

			Slot slot = skeleton.slots[slotIndex];

			if (time >= frames[frames.Length - 5]) { // Time is after last frame.
				int i = frames.Length - 1;
				slot.r = frames[i - 3];
				slot.g = frames[i - 2];
				slot.b = frames[i - 1];
				slot.a = frames[i];
				return;
			}

			// Interpolate between the last frame and the current frame.
			int frameIndex = Animation.binarySearch(frames, time, 5);
			float lastFrameR = frames[frameIndex - 4];
			float lastFrameG = frames[frameIndex - 3];
			float lastFrameB = frames[frameIndex - 2];
			float lastFrameA = frames[frameIndex - 1];
			float frameTime = frames[frameIndex];
			float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime);
			percent = GetCurvePercent(frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));

			float r = lastFrameR + (frames[frameIndex + FRAME_R] - lastFrameR) * percent;
			float g = lastFrameG + (frames[frameIndex + FRAME_G] - lastFrameG) * percent;
			float b = lastFrameB + (frames[frameIndex + FRAME_B] - lastFrameB) * percent;
			float a = lastFrameA + (frames[frameIndex + FRAME_A] - lastFrameA) * percent;
			if (alpha < 1) {
				slot.r += (r - slot.r) * alpha;
				slot.g += (g - slot.g) * alpha;
				slot.b += (b - slot.b) * alpha;
				slot.a += (a - slot.a) * alpha;
			} else {
				slot.r = r;
				slot.g = g;
				slot.b = b;
				slot.a = a;
			}
		}
		override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
			float[] frames = this.frames;
			if (time < frames[0]) return; // Time is before first frame.

			Bone bone = skeleton.bones[boneIndex];
			if (time >= frames[frames.Length - 3]) { // Time is after last frame.
				bone.scaleX += (bone.data.scaleX - 1 + frames[frames.Length - 2] - bone.scaleX) * alpha;
				bone.scaleY += (bone.data.scaleY - 1 + frames[frames.Length - 1] - bone.scaleY) * alpha;
				return;
			}

			// Interpolate between the last frame and the current frame.
			int frameIndex = Animation.binarySearch(frames, time, 3);
			float lastFrameX = frames[frameIndex - 2];
			float lastFrameY = frames[frameIndex - 1];
			float frameTime = frames[frameIndex];
			float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime);
			percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));

			bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + FRAME_X] - lastFrameX) * percent - bone.scaleX) * alpha;
			bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + FRAME_Y] - lastFrameY) * percent - bone.scaleY) * alpha;
		}
		override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
			float[] frames = this.frames;
			if (time < frames[0]) return; // Time is before first frame.

			Bone bone = skeleton.bones[boneIndex];

			float amount;

			if (time >= frames[frames.Length - 2]) { // Time is after last frame.
				amount = bone.data.rotation + frames[frames.Length - 1] - bone.rotation;
				while (amount > 180)
					amount -= 360;
				while (amount < -180)
					amount += 360;
				bone.rotation += amount * alpha;
				return;
			}

			// Interpolate between the last frame and the current frame.
			int frameIndex = Animation.binarySearch(frames, time, 2);
			float lastFrameValue = frames[frameIndex - 1];
			float frameTime = frames[frameIndex];
			float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime);
			percent = GetCurvePercent(frameIndex / 2 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));

			amount = frames[frameIndex + FRAME_VALUE] - lastFrameValue;
			while (amount > 180)
				amount -= 360;
			while (amount < -180)
				amount += 360;
			amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation;
			while (amount > 180)
				amount -= 360;
			while (amount < -180)
				amount += 360;
			bone.rotation += amount * alpha;
		}
		abstract public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha);
        public void Load(Vector2 position,string name,float scale, float acceleration)
        {
            this.name = name;
            //----------Spine----------
            skeletonRenderer = new SkeletonRenderer(Game1.graphics.GraphicsDevice);
            skeletonRenderer.PremultipliedAlpha = true;

            Atlas atlas = new Atlas("spine/sprites/" + name + ".atlas", new XnaTextureLoader(Game1.graphics.GraphicsDevice));
            SkeletonJson json = new SkeletonJson(atlas);
            json.Scale = scale;
            skeleton = new Skeleton(json.ReadSkeletonData("spine/sprites/" + name + ".json"));
            skeleton.SetSlotsToSetupPose(); // Without this the skin attachments won't be attached. See SetSkin.

            // Define mixing between animations.
            AnimationStateData animationStateData = new AnimationStateData(skeleton.Data);
            float fading_standard = 0.2f;
            switch (name)
            {
                case "bonepuker":
                    animationStateData.SetMix("idle", "run", acceleration);
                    animationStateData.SetMix("run", "idle", acceleration);
                    animationStateData.SetMix("idle", "jump", 0.3f);
                    animationStateData.SetMix("run", "jump", 0.3f);
                    animationStateData.SetMix("jump", "run", 0.1f);
                    animationStateData.SetMix("jump", "idle", 0.3f);
                    animationStateData.SetMix("jump", "die", 0.3f);
                    animationStateData.SetMix("run", "die", 0.1f);
                    animationStateData.SetMix("idle", "die", 0.2f);
                    animationStateData.SetMix("smash", "idle", 0.2f);
                    animationStateData.SetMix("smash", "run", 0.2f);
                    animationStateData.SetMix("smash", "jump", 0.2f);
                    //Fading für Attack dürfte so nicht funktionieren, da Attack auf einem anderen Track ausgeführt wird
                    animationStateData.SetMix("attack", "idle", 0.1f);
                    animationStateData.SetMix("attack", "run", 0.1f);
                    animationStateData.SetMix("attack", "jump", 0.1f);
                    break;
                case "ashbrett":
                    fading_standard = 0.2f;
                    animationStateData.SetMix("idle", "walk", fading_standard);
                    animationStateData.SetMix("idle", "jump", fading_standard);
                    animationStateData.SetMix("idle", "attack", fading_standard);
                    animationStateData.SetMix("idle", "close", fading_standard);
                    animationStateData.SetMix("idle", "defend", fading_standard);
                    animationStateData.SetMix("idle", "die", fading_standard);
                    animationStateData.SetMix("idle", "hit", fading_standard);
                    animationStateData.SetMix("idle", "super_attack", fading_standard);

                    animationStateData.SetMix("walk", "idle", fading_standard);
                    animationStateData.SetMix("walk", "jump", fading_standard);
                    animationStateData.SetMix("walk", "attack", fading_standard);
                    animationStateData.SetMix("walk", "close", fading_standard);
                    animationStateData.SetMix("walk", "defend", fading_standard);
                    animationStateData.SetMix("walk", "die", fading_standard);
                    animationStateData.SetMix("walk", "hit", fading_standard);
                    animationStateData.SetMix("walk", "super_attack", fading_standard);

                    animationStateData.SetMix("jump", "idle", fading_standard);
                    animationStateData.SetMix("jump", "walk", fading_standard);
                    animationStateData.SetMix("jump", "attack", fading_standard);
                    animationStateData.SetMix("jump", "close", fading_standard);
                    animationStateData.SetMix("jump", "defend", fading_standard);
                    animationStateData.SetMix("jump", "die", fading_standard);
                    animationStateData.SetMix("jump", "hit", fading_standard);
                    animationStateData.SetMix("jump", "super_attack", fading_standard);

                    animationStateData.SetMix("attack", "idle", fading_standard);
                    animationStateData.SetMix("attack", "walk", fading_standard);
                    animationStateData.SetMix("attack", "jump", fading_standard);
                    animationStateData.SetMix("attack", "close", fading_standard);
                    animationStateData.SetMix("attack", "defend", fading_standard);
                    animationStateData.SetMix("attack", "die", fading_standard);
                    animationStateData.SetMix("attack", "hit", fading_standard);
                    animationStateData.SetMix("attack", "super_attack", fading_standard);

                    animationStateData.SetMix("close", "idle", fading_standard);
                    animationStateData.SetMix("close", "walk", fading_standard);
                    animationStateData.SetMix("close", "jump", fading_standard);
                    animationStateData.SetMix("close", "attack", fading_standard);
                    animationStateData.SetMix("close", "defend", fading_standard);
                    animationStateData.SetMix("close", "die", fading_standard);
                    animationStateData.SetMix("close", "hit", fading_standard);
                    animationStateData.SetMix("close", "super_attack", fading_standard);

                    animationStateData.SetMix("defend", "idle", fading_standard);
                    animationStateData.SetMix("defend", "walk", fading_standard);
                    animationStateData.SetMix("defend", "jump", fading_standard);
                    animationStateData.SetMix("defend", "attack", fading_standard);
                    animationStateData.SetMix("defend", "close", fading_standard);
                    animationStateData.SetMix("defend", "die", fading_standard);
                    animationStateData.SetMix("defend", "hit", fading_standard);
                    animationStateData.SetMix("defend", "super_attack", fading_standard);

                    animationStateData.SetMix("hit", "idle", fading_standard);
                    animationStateData.SetMix("hit", "walk", fading_standard);
                    animationStateData.SetMix("hit", "jump", fading_standard);
                    animationStateData.SetMix("hit", "attack", fading_standard);
                    animationStateData.SetMix("hit", "close", fading_standard);
                    animationStateData.SetMix("hit", "die", fading_standard);
                    animationStateData.SetMix("hit", "defend", fading_standard);
                    animationStateData.SetMix("hit", "super_attack", fading_standard);

                    animationStateData.SetMix("super_attack", "idle", fading_standard);
                    animationStateData.SetMix("super_attack", "walk", fading_standard);
                    animationStateData.SetMix("super_attack", "jump", fading_standard);
                    animationStateData.SetMix("super_attack", "attack", fading_standard);
                    animationStateData.SetMix("super_attack", "close", fading_standard);
                    animationStateData.SetMix("super_attack", "die", fading_standard);
                    animationStateData.SetMix("super_attack", "defend", fading_standard);
                    animationStateData.SetMix("super_attack", "hit", fading_standard);
                    break;
                case "fluffy":
                    fading_standard = 0.2f;
                    animationStateData.SetMix("attack", "die", fading_standard);
                    animationStateData.SetMix("attack", "smash_die", fading_standard);
                    animationStateData.SetMix("attack", "idle", fading_standard);
                    animationStateData.SetMix("attack", "walk", fading_standard);

                    animationStateData.SetMix("idle", "die", fading_standard);
                    animationStateData.SetMix("idle", "smash_die", fading_standard);
                    animationStateData.SetMix("idle", "attack", fading_standard);
                    animationStateData.SetMix("idle", "walk", fading_standard);

                    animationStateData.SetMix("walk", "die", fading_standard);
                    animationStateData.SetMix("walk", "smash_die", fading_standard);
                    animationStateData.SetMix("walk", "attack", fading_standard);
                    animationStateData.SetMix("walk", "idle", fading_standard);
                    break;
                case "skullmonkey":
                    fading_standard = 0.2f;
                    animationStateData.SetMix("attack", "dying", fading_standard);
                    animationStateData.SetMix("attack", "sitting", fading_standard);
                    animationStateData.SetMix("attack", "walking", fading_standard);

                    animationStateData.SetMix("sitting", "dying", fading_standard);
                    animationStateData.SetMix("sitting", "attack", fading_standard);
                    animationStateData.SetMix("sitting", "walking", fading_standard);

                    animationStateData.SetMix("walking", "dying", fading_standard);
                    animationStateData.SetMix("walking", "attack", fading_standard);
                    animationStateData.SetMix("walking", "sitting", fading_standard);
                    break;
                case "sweetcheeks":
                    fading_standard = 0.2f;
                    animationStateData.SetMix("attack", "die", fading_standard);
                    animationStateData.SetMix("attack", "hit", fading_standard);
                    animationStateData.SetMix("attack", "idle", fading_standard);
                    animationStateData.SetMix("attack", "jump", fading_standard);
                    animationStateData.SetMix("attack", "run", fading_standard);
                    animationStateData.SetMix("attack", "scream", fading_standard);

                    animationStateData.SetMix("hit", "die", fading_standard);
                    animationStateData.SetMix("hit", "attack", fading_standard);
                    animationStateData.SetMix("hit", "idle", fading_standard);
                    animationStateData.SetMix("hit", "jump", fading_standard);
                    animationStateData.SetMix("hit", "run", fading_standard);
                    animationStateData.SetMix("hit", "scream", fading_standard);

                    animationStateData.SetMix("idle", "die", fading_standard);
                    animationStateData.SetMix("idle", "attack", fading_standard);
                    animationStateData.SetMix("idle", "hit", fading_standard);
                    animationStateData.SetMix("idle", "jump", fading_standard);
                    animationStateData.SetMix("idle", "run", fading_standard);
                    animationStateData.SetMix("idle", "scream", fading_standard);

                    animationStateData.SetMix("jump", "die", fading_standard);
                    animationStateData.SetMix("jump", "attack", fading_standard);
                    animationStateData.SetMix("jump", "hit", fading_standard);
                    animationStateData.SetMix("jump", "idle", fading_standard);
                    animationStateData.SetMix("jump", "run", fading_standard);
                    animationStateData.SetMix("jump", "scream", fading_standard);

                    animationStateData.SetMix("run", "die", fading_standard);
                    animationStateData.SetMix("run", "attack", fading_standard);
                    animationStateData.SetMix("run", "hit", fading_standard);
                    animationStateData.SetMix("run", "idle", fading_standard);
                    animationStateData.SetMix("run", "jump", fading_standard);
                    animationStateData.SetMix("run", "scream", fading_standard);

                    animationStateData.SetMix("scream", "die", fading_standard);
                    animationStateData.SetMix("scream", "attack", fading_standard);
                    animationStateData.SetMix("scream", "hit", fading_standard);
                    animationStateData.SetMix("scream", "idle", fading_standard);
                    animationStateData.SetMix("scream", "jump", fading_standard);
                    animationStateData.SetMix("scream", "run", fading_standard);
                    break;
            }
            animationState = new AnimationState(animationStateData);

            // Event handling for all animations.
            /*
            animationState.Start += Start;
            animationState.End += End;
            animationState.Complete += Complete;
            animationState.Event += Event;
             * */

            skeleton.x = position.X;
            skeleton.y = position.Y;
        }