예제 #1
0
        public GameStateMachine(IGameActions game, IGameSettings settings, GameNotifications gameNotifications)
        {
            InstanceState(x => x.Status);

            DuringAny(
                When(Tick)
                .Then(context => context.Instance.LastTick = context.Data.Now));

            Initially(
                When(Tick)
                .Then(context => context.Instance.LastTick = context.Data.Now)
                .Then(context => game.MoveGhostsHome())
                .Then(context => game.ShowGhosts(context.Instance))
                .Then(context => gameNotifications.Publish(GameNotification.Beginning))
                .TransitionTo(Scatter));

            WhenEnter(Scatter,
                      binder => binder
                      .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(settings.InitialScatterTimeInSeconds))
                      .Then(context => game.ScatterGhosts()));

            During(Scatter,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .TransitionTo(GhostChase));

            WhenEnter(GhostChase,
                      binder => binder
                      .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(settings.ChaseTimeInSeconds))
                      .Then(context => game.GhostToChase()));

            During(GhostChase,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .TransitionTo(Scatter));

            During(Frightened,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(x => game.MakeGhostsNotEdible())
                   .TransitionTo(Scatter));

            During(Scatter, GhostChase, Frightened,
                   When(Tick)
                   .ThenAsync(async context => await game.MoveGhosts(context, this))
                   .Then(context => game.MovePacMan(context, this)),
                   When(CoinEaten)
                   .Then(context => context.Instance.Score += 10)
                   .Then(context => gameNotifications.Publish(GameNotification.EatCoin)),
                   When(PowerPillEaten)
                   .Then(context => context.Instance.Score += 50)
                   .Then(context => gameNotifications.Publish(GameNotification.EatPowerPill))
                   .Then(context => game.MakeGhostsEdible())
                   .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(7))
                   .TransitionTo(Frightened),
                   When(GhostCollision)
                   .IfElse(x => x.Data.Ghost.Edible,
                           binder => binder.Then(x => game.SendGhostHome(x.Data.Ghost)),
                           binder => binder.Then(context => context.Instance.Lives -= 1)
                           .TransitionTo(Dying)));

            WhenEnter(Dying,
                      binder => binder
                      .Then(context => context.Instance.TimeToChangeState = context.Instance.LastTick.AddSeconds(4))
                      .Then(context => gameNotifications.Publish(GameNotification.Dying)));

            During(Dying,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(context => game.HideGhosts(context.Instance))
                   .Then(context => context.Instance.TimeToChangeState = context.Data.Now.AddSeconds(4))
                   .IfElse(context => context.Instance.Lives > 0,
                           binder => binder.TransitionTo(Respawning),
                           binder => binder.TransitionTo(Dead)));

            WhenEnter(Respawning,
                      binder => binder
                      .Then(context => gameNotifications.Publish(GameNotification.Respawning)));

            During(Respawning,
                   When(Tick, context => context.Data.Now >= context.Instance.TimeToChangeState)
                   .Then(context => context.Instance.TimeToChangeState = context.Data.Now.AddSeconds(4))
                   .Then(context => game.MoveGhostsHome())
                   .Then(context => game.MovePacManHome())
                   .Then(context => game.ShowGhosts(context.Instance))
                   .TransitionTo(GhostChase));

            During(Dead, Ignore(Tick));
        }