public new void Apply(Skeleton skeleton, float time, float alpha)
        {
            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 = SearchUtils.BinarySearch (frames, time, 3);
            float lastFrameX = frames [frameIndex - 2];
            float lastFrameY = frames [frameIndex - 1];
            float frameTime = frames [frameIndex];
            float percent = MathUtils.Clamp (1 - (time - frameTime) / (frames [frameIndex + LAST_FRAME_TIME] - frameTime), 0, 1);
            percent = GetCurvePercent (frameIndex / 3 - 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;
        }
        /** Copy constructor. */
        public Skeleton(Skeleton skeleton)
        {
            if (skeleton == null)
            {
                throw new ArgumentException("skeleton cannot be null.");
            }
            Data = skeleton.Data;

            Bones = new List<Bone>(skeleton.Bones.Count);
            foreach (Bone bone in skeleton.Bones)
            {
                Bone parent = Bones[skeleton.Bones.IndexOf(bone.Parent)];
                Bones.Add(new Bone(bone, parent));
            }

            Slots = new List<Slot>(skeleton.Slots.Count);
            foreach (Slot slot in skeleton.Slots)
            {
                Bone bone = Bones[skeleton.Bones.IndexOf(slot.Bone)];
                var newSlot = new Slot(slot, this, bone);
                Slots.Add(newSlot);
            }

            DrawOrder = new List<Slot>(Slots.Count);
            foreach (Slot slot in skeleton.DrawOrder)
                DrawOrder.Add(Slots[skeleton.Slots.IndexOf(slot)]);

            Skin = skeleton.Skin;
            Color = skeleton.Color;
            Time = skeleton.Time;
        }
        public void Apply(Skeleton skeleton, float time, 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 - 2])
            { // Time is after last frame.
                float rotationAmount = bone.Data.Rotation + frames [frames.Length - 1] - bone.rotation;
                while (rotationAmount > 180)
                {
                    rotationAmount -= 360;
                }

                while (rotationAmount < -180)
                {
                    rotationAmount += 360;
                }

                bone.rotation += rotationAmount * alpha;
                return;
            }

            // Interpolate between the last frame and the current frame.
            int frameIndex = SearchUtils.BinarySearch (frames, time, 2);
            float lastFrameValue = frames [frameIndex - 1];
            float frameTime = frames [frameIndex];
            float percent = MathUtils.Clamp (1 - (time - frameTime) / (frames [frameIndex + LAST_FRAME_TIME] - frameTime), 0, 1);
            percent = GetCurvePercent (frameIndex / 2 - 1, percent);

            float 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;
        }
        public void Apply(Skeleton skeleton, float time, float alpha)
        {
            if (time < frames[0])
            {
                return;
            } // Time is before first frame.

            Color color = skeleton.Slots[slotIndex].Color;

            if (time >= frames[frames.Length - 5])
            {
                // Time is after last frame.
                int i = frames.Length - 1;
                float colorRed = frames[i - 3];
                float colorGreen = frames[i - 2];
                float colorBlue = frames[i - 1];
                float colorAlpha = frames[i];
                color = new Color(colorRed, colorGreen, colorBlue, colorAlpha);
                return;
            }

            // Interpolate between the last frame and the current frame.
            int frameIndex = SearchUtils.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 = MathUtils.Clamp(1 - (time - frameTime)/(frames[frameIndex + LAST_FRAME_TIME] - frameTime), 0, 1);
            percent = GetCurvePercent(frameIndex/5 - 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)
            {
                color = new Color(
                    MathUtils.Clamp(color.R + ((r - color.R)*alpha), 0, 1),
                    MathUtils.Clamp(color.G + ((g - color.G)*alpha), 0, 1),
                    MathUtils.Clamp(color.B + ((b - color.B)*alpha), 0, 1),
                    MathUtils.Clamp(color.A + ((a - color.A)*alpha), 0, 1));
            }
            else
            {
                color = new Color(r, g, b, a);
            }
        }
 public Slot(SlotData data, Skeleton skeleton, Bone bone)
 {
     if (data == null)
     {
         throw new ArgumentException ("data cannot be null.");
     }
     if (skeleton == null)
     {
         throw new ArgumentException ("skeleton cannot be null.");
     }
     if (bone == null)
     {
         throw new ArgumentException ("bone cannot be null.");
     }
     this.Data = data;
     this.Skeleton = skeleton;
     this.Bone = bone;
     this.Color = new Color (1, 1, 1, 1);
     this.SetToBindPose ();
 }
        public void Apply(Skeleton skeleton, float time, float alpha)
        {
            if (time < this.frames [0])
            {
                return;
            } // Time is before first frame.

            int frameIndex;
            if (time >= this.frames [this.frames.Length - 1])
            { // Time is after last frame.
                frameIndex = this.frames.Length - 1;
            }
            else
            {
                frameIndex = SearchUtils.BinarySearch (this.frames, time, 1) - 1;
            }

            String attachmentName = this.attachmentNames [frameIndex];
            skeleton.Slots [slotIndex].SetAttachment (
                attachmentName == null ? null : skeleton.GetAttachment (slotIndex, attachmentName));
        }
        /** Copy constructor. */
        public Slot(Slot slot, Skeleton skeleton, Bone bone)
        {
            if (slot == null)
            {
                throw new ArgumentException ("slot cannot be null.");
            }
            if (skeleton == null)
            {
                throw new ArgumentException ("skeleton cannot be null.");
            }
            if (bone == null)
            {
                throw new ArgumentException ("bone cannot be null.");
            }

            Data = slot.Data;
            this.Skeleton = skeleton;
            this.Bone = bone;
            Color = slot.Color;
            attachment = slot.attachment;
            attachmentTime = slot.attachmentTime;
        }
        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(_graphicsDeviceManager.GraphicsDevice);
            #if WINDOWS
            var crabTextureMap = Content.Load<Texture2D>("crab");
            #else
            var crabTextureMap = Content.Load<Texture2D> ("crab.png");
            #endif
            _textureMaps.Add(crabTextureMap);

            var texturePackerReader = new TextureMapJsonReader();
            #if WINDOWS
            TextureAtlas textureAtlas = texturePackerReader.ReadTextureJsonFile("Content/crab.json", crabTextureMap);
            #elif ANDROID
            var textureAtlas = texturePackerReader.ReadTextureJsonFile (Activity,"Content/crab.json", crabTextureMap);
            #endif
            var skeletonReader = new SkeletonJsonReader(new TextureAtlasAttachmentLoader(textureAtlas));
            #if WINDOWS
            _skeleton = skeletonReader.ReadSkeletonJsonFile("Content/crab-skeleton.json");
            #elif ANDROID

            this.skeleton = skeletonReader.ReadSkeletonJsonFile (Activity,"Content/crab-skeleton.json");
            #endif
            _skeleton.FlipY = true;

            var animationReader = new AnimationJsonReader();
            #if WINDOWS
            _animationWalk = animationReader.ReadAnimationJsonFile("Content/crab-WalkLeft.json", _skeleton.Data);
            _animationJump = animationReader.ReadAnimationJsonFile("Content/crab-Jump.json", _skeleton.Data);
            #elif ANDROID

            this.animationWalk = animationReader.ReadAnimationJsonFile ( Activity,"Content/crab-WalkLeft.json", skeleton.Data);
            this.animationJump = animationReader.ReadAnimationJsonFile (Activity,"Content/crab-Jump.json", skeleton.Data);
            #endif
            _animation = 0;
            SetSkeletonStartPosition();

            // used for debugging - draw the bones
            _lineTexture = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
            _lineTexture.SetData(new[] {Color.White});
            _textureMaps.Add(_lineTexture);

            base.LoadContent();
        }