Inheritance: FlatRedBallExtensions.ScaledPositionedObject
Esempio n. 1
0
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            Renderer.UseRenderTargets = false;
            FlatRedBallServices.InitializeFlatRedBall(this, graphics);
            GlobalContent.Initialize();

            FlatRedBall.Screens.ScreenManager.Start(typeof(TestableGame.Screens.TestScreen));

            SpriteManager.Camera.BackgroundColor = Color.Black;

            IsMouseVisible = true;

            this.runner = new TestRunner<Game1>(this.Services);
            this.reporter = new XnaTestReporter();
            this.runner.Reporter(this.reporter);

            this.font = this.Content.Load<SpriteFont>("font");

            var sos =
                SpriterObjectSave.FromFile(
                    @"c:\flatredballprojects\flatredball-spriter\spriterfiles\simpleballanimation\simpleballanimation.scml");

            var oldDir = FileManager.RelativeDirectory;
            FileManager.RelativeDirectory =
                FileManager.GetDirectory(
                    @"c:/flatredballprojects/flatredball-spriter/spriterfiles/simpleballanimation/ball.png");
            so = sos.ToRuntime();
            FileManager.RelativeDirectory = oldDir;

            so.X = 300f;
            so.Y = 300f;

            so.AddToManagers(null);
            SpriteManager.Camera.Position.Z += 1900;
            SpriteManager.Camera.Position.Y -= 300;

            SpriteManager.Camera.FarClipPlane = 30000f;
            base.Initialize();
        }
        public SpriterObject Clone()
        {
            var so = new SpriterObject(FlatRedBallServices.GlobalContentManager, false)
            {
                Animations = new Dictionary<string, SpriterObjectAnimation>()
            };

            var allObjects =
                Animations.Select(a => a.Value)
                    .SelectMany(v => v.KeyFrames)
                    .SelectMany(kf => kf.Values)
                    .Select(kfv => kfv.Key)
                    .GroupBy(k => k.Name)
                    .Select(g => g.First().Clone<PositionedObject>())
                    .ToList();

            foreach (var animationPair in Animations)
            {
                var keyframes = new List<KeyFrame>();
                animationPair.Value.KeyFrames.ForEach(kf =>
                    {
                        var keyFrame = new KeyFrame
                            {
                                Time = kf.Time,
                                Values = new Dictionary<PositionedObject, KeyFrameValues>(kf.Values.Count)
                            };

                        foreach (var kfPair in kf.Values)
                        {
                            var parent = kfPair.Value.Parent == null || kfPair.Value.Parent.Name == null
                                ? null
                                : allObjects.First(k => k.Name == kfPair.Value.Parent.Name);

                            var kfv = new KeyFrameValues
                            {
                                Alpha = kfPair.Value.Alpha,
                                Parent = parent,
                                RelativePosition = kfPair.Value.RelativePosition,
                                RelativeRotation = kfPair.Value.RelativeRotation,
                                RelativeScaleX = kfPair.Value.RelativeScaleX,
                                RelativeScaleY = kfPair.Value.RelativeScaleY,
                                Spin = kfPair.Value.Spin,
                                Texture = kfPair.Value.Texture
                            };

                            keyFrame.Values[allObjects.First(k => k.Name == kfPair.Key.Name)] = kfv;
                        }
                        keyframes.Add(keyFrame);
                    });
                so.Animations[animationPair.Key] = new SpriterObjectAnimation(animationPair.Value.Name,
                                                                              animationPair.Value.Looping,
                                                                              animationPair.Value.TotalTime,
                                                                              keyframes);
            }
            so.ObjectList = so.Animations.Select(a => a.Value)
                    .SelectMany(v => v.KeyFrames)
                    .SelectMany(kf => kf.Values)
                    .Select(kfv => kfv.Key)
                    .GroupBy(k => k.Name)
                    .Select(g => g.First())
                    .ToList();

            return so;
        }
        private static SpriterObject GetSimpleSpriterObject(bool loops = false)
        {
            var so = new SpriterObject("Global", false);

            var sprite = new ScaledSprite();
            var pivot = new ScaledPositionedObject();
            pivot.AttachTo(so, true);
            sprite.AttachTo(pivot, true);
            sprite.Name = "sprite";
            pivot.Name = "pivot";

            so.Animations.Add("", new SpriterObjectAnimation("", loops, 2.0f, new List<KeyFrame>()));

            // first keyframe (0ms)
            var keyFrame = new KeyFrame
            {
                Time = 0
            };

            // The pivot is at 30,30
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = new Vector3(30f, 30f, 0f)
            };
            // Sprite is just there to connect to the pivot
            keyFrame.Values[sprite] = new KeyFrameValues
            {
                Alpha = 1.0f,
                Parent = pivot,
                RelativeScaleX = 1.0f,
                RelativeScaleY = 1.0f
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            keyFrame = new KeyFrame
            {
                Time = 1.0f
            };
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = Vector3.Zero
            };

            keyFrame.Values[sprite] = new KeyFrameValues
            {
                Alpha = 1.0f,
                Parent = pivot,
                RelativeScaleX = 1.0f,
                RelativeScaleY = 1.0f,
                RelativePosition = Vector3.Zero
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            so.ObjectList.Add(sprite);
            so.ObjectList.Add(pivot);

            //so.AddToManagers(null);
            return so;
        }
        private SpriterObject CreateSpriterObjectFromEntity(SpriterDataEntity entity)
        {
            var spriterObject = new SpriterObject(FlatRedBallServices.GlobalContentManager, false);

            IDictionary<string, string> filenames = new Dictionary<string, string>();
            IDictionary<int, ScaledSprite> persistentScaledSprites = new Dictionary<int, ScaledSprite>();
            IDictionary<int, SpriterBone> persistentBones = new Dictionary<int, SpriterBone>();
            IDictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>();
            IDictionary<string, ObjectInfo> boxes = new Dictionary<string, ObjectInfo>();
            IDictionary<int, ScaledPositionedObject> boneRefDic = new Dictionary<int, ScaledPositionedObject>();
            IDictionary<KeyFrameValues, int> keyFrameValuesParentDictionary = new Dictionary<KeyFrameValues, int>();
            IDictionary<int, ScaledPolygon> persistentScaledPolygons = new Dictionary<int, ScaledPolygon>();
            IDictionary<int, SpriterPoint> persistentPoints = new Dictionary<int, SpriterPoint>();

            string oldDir = FileManager.RelativeDirectory;
            FileManager.RelativeDirectory = this.Directory;
            foreach (var folder in this.Folder)
            {
                foreach (var file in folder.File)
                {
                    string folderFileId = string.Format("{0}_{1}", folder.Id, file.Id);
                    filenames[folderFileId] = file.Name;
                    textures[folderFileId] = LoadTexture(file);
                }
            }
            FileManager.RelativeDirectory = oldDir;

            if (entity.ObjectInfos != null)
            {
                boxes =
                    entity.ObjectInfos.Where(oi => oi.Type == "box")
                        .ToDictionary(s => s.Name);
            }

            foreach (var animation in entity.Animation)
            {
                var mainline = animation.Mainline;
                var keyFrameList = new List<KeyFrame>();

                foreach (var key in mainline.Keys)
                {
                    var keyFrame = new KeyFrame {Time = key.Time/1000.0f};

                    // If it's a ScaledSprite (not a bone)
                    if (key.ObjectRef != null)
                    {
                        CreateRuntimeObjectsForSpriterObjectRef(key, persistentScaledSprites, spriterObject, animation, textures,
                            keyFrame, keyFrameValuesParentDictionary, boxes, persistentScaledPolygons, persistentPoints);
                    }

                    // If it's a bone (not a ScaledSprite)
                    if (key.BoneRef != null)
                    {
                        CreateRuntimeObjectsForSpriterBoneRef(key, persistentBones, spriterObject, animation, keyFrame,
                            boneRefDic, keyFrameValuesParentDictionary, entity);
                    }

                    keyFrameList.Add(keyFrame);
                }

                HandleUnreferencedTimelinekeys(animation, mainline, keyFrameList, persistentScaledSprites, spriterObject,
                    textures, keyFrameValuesParentDictionary, persistentBones, boneRefDic, boxes, persistentScaledPolygons,
                    persistentPoints, entity);

                // find all the keyframevalues, and look up the bone id, then take that bone id and
                // set the parent in the keyframevalues variable to the ScaledPositionedObject in the boneRefDic
                foreach (var pair in keyFrameList.SelectMany(keyFrame => keyFrame.Values))
                {
                    if (keyFrameValuesParentDictionary.ContainsKey(pair.Value))
                    {
                        int boneId = keyFrameValuesParentDictionary[pair.Value];
                        var parent = boneRefDic[boneId];
                        pair.Value.Parent = parent;
                    }
                    else if (pair.Key.GetType() != typeof (ScaledSprite) && pair.Key.GetType() != typeof (ScaledPolygon))
                    {
                        pair.Value.Parent = spriterObject;
                    }
                }

                var SpriterObjectAnimation = new SpriterObjectAnimation(animation.Name,
                    animation.Looping, animation.Length/1000.0f,
                    keyFrameList);
                spriterObject.Animations[animation.Name] = SpriterObjectAnimation;
            }
            return spriterObject;
        }
        private void HandleUnreferencedTimelinekeys(SpriterDataEntityAnimation animation, SpriterDataEntityAnimationMainline mainline, List<KeyFrame> keyFrameList, IDictionary<int, ScaledSprite> persistentScaledSprites, SpriterObject SpriterObject, IDictionary<string, Texture2D> textures, IDictionary<KeyFrameValues, int> keyFrameValuesParentDictionary, IDictionary<int, SpriterBone> persistentBones, IDictionary<int, ScaledPositionedObject> boneRefDic, IDictionary<string, ObjectInfo> boxes, IDictionary<int, ScaledPolygon> persistentScaledPolygons, IDictionary<int, SpriterPoint> persistentPoints, SpriterDataEntity entity)
        {
            foreach (var timeline in animation.Timeline)
            {
                foreach (var timelineKey in timeline.Key)
                {
                    // if timeline key has an object, and no mainline keys for objects reference this key
                    if (timelineKey.Object != null &&
                        !mainline.Keys.Where(k => k.ObjectRef != null)
                                 .Any(k => k.ObjectRef.Any(r => r.Key == timelineKey.Id && r.Timeline == timeline.Id)) ||
                        timelineKey.Bone != null &&
                        !mainline.Keys.Where(k => k.BoneRef != null)
                                 .Any(k => k.BoneRef.Any(r => r.Key == timelineKey.Id && r.Timeline == timeline.Id)))
                    {
                        int index = keyFrameList.FindLastIndex(kf => Math.Abs(kf.Time - (timelineKey.Time/1000.0f)) < .0001f);
                        if (index > 0)
                        {
                            var keyFrame = new KeyFrame {Time = timelineKey.Time/1000.0f};
                            var mainlineKey = mainline.Keys.Single(k => k.Time == timelineKey.Time);
                            if (mainlineKey.ObjectRef != null && timelineKey.Object != null)
                            {
                                CreateRuntimeObjectsForSpriterObjectRef(mainlineKey, persistentScaledSprites,
                                                                        SpriterObject, animation, textures, keyFrame,
                                                                        keyFrameValuesParentDictionary, boxes, persistentScaledPolygons, persistentPoints, timelineKeyOverride: timelineKey);
                            }

                            if (mainlineKey.BoneRef != null && timelineKey.Bone != null)
                            {
                                CreateRuntimeObjectsForSpriterBoneRef(mainlineKey, persistentBones, SpriterObject,
                                                                      animation, keyFrame, boneRefDic,
                                                                      keyFrameValuesParentDictionary, entity, timelineKey);
                            }
                            keyFrameList.Insert(index, keyFrame);
                        }
                    }
                }
            }
        }
        private void CreateRuntimeObjectsForSpriterObjectRef(Key key, IDictionary<int, ScaledSprite> persistentScaledSprites, SpriterObject SpriterObject, SpriterDataEntityAnimation animation, IDictionary<string, Texture2D> textures, KeyFrame keyFrame, IDictionary<KeyFrameValues, int> SpriterefParentDic, IDictionary<string, ObjectInfo> boxes, IDictionary<int, ScaledPolygon> persistentScaledPolygons, IDictionary<int, SpriterPoint> persistentPoints, Key timelineKeyOverride = null)
        {
            foreach (var objectRef in key.ObjectRef)
            {
                var timeline = animation.Timeline.Single(t => t.Id == objectRef.Timeline);
                Key timelineKey = timelineKeyOverride ?? timeline.Key.Single(k => k.Id == objectRef.Key);
                if (timelineKeyOverride == null && key.Time != timelineKey.Time)
                {
                    var nextTimelineKey = timeline.Key.FirstOrDefault(k => k.Time > key.Time) ??
                                          new Key(timeline.Key.First()) { Time = animation.Length };

                    timelineKey = InterpolateToNewTimelineKey(key, timelineKey, nextTimelineKey);
                }

                if (timeline.ObjectType == "box")
                {
                    ScaledPolygon scaledPolygon;
                    ScaledPositionedObject pivot;
                    var box = boxes[timeline.Name];

                    if (persistentScaledPolygons.ContainsKey(objectRef.Id))
                    {
                        scaledPolygon = persistentScaledPolygons[objectRef.Id];
                        pivot = (ScaledPositionedObject)scaledPolygon.Parent;
                    }
                    else
                    {
                        scaledPolygon = ScaledPolygon.CreateRectangle(timelineKey.Object.X, timelineKey.Object.Y, (int)box.Width, (int)box.Height);
                        scaledPolygon.ParentScaleChangesPosition = false;
                        scaledPolygon.Visible = false;

                        var name = objectRef.Name ?? objectRef.Id.ToString(CultureInfo.InvariantCulture);
                        pivot = new ScaledPositionedObject { Name = string.Format("{0}_pivot", name) };

                        scaledPolygon.Name = timeline.Name;

                        scaledPolygon.AttachTo(pivot, true);
                        pivot.AttachTo(SpriterObject, true);

                        persistentScaledPolygons[objectRef.Id] = scaledPolygon;
                        SpriterObject.ObjectList.Add(scaledPolygon);
                        SpriterObject.ObjectList.Add(pivot);
                    }

                    var values = GetKeyFrameValues(timelineKey, box, objectRef);

                    values.ScaledPolygon.Parent = pivot;
                    if (objectRef.Parent.HasValue)
                    {
                        SpriterefParentDic[values.Pivot] = objectRef.Parent.Value;
                    }
                    else
                    {
                        values.Pivot.Parent = SpriterObject;
                    }

                    keyFrame.Values[pivot] = values.Pivot;
                    keyFrame.Values[scaledPolygon] = values.ScaledPolygon;
                }
                else if (timeline.ObjectType == "point")
                {
                    SpriterPoint point;

                    if (persistentPoints.ContainsKey(objectRef.Id))
                    {
                        point = persistentPoints[objectRef.Id];
                    }
                    else
                    {
                        point = new SpriterPoint
                        {
                            X = timelineKey.Object.X,
                            Y = timelineKey.Object.Y,
                            Name = timeline.Name
                        };
                        SpriterObject.ObjectList.Add(point);
                        persistentPoints[objectRef.Id] = point;
                    }

                    KeyFrameValues values = GetKeyFrameValuesForPoint(timelineKey, objectRef);

                    if (objectRef.Parent.HasValue)
                    {
                        SpriterefParentDic[values] = objectRef.Parent.Value;
                    }
                    else
                    {
                        values.Parent = SpriterObject;
                    }

                    keyFrame.Values[point] = values;
                }
                else if (string.IsNullOrEmpty(timeline.ObjectType))
                {
                    var folderFileId = string.Format("{0}_{1}", timelineKey.Object.Folder,
                        timelineKey.Object.File);
                    var file =
                        this.Folder.First(f => f.Id == timelineKey.Object.Folder)
                            .File.First(f => f.Id == timelineKey.Object.File);

                    ScaledSprite scaledSprite;
                    ScaledPositionedObject pivot;
                    if (persistentScaledSprites.ContainsKey(objectRef.Id))
                    {
                        scaledSprite = persistentScaledSprites[objectRef.Id];
                        pivot = (ScaledPositionedObject) scaledSprite.Parent;
                    }
                    else
                    {
                        var name = objectRef.Name ?? objectRef.Id.ToString(CultureInfo.InvariantCulture);
                        pivot = new ScaledPositionedObject {Name = string.Format("{0}_pivot", name)};

                        scaledSprite = new ScaledSprite
                        {
                            Name = string.Format("{0}_sprite", name),
                            Width = file.Width,
                            Height = file.Height,
                            ParentScaleChangesPosition = false
                        };

                        scaledSprite.AttachTo(pivot, true);
                        pivot.AttachTo(SpriterObject, true);

                        persistentScaledSprites[objectRef.Id] = scaledSprite;
                        SpriterObject.ObjectList.Add(scaledSprite);
                        SpriterObject.ObjectList.Add(pivot);
                    }

                    var values = GetKeyFrameValues(timelineKey, file, textures, folderFileId, objectRef);

                    values.ScaledSprite.Parent = pivot;
                    if (objectRef.Parent.HasValue)
                    {
                        SpriterefParentDic[values.Pivot] = objectRef.Parent.Value;
                    }
                    else
                    {
                        values.Pivot.Parent = SpriterObject;
                    }

                    keyFrame.Values[pivot] = values.Pivot;
                    keyFrame.Values[scaledSprite] = values.ScaledSprite;
                }
            }
        }
        private static void CreateRuntimeObjectsForSpriterBoneRef(Key key, IDictionary<int, SpriterBone> persistentBones,
                                                                  SpriterObject SpriterObject,
                                                                  SpriterDataEntityAnimation animation, KeyFrame keyFrame,
                                                                  IDictionary<int, ScaledPositionedObject> boneRefDic, IDictionary<KeyFrameValues, int> boneRefParentDic, SpriterDataEntity entity,
                                                                  Key timelineKeyOverride = null)
        {
            IDictionary<int, KeyBone> bones = new Dictionary<int, KeyBone>();

            foreach (var boneRef in key.BoneRef)
            {
                SpriterBone bone;
                var timeline = animation.Timeline.Single(t => t.Id == boneRef.Timeline);

                if (persistentBones.ContainsKey(boneRef.Id))
                {
                    bone = persistentBones[boneRef.Id];
                }
                else
                {
                    var objectInfo = entity.ObjectInfos == null ? (ObjectInfo)null : entity.ObjectInfos.FirstOrDefault(o => o.Type == "bone" && o.Name == timeline.Name);
                    bone = new SpriterBone
                    {
                        Name = timeline.Name,
                        Length = objectInfo == null ? 200 : objectInfo.Width
                    };

                    bone.AttachTo(SpriterObject, true);

                    persistentBones[boneRef.Id] = bone;
                    SpriterObject.ObjectList.Add(bone);
                }

                var timelineKey = timelineKeyOverride ?? timeline.Key.Single(k => k.Id == boneRef.Key);
                if (timelineKeyOverride == null && key.Time != timelineKey.Time)
                {
                    var nextTimelineKey = timeline.Key.FirstOrDefault(k => k.Time > key.Time) ?? new Key(timeline.Key.First()) { Time = animation.Length };

                    timelineKey = InterpolateToNewTimelineKey(key, timelineKey, nextTimelineKey);
                }

                var timelineKeyBone = new KeyBone(timelineKey.Bone);

                bones[boneRef.Id] = timelineKeyBone;

                keyFrame.Values[bone] = new KeyFrameValues
                    {
                        RelativePosition = new Vector3(timelineKeyBone.X, timelineKeyBone.Y, 0.0f),
                        RelativeRotation = new Vector3(0.0f, 0.0f, timelineKeyBone.Angle),
                        RelativeScaleX = timelineKeyBone.ScaleX,
                        RelativeScaleY = timelineKeyBone.ScaleY,
                        Spin = timelineKey.Spin
                    };

                boneRefDic[boneRef.Id] = bone;
                if (boneRef.Parent.HasValue)
                {
                    boneRefParentDic[keyFrame.Values[bone]] = boneRef.Parent.Value;
                }
            }
        }
Esempio n. 8
0
        protected virtual void InitializeEntity(bool addToManagers)
        {
            // Generated Initialize
            LoadStaticContent(ContentManagerName);
            mBirdCollision = BirdShapeCollection.Clone();
            BirdSpriterObject = SpriterObjectCollectionFile.FindByName("Bird").Clone();

            PostInitialize();
            if (addToManagers)
            {
                AddToManagers(null);
            }
        }
        public void Test2Objects()
        {
            var so = new SpriterObject("Global", false);

            var sprite = new ScaledSprite();
            var pivot = new ScaledPositionedObject();
            var sprite2 = new ScaledSprite();
            var pivot2 = new ScaledPositionedObject();

            pivot.AttachTo(so, true);
            sprite.AttachTo(pivot, true);

            pivot2.AttachTo(so, true);
            sprite2.AttachTo(pivot2, true);
            so.Animations.Add("", new SpriterObjectAnimation("", true, 2.0f, new List<KeyFrame>()));

            var keyFrame = new KeyFrame
            {
                Time = 0
            };
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = Vector3.Zero
            };
            keyFrame.Values[pivot2] = new KeyFrameValues
            {
                RelativePosition = Vector3.Zero
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            keyFrame = new KeyFrame
            {
                Time = 1.0f
            };
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = new Vector3(0f, 10f, 0f)
            };
            keyFrame.Values[pivot2] = new KeyFrameValues
            {
                RelativePosition = new Vector3(10f, 0f, 0f)
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            so.ObjectList.Add(sprite);
            so.ObjectList.Add(pivot);
            so.ObjectList.Add(sprite2);
            so.ObjectList.Add(pivot2);

            so.StartAnimation();
            TimeManager.CurrentTime += .5;
            so.TimedActivity(.5f, 0f, 0f);

            Assert.AreEqual(5f, so.ObjectList[1].Position.Y);
            Assert.AreEqual(5f, so.ObjectList[3].Position.X);

            TimeManager.CurrentTime += .25;
            so.TimedActivity(.25f, 0f, 0f);
            Assert.AreEqual(7.5f, so.ObjectList[1].Position.Y);
            Assert.AreEqual(7.5f, so.ObjectList[3].Position.X);
        }
        public void BoneReparenting()
        {
            var so = new SpriterObject("Global", false);
            var bone1 = new ScaledPositionedObject();
            var bone2 = new ScaledPositionedObject();

            so.Animations.Add("", new SpriterObjectAnimation("", false, 2.0f, new List<KeyFrame>()));

            var keyFrame = new KeyFrame
            {
                Time = 0f
            };

            keyFrame.Values[bone1] = new KeyFrameValues
            {
                Parent = so
            };

            keyFrame.Values[bone2] = new KeyFrameValues { Parent = bone1 };
            so.Animations[""].KeyFrames.Add(keyFrame);

            keyFrame = new KeyFrame
            {
                Time = 1.0f
            };

            keyFrame.Values[bone1] = new KeyFrameValues { RelativePosition = new Vector3(100f, 0f, 0f), Parent = so };
            keyFrame.Values[bone2] = new KeyFrameValues
            {
                Parent = so
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            so.ObjectList.Add(bone1);
            so.ObjectList.Add(bone2);

            so.StartAnimation();

            so.TimedActivity(.5f, 0f, 0f);
            Assert.AreSame(so.ObjectList[0], so.ObjectList[1].Parent);
            Assert.AreSame(so, so.ObjectList[0].Parent);

            so.TimedActivity(.5f, 0f, 0f);
            Assert.AreSame(so, so.ObjectList[1].Parent);
            Assert.AreSame(so, so.ObjectList[0].Parent);
        }