Ejemplo n.º 1
0
        public void VerticalMachine()
        {
            verticalMachine = Fsm <VState, VTrigger> .Builder(VState.STANDING)
                              .State(VState.STANDING)
                              .TransitionTo(VState.DUCKING)
                              .On(VTrigger.DOWN_PRESSED)
                              .TransitionTo(VState.JUMPING)
                              .On(VTrigger.UP_PRESSED)
                              .State(VState.DUCKING)
                              .TransitionTo(VState.STANDING)
                              .On(VTrigger.DOWN_RELEASED)
                              .State(VState.JUMPING)
                              .TransitionTo(VState.DIVING)
                              .On(VTrigger.DOWN_PRESSED)
                              .State(VState.DESCENDING)
                              .TransitionTo(VState.DIVING)
                              .On(VTrigger.DOWN_PRESSED)
                              .State(VState.DIVING)
                              .TransitionTo(VState.DESCENDING)
                              .On(VTrigger.DOWN_RELEASED)
                              .GlobalTransitionTo(VState.STANDING)
                              .OnGlobal(VTrigger.SPACE_PRESSED)
                              .Build();

            string s = verticalMachine.GetPlantUml();
        }
Ejemplo n.º 2
0
        public void StateChangesStandingDuckingJumpingDiving()
        {
            var m = Fsm <State, Trigger> .Builder(State.STANDING)
                    .State(State.DUCKING)
                    .TransitionTo(State.STANDING).On(Trigger.UP)
                    .State(State.STANDING)
                    .TransitionTo(State.DUCKING).On(Trigger.DOWN)
                    .TransitionTo(State.JUMPING).On(Trigger.UP)
                    .State(State.JUMPING)
                    .TransitionTo(State.DIVING).On(Trigger.DOWN)
                    .State(State.DIVING)
                    .Build();

            Assert.That(m.Current.Identifier, Is.EqualTo(State.STANDING));
            m.Trigger(Trigger.DOWN);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.DUCKING));
            m.Trigger(Trigger.DOWN);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.DUCKING));
            m.Trigger(Trigger.UP);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.STANDING));
            m.Trigger(Trigger.UP);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.JUMPING));
            m.Trigger(Trigger.UP);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.JUMPING));
            m.Trigger(Trigger.DOWN);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.DIVING));
        }
Ejemplo n.º 3
0
        public void WhenMultipleAfterConditionsFireOnASingleUpdateOnEnterAndOnExitShoudFire()
        {
            var enterCount = 0;
            var exitCount  = 0;
            var m          = Fsm <State, Trigger> .Builder(State.IDLE)
                             .State(State.IDLE)
                             .OnEnter(t => enterCount++)
                             .OnExit(t => exitCount++)
                             .TransitionTo(State.OVER).After(TimeSpan.FromMilliseconds(10))
                             .State(State.OVER)
                             .OnEnter(t => enterCount++)
                             .OnExit(t => exitCount++)
                             .TransitionTo(State.PRESSED).After(TimeSpan.FromMilliseconds(10))
                             .State(State.PRESSED)
                             .OnEnter(t => enterCount++)
                             .OnExit(t => exitCount++)
                             .TransitionTo(State.REFRESHING).After(TimeSpan.FromMilliseconds(10))
                             .State(State.REFRESHING)
                             .OnEnter(t => enterCount++)
                             .OnExit(t => exitCount++)
                             .TransitionTo(State.IDLE).After(TimeSpan.FromMilliseconds(10))
                             .Build();

            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Update(TimeSpan.FromMilliseconds(40));
            Assert.That(enterCount, Is.EqualTo(4));
            Assert.That(exitCount, Is.EqualTo(4));
        }
Ejemplo n.º 4
0
        public void WhenBuiltWithBuilderAndStringsStackMachineShouldWork()
        {
            var m = Fsm <string, string> .Builder("OPENED")
                    .EnableStack()
                    .State("OPENED")
                    .TransitionTo("OPENED").On("OPEN")
                    .TransitionTo("CLOSED").On("CLOSE")
                    .State("CLOSED").ClearsStack()
                    .TransitionTo("CLOSED").On("CLOSE")
                    .TransitionTo("OPENED").On("OPEN")
                    .Build();

            m.Trigger("OPEN");
            Assert.That(m.Current.Identifier, Is.EqualTo("OPENED"));
            Assert.That(m.Stack.Select(x => x.Identifier).ToArray(), Is.EquivalentTo(new[] { "OPENED", "OPENED" }));

            m.Trigger("CLOSE");
            Assert.That(m.Current.Identifier, Is.EqualTo("CLOSED"));
            Assert.That(m.Stack.ToArray(), Is.EquivalentTo(new State <State, Trigger>[] { }));

            m.Trigger("CLOSE");
            Assert.That(m.Current.Identifier, Is.EqualTo("CLOSED"));
            Assert.That(m.Stack.ToArray(), Is.EquivalentTo(new State <State, Trigger>[] { }));

            m.Trigger("OPEN");
            Assert.That(m.Current.Identifier, Is.EqualTo("OPENED"));
            Assert.That(m.Stack.Select(x => x.Identifier).ToArray(), Is.EquivalentTo(new[] { "OPENED" }));
        }
Ejemplo n.º 5
0
        public void Main()
        {
            var hero = new Hero();

            CreateMachineFor(Fsm <State, Trigger> .Builder(State.IDLE), new Button(), hero);
            CreateMachineFor(Fsm <State, Trigger> .Builder(State.IDLE), new Button(), hero);
        }
Ejemplo n.º 6
0
        public void WhenBuiltWithBuilderStackMachineShouldWork()
        {
            var m = Fsm <State, Trigger> .Builder(State.OPENED)
                    .EnableStack()
                    .State(State.OPENED)
                    .TransitionTo(State.OPENED).On(Trigger.OPEN)
                    .TransitionTo(State.CLOSED).On(Trigger.CLOSE)
                    .State(State.CLOSED).ClearsStack()
                    .TransitionTo(State.CLOSED).On(Trigger.CLOSE)
                    .TransitionTo(State.OPENED).On(Trigger.OPEN)
                    .Build();

            AssertSimpleTest(m);
        }
Ejemplo n.º 7
0
        public void WhenMultipleAfterConditionsFireOnASingleUpdateAdvanceStateCorrectly()
        {
            var m = Fsm <State, Trigger> .Builder(State.IDLE)
                    .State(State.IDLE)
                    .TransitionTo(State.OVER).After(TimeSpan.FromMilliseconds(10))
                    .State(State.OVER)
                    .TransitionTo(State.PRESSED).After(TimeSpan.FromMilliseconds(10))
                    .State(State.PRESSED)
                    .TransitionTo(State.REFRESHING).After(TimeSpan.FromMilliseconds(10))
                    .State(State.REFRESHING)
                    .TransitionTo(State.IDLE).After(TimeSpan.FromMilliseconds(10))
                    .Build();

            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Update(TimeSpan.FromMilliseconds(40));
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
        }
Ejemplo n.º 8
0
        public void WhenCallingPopOnStackMachineBuiltWithBuilderShouldBehaveCorrectly()
        {
            var m = Fsm <State, Trigger> .Builder(State.OPENED)
                    .EnableStack()
                    .State(State.OPENED)
                    .TransitionTo(State.OPENED).On(Trigger.OPEN)
                    .TransitionTo(State.CLOSED).On(Trigger.CLOSE)
                    .TransitionTo(State.POP).On(Trigger.PUSH_POP)
                    .State(State.CLOSED).ClearsStack()
                    .TransitionTo(State.CLOSED).On(Trigger.CLOSE)
                    .TransitionTo(State.OPENED).On(Trigger.OPEN)
                    .State(State.POP)
                    .PopTransition().On(Trigger.PUSH_POP)
                    .Build();

            AssertTestWithPop(m);
        }
Ejemplo n.º 9
0
        public void WhenAnAfterConditionDoesNotFiresAndATransitionHappensTheTimerIsResetOnReentry()
        {
            var m = Fsm <State, Trigger> .Builder(State.IDLE)
                    .State(State.IDLE)
                    .TransitionTo(State.OVER).After(TimeSpan.FromMilliseconds(10))
                    .TransitionTo(State.OVER).On(Trigger.MOUSE_CLICKED)
                    .State(State.OVER)
                    .TransitionTo(State.IDLE).On(Trigger.MOUSE_CLICKED)
                    .Build();

            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Update(TimeSpan.FromMilliseconds(5));
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_CLICKED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
            m.Trigger(Trigger.MOUSE_CLICKED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Update(TimeSpan.FromMilliseconds(5));
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
        }
 private Fsm <State, Trigger> CreateFiniteStateMachine()
 {
     return(Fsm <State, Trigger> .Builder(State.RESOLUTION_800_X600)
            .State(State.RESOLUTION_800_X600)
            .OnEnter(args => { SetResolution(800, 600, false); })
            .TransitionTo(State.RESOLUTION_800_X600_FULLSCREEN).On(Trigger.SPACE)
            .State(State.RESOLUTION_800_X600_FULLSCREEN)
            .OnEnter(args => { SetResolution(800, 600, true); })
            .TransitionTo(State.RESOLUTION_1024_X768).On(Trigger.SPACE).State(State.RESOLUTION_1024_X768).OnEnter(
                args => { SetResolution(1024, 768, false); })
            .TransitionTo(State.RESOLUTION_1024_X768_FULLSCREEN).On(Trigger.SPACE)
            .State(State.RESOLUTION_1024_X768_FULLSCREEN)
            .OnEnter(args => { SetResolution(1024, 768, true); })
            .TransitionTo(State.RESOLUTION_1280_X768).On(Trigger.SPACE).State(State.RESOLUTION_1280_X768).OnEnter(
                args => { SetResolution(1280, 768, false); })
            .TransitionTo(State.RESOLUTION_1280_X768_FULLSCREEN).On(Trigger.SPACE)
            .State(State.RESOLUTION_1280_X768_FULLSCREEN).OnEnter(args => { SetResolution(1280, 768, true); })
            .TransitionTo(State.RESOLUTION_1920_X1080).On(Trigger.SPACE).State(State.RESOLUTION_1920_X1080).OnEnter(
                args => { SetResolution(1920, 1080, false); })
            .TransitionTo(State.RESOLUTION_1920_X1080_FULLSCREEN).On(Trigger.SPACE)
            .State(State.RESOLUTION_1920_X1080_FULLSCREEN).OnEnter(args => { SetResolution(1920, 1080, true); })
            .Build());
 }
Ejemplo n.º 11
0
        public void HorizontalMachine()
        {
            horizontalMachine = Fsm <HState, HTrigger> .Builder(HState.STANDING)
                                .State(HState.STANDING)
                                .TransitionTo(HState.WALKING_LEFT)
                                .On(HTrigger.LEFT_PRESSED)
                                .TransitionTo(HState.WALKING_RIGHT)
                                .On(HTrigger.RIGHT_PRESSED)
                                .State(HState.WALKING_LEFT)
                                .TransitionTo(HState.WALKING_DELAY_LEFT)
                                .On(HTrigger.LEFT_RELEASED)
                                .State(HState.WALKING_RIGHT)
                                .TransitionTo(HState.WALKING_DELAY_RIGHT)
                                .On(HTrigger.RIGHT_RELEASED)
                                .State(HState.WALKING_DELAY_LEFT)
                                .TransitionTo(HState.WALKING_RIGHT)
                                .On(HTrigger.RIGHT_PRESSED)
                                .TransitionTo(HState.RUNNING_LEFT)
                                .On(HTrigger.LEFT_PRESSED)
                                .State(HState.WALKING_DELAY_RIGHT)
                                .TransitionTo(HState.WALKING_LEFT)
                                .On(HTrigger.LEFT_PRESSED)
                                .TransitionTo(HState.RUNNING_RIGHT)
                                .On(HTrigger.RIGHT_PRESSED)
                                .State(HState.RUNNING_LEFT)
                                .TransitionTo(HState.STANDING)
                                .On(HTrigger.LEFT_RELEASED)
                                .State(HState.RUNNING_RIGHT)
                                .TransitionTo(HState.STANDING)
                                .On(HTrigger.RIGHT_RELEASED)
                                .GlobalTransitionTo(HState.STANDING)
                                .OnGlobal(HTrigger.SPACE_PRESSED)
                                .Build();

            string s = horizontalMachine.GetPlantUml();
        }
Ejemplo n.º 12
0
        public void StateChangesGunRotation()
        {
            // Now for the weapons-machine with basic forward- and backward-rotation.
            var m = Fsm <WState, WTrigger> .Builder(WState.EMPTY_HANDED)
                    .State(WState.EMPTY_HANDED)
                    .TransitionTo(WState.GUN).On(WTrigger.TAB)
                    .TransitionTo(WState.LASER_RIFLE).On(WTrigger.SHIFT_TAB)
                    .State(WState.GUN)
                    .TransitionTo(WState.SHOTGUN).On(WTrigger.TAB)
                    .TransitionTo(WState.EMPTY_HANDED).On(WTrigger.SHIFT_TAB)
                    .State(WState.SHOTGUN)
                    .TransitionTo(WState.LASER_RIFLE).On(WTrigger.TAB)
                    .TransitionTo(WState.GUN).On(WTrigger.SHIFT_TAB)
                    .State(WState.LASER_RIFLE)
                    .TransitionTo(WState.EMPTY_HANDED).On(WTrigger.TAB)
                    .TransitionTo(WState.SHOTGUN).On(WTrigger.SHIFT_TAB)
                    .Build();

            Assert.That(m.Current.Identifier, Is.EqualTo(WState.EMPTY_HANDED));
            m.Trigger(WTrigger.TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.GUN));
            m.Trigger(WTrigger.TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.SHOTGUN));
            m.Trigger(WTrigger.TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.LASER_RIFLE));
            m.Trigger(WTrigger.TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.EMPTY_HANDED));
            m.Trigger(WTrigger.SHIFT_TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.LASER_RIFLE));
            m.Trigger(WTrigger.SHIFT_TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.SHOTGUN));
            m.Trigger(WTrigger.SHIFT_TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.GUN));
            m.Trigger(WTrigger.SHIFT_TAB);
            Assert.That(m.Current.Identifier, Is.EqualTo(WState.EMPTY_HANDED));
        }
Ejemplo n.º 13
0
        public void WhenStateChangesOnEnterAndOnExitHooksShouldTrigger()
        {
            var button = new Button();

            var m = Fsm <State, Trigger> .Builder(State.IDLE)
                    .State(State.IDLE)
                    .TransitionTo(State.OVER).On(Trigger.MOUSE_OVER)
                    .OnEnter(t => button.BtnState = State.IDLE)
                    .OnExit(t => button.OldState  = button.BtnState)
                    .State(State.OVER)
                    .TransitionTo(State.IDLE).On(Trigger.MOUSE_LEAVE)
                    .TransitionTo(State.PRESSED).On(Trigger.MOUSE_CLICKED)
                    .OnEnter(t => button.BtnState     = State.OVER)
                    .OnExit(t => button.OldState      = button.BtnState)
                    .Update(a => button.UpdateCounter = button.UpdateCounter + 1)
                    .State(State.PRESSED)
                    .TransitionTo(State.IDLE).On(Trigger.MOUSE_LEAVE)
                    .TransitionTo(State.REFRESHING).On(Trigger.MOUSE_RELEASED).If(a => button.IsActivated)
                    .OnEnter(t => button.BtnState = State.PRESSED)
                    .OnExit(t => button.OldState  = button.BtnState)
                    .State(State.REFRESHING)
                    .OnEnter(t => button.BtnState = State.REFRESHING)
                    .OnExit(t => button.OldState  = button.BtnState)
                    .Update(a =>
            {
                button.RefreshTimer -= (float)a.ElapsedTimeSpan.TotalMilliseconds;
                if (button.RefreshTimer <= 0F)
                {
                    button.RefreshTimer = 0F;
                    a.Machine.JumpTo(State.OVER);         // or m.JumpTo(State.IDLE);
                }
                button.UpdateCounter = button.UpdateCounter + 1;
            })
                    .Build();

            m.Update(TimeSpan.FromMilliseconds(2)); // Should do nothing.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_CLICKED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_LEAVE);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_RELEASED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_OVER);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
            Assert.That(button.BtnState, Is.EqualTo(State.OVER));
            Assert.That(button.OldState, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_CLICKED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.PRESSED));
            Assert.That(button.BtnState, Is.EqualTo(State.PRESSED));
            Assert.That(button.OldState, Is.EqualTo(State.OVER));
            m.Trigger(Trigger.MOUSE_RELEASED); // Button is deactivated.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.PRESSED));
            Assert.That(button.BtnState, Is.EqualTo(State.PRESSED));
            Assert.That(button.OldState, Is.EqualTo(State.OVER));
            button.IsActivated = true;
            m.Trigger(Trigger.MOUSE_RELEASED); // Now it's activated.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.REFRESHING));
            Assert.That(button.BtnState, Is.EqualTo(State.REFRESHING));
            Assert.That(button.OldState, Is.EqualTo(State.PRESSED));
            m.Update(TimeSpan.FromMilliseconds(1)); // No transition yet...
            Assert.That(m.Current.Identifier, Is.EqualTo(State.REFRESHING));
            Assert.That(button.BtnState, Is.EqualTo(State.REFRESHING));
            Assert.That(button.OldState, Is.EqualTo(State.PRESSED));
            m.Update(TimeSpan.FromMilliseconds(1)); // But now.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
            Assert.That(button.BtnState, Is.EqualTo(State.OVER));
            Assert.That(button.OldState, Is.EqualTo(State.REFRESHING));

            // Update was triggered twice over all states.
            Assert.That(button.UpdateCounter, Is.EqualTo(2));
        }
Ejemplo n.º 14
0
        public void WhenAfterConditionFiresOnEnterAndOnExitHooksShouldTrigger()
        {
            var button = new Button();

            var m = Fsm <State, Trigger> .Builder(State.IDLE)
                    .State(State.IDLE)
                    .TransitionTo(State.OVER).On(Trigger.MOUSE_OVER)
                    .OnEnter(t => button.BtnState = State.IDLE)
                    .OnExit(t => button.OldState  = button.BtnState)
                    .State(State.OVER)
                    .TransitionTo(State.IDLE).On(Trigger.MOUSE_LEAVE)
                    .TransitionTo(State.PRESSED).On(Trigger.MOUSE_CLICKED)
                    .OnEnter(t => button.BtnState     = State.OVER)
                    .OnExit(t => button.OldState      = button.BtnState)
                    .Update(a => button.UpdateCounter = button.UpdateCounter + 1)
                    .State(State.PRESSED)
                    .TransitionTo(State.IDLE).On(Trigger.MOUSE_LEAVE)
                    .TransitionTo(State.REFRESHING).On(Trigger.MOUSE_RELEASED).If(a => button.IsActivated)
                    .OnEnter(t => button.BtnState = State.PRESSED)
                    .OnExit(t => button.OldState  = button.BtnState)
                    .State(State.REFRESHING)
                    .OnEnter(t => button.BtnState = State.REFRESHING)
                    .OnExit(t => button.OldState  = button.BtnState)
                    .TransitionTo(State.OVER).After(TimeSpan.FromSeconds(1))
                    .GlobalTransitionTo(State.IDLE).AfterGlobal(TimeSpan.FromSeconds(10))
                    .Build();

            m.Update(TimeSpan.FromMilliseconds(16)); // Should do nothing.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_CLICKED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_LEAVE);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_RELEASED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_OVER);
            m.Update(TimeSpan.FromMilliseconds(16));
            m.Update(TimeSpan.FromMilliseconds(16));
            Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
            Assert.That(button.BtnState, Is.EqualTo(State.OVER));
            Assert.That(button.OldState, Is.EqualTo(State.IDLE));
            m.Trigger(Trigger.MOUSE_CLICKED);
            Assert.That(m.Current.Identifier, Is.EqualTo(State.PRESSED));
            Assert.That(button.BtnState, Is.EqualTo(State.PRESSED));
            Assert.That(button.OldState, Is.EqualTo(State.OVER));
            m.Trigger(Trigger.MOUSE_RELEASED); // Button is deactivated.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.PRESSED));
            Assert.That(button.BtnState, Is.EqualTo(State.PRESSED));
            Assert.That(button.OldState, Is.EqualTo(State.OVER));
            button.IsActivated = true;
            m.Trigger(Trigger.MOUSE_RELEASED); // Now it's activated.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.REFRESHING));
            Assert.That(button.BtnState, Is.EqualTo(State.REFRESHING));
            Assert.That(button.OldState, Is.EqualTo(State.PRESSED));
            m.Update(TimeSpan.FromMilliseconds(500)); // No transition yet...
            Assert.That(m.Current.Identifier, Is.EqualTo(State.REFRESHING));
            Assert.That(button.BtnState, Is.EqualTo(State.REFRESHING));
            Assert.That(button.OldState, Is.EqualTo(State.PRESSED));
            m.Update(TimeSpan.FromMilliseconds(600)); // But now.
            Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
            Assert.That(button.BtnState, Is.EqualTo(State.OVER));
            Assert.That(button.OldState, Is.EqualTo(State.REFRESHING));
            m.Update(TimeSpan.FromMilliseconds(10000));
            Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
            Assert.That(button.BtnState, Is.EqualTo(State.IDLE));
            Assert.That(button.OldState, Is.EqualTo(State.OVER));

            // Update was triggered twice over all states.
            Assert.That(button.UpdateCounter, Is.EqualTo(3F));
        }
Ejemplo n.º 15
0
        /// <summary>
        ///     LoadContent will be called once per game and is the place to load
        ///     all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            var texture = Content.Load <Texture2D>("spaceman");

            atlas = TextureAtlas.Create("hero-atlas", texture, 50, 50, 24, 1, 1);

            var factory = new SpriteSheetAnimationFactory(atlas);

            factory.Add("idle_left", new SpriteSheetAnimationData(new[] { 1 }));
            factory.Add("idle_right", new SpriteSheetAnimationData(new[] { 0 }));
            factory.Add("walk_left", new SpriteSheetAnimationData(new[] { 16, 17, 18, 19, 20, 21, 22, 23 }));
            factory.Add("walk_right", new SpriteSheetAnimationData(new[] { 8, 9, 10, 11, 12, 13, 14, 15 }));
            factory.Add("jump_left", new SpriteSheetAnimationData(new[] { 5, 7 }, isLooping: false));
            factory.Add("jump_right", new SpriteSheetAnimationData(new[] { 4, 6 }, isLooping: false));
            factory.Add("duck_left", new SpriteSheetAnimationData(new[] { 3 }));
            factory.Add("duck_right", new SpriteSheetAnimationData(new[] { 2 }));

            hero = new AnimatedSprite(factory);

            heroStateMachine = Fsm <string, Keys> .Builder("idle_left")
                               .State("idle_left")
                               .Update(args => hero.Play(args.State.Identifier))
                               .TransitionTo("walk_left").On(Keys.Left)
                               .TransitionTo("duck_left").On(Keys.Down)
                               .TransitionTo("jump_left").On(Keys.Up)
                               .TransitionTo("idle_right").On(Keys.Right)
                               .State("idle_right")
                               .Update(args => hero.Play(args.State.Identifier))
                               .TransitionTo("walk_right").On(Keys.Right)
                               .TransitionTo("duck_right").On(Keys.Down)
                               .TransitionTo("jump_right").On(Keys.Up)
                               .TransitionTo("idle_left").On(Keys.Left)
                               .State("walk_left")
                               .Update(args => {
                if (Keyboard.GetState().IsKeyDown(Keys.Left))
                {
                    hero.Play(args.State.Identifier);
                }
                else
                {
                    args.Machine.JumpTo("idle_left");
                }
            })
                               .TransitionTo("duck_left").On(Keys.Down)
                               .TransitionTo("jump_left").On(Keys.Up)
                               .TransitionTo("idle_right").On(Keys.Right)
                               .State("walk_right")
                               .Update(args => {
                if (Keyboard.GetState().IsKeyDown(Keys.Right))
                {
                    hero.Play(args.State.Identifier);
                }
                else
                {
                    args.Machine.JumpTo("idle_right");
                }
            })
                               .TransitionTo("duck_right").On(Keys.Down)
                               .TransitionTo("jump_right").On(Keys.Up)
                               .TransitionTo("idle_left").On(Keys.Left)
                               .State("jump_left")
                               .OnEnter(args => hero.Play(args.To.Identifier).OnCompleted = () => args.Fsm.JumpTo("idle_left"))
                               .State("jump_right")
                               .OnEnter(args => hero.Play(args.To.Identifier).OnCompleted = () => args.Fsm.JumpTo("idle_right"))
                               .State("duck_left")
                               .Update(args => {
                if (Keyboard.GetState().IsKeyDown(Keys.Down))
                {
                    hero.Play(args.State.Identifier);
                }
                else
                {
                    args.Machine.JumpTo("idle_left");
                }
            })
                               .TransitionTo("walk_right").On(Keys.Right)
                               .TransitionTo("walk_left").On(Keys.Left)
                               .TransitionTo("jump_left").On(Keys.Up)
                               .State("duck_right")
                               .Update(args => {
                if (Keyboard.GetState().IsKeyDown(Keys.Down))
                {
                    hero.Play(args.State.Identifier);
                }
                else
                {
                    args.Machine.JumpTo("idle_right");
                }
            })
                               .TransitionTo("walk_right").On(Keys.Right)
                               .TransitionTo("walk_left").On(Keys.Left)
                               .TransitionTo("jump_right").On(Keys.Up)
                               .Build();
        }