Esempio n. 1
0
        static void Main(string[] args)
        {
            Console.WriteLine("状态模式:");

            Context context = new Context(new StateA());

            context.Request();
            context.Request();
            context.Request();
            context.Request();

            #region 角色系统
            //Role role = new Role(new Primary(), 0.0f);
            //role.IsVictory = true;
            //role.Play();
            //role.IsVictory = true;
            //role.Play();
            //role.IsVictory = true;
            //role.Play();
            //role.IsVictory = true;
            //role.Play();
            //role.IsVictory = true;
            //role.Play();
            //role.IsVictory = true;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            //role.IsVictory = false;
            //role.Play();
            #endregion

            #region  输门
            //TransmissionGate transGate = new TransmissionGate(new Closed());
            //transGate.Complete();
            //transGate.Click();
            //transGate.TimeOut();
            //transGate.Click();
            //transGate.Complete();
            //transGate.TimeOut();
            //transGate.Click();
            //transGate.Complete();
            //transGate.TimeOut();
            //transGate.Click();
            //transGate.Complete();
            //transGate.Click();
            //transGate.Click();
            //transGate.Complete();
            #endregion

            Idle   idle   = new Idle();
            Walk   walk   = new Walk();
            Jump   jump   = new Jump();
            Attack attack = new Attack();

            idle.AddTransition(new JyTransition(idle, walk, 'w'));
            idle.AddTransition(new JyTransition(idle, jump, 'j'));
            idle.AddTransition(new JyTransition(idle, attack, 'k'));

            walk.AddTransition(new JyTransition(walk, idle, 's'));
            walk.AddTransition(new JyTransition(walk, jump, 'j'));
            walk.AddTransition(new JyTransition(walk, attack, 'k'));

            jump.AddTransition(new JyTransition(jump, idle, 's'));
            jump.AddTransition(new JyTransition(jump, walk, 'w'));
            jump.AddTransition(new JyTransition(jump, attack, 'k'));

            attack.AddTransition(new JyTransition(attack, idle, 's'));
            attack.AddTransition(new JyTransition(attack, walk, 'w'));
            attack.AddTransition(new JyTransition(attack, jump, 'j'));

            HeroStateMachine heroStateMachine = new HeroStateMachine(idle);
            heroStateMachine.AddState(walk);
            heroStateMachine.AddState(jump);
            heroStateMachine.AddState(attack);

            ConsoleKeyInfo ConsoleKeyInfo = new ConsoleKeyInfo();
            while (ConsoleKeyInfo.Key != ConsoleKey.Escape)
            {
                ConsoleKeyInfo = Console.ReadKey();
                Console.WriteLine(ConsoleKeyInfo.Key.ToString());
                heroStateMachine.Word = ConsoleKeyInfo.KeyChar;
                heroStateMachine.OnStay();
            }
        }
        public StateController <CharacterState, CharacterContext> BuildCharacterControllerImpl(StateControllerBuilder <CharacterState, CharacterContext> builder)
        {
            Builder = builder;
            InjectState(this);

            // Declare Smash Attacks
            SmashUp.Charge.Data.SmashAttack   = SmashAttack.Charge;
            SmashSide.Charge.Data.SmashAttack = SmashAttack.Charge;
            SmashDown.Charge.Data.SmashAttack = SmashAttack.Charge;

            SmashUp.Attack.Data.SmashAttack   = SmashAttack.Attack;
            SmashSide.Attack.Data.SmashAttack = SmashAttack.Attack;
            SmashDown.Attack.Data.SmashAttack = SmashAttack.Attack;

            // Ground Attacks
            new [] { Idle, Walk, CrouchStart, Crouch, CrouchEnd }
            // Smash Attacks
            .AddTransitions <CharacterState, CharacterContext>(context => {
                var input = context.Input;
                if (!input.Attack.WasPressed)
                {
                    return(null);
                }
                switch (input.Smash.Direction)
                {
                case Direction.Right:
                case Direction.Left:
                    return(SmashSide.Charge);

                case Direction.Up:
                    return(SmashUp.Charge);

                case Direction.Down:
                    return(SmashDown.Charge);
                }
                return(null);
            })
            // Tilt Attacks
            .AddTransitions <CharacterState, CharacterContext>(context => {
                var input = context.Input;
                if (!input.Attack.WasPressed)
                {
                    return(null);
                }
                switch (input.Movement.Direction)
                {
                case Direction.Right:
                case Direction.Left:
                    return(TiltSide);

                case Direction.Up:
                    return(TiltUp);

                case Direction.Down:
                    return(TiltDown);
                }
                return(Neutral);
            });
            SmashUp.Charge.AddTransitionTo(SmashUp.Attack);
            SmashDown.Charge.AddTransitionTo(SmashDown.Attack);
            SmashSide.Charge.AddTransitionTo(SmashSide.Attack);
            TiltDown.AddTransitionTo(Crouch, Input(i => i.Movement.Direction == Direction.Down));
            new[] { Neutral, TiltUp, TiltDown, TiltSide, SmashUp.Attack, SmashDown.Attack, SmashSide.Attack }
            .AddTransitionTo(Idle);

            new [] { Fall, Jump, JumpAerial }
            .AddTransitions(Land, ctx => ctx.IsGrounded)
            // Aerial Attacks
            .AddTransitions <CharacterState, CharacterContext>(context => {
                var input = context.Input;
                if (!input.Attack.WasPressed)
                {
                    return(null);
                }
                switch (input.Movement.Direction)
                {
                case Direction.Right:
                    return(context.Direction >= 0f ? AerialForward : AerialBackward);

                case Direction.Left:
                    return(context.Direction >= 0f ? AerialBackward : AerialForward);

                case Direction.Up:
                    return(AerialUp);

                case Direction.Down:
                    return(AerialDown);
                }
                return(AerialNeutral);
            });
            new[] { AerialForward, AerialBackward, AerialDown, AerialUp, AerialNeutral }
            .AddTransitions(AerialAttackLand, ctx => ctx.IsGrounded)
            .AddTransitionTo(Fall);
            AerialAttackLand.AddTransitionTo(Idle);

            // Aerial Movement
            new [] { Idle, Walk, Dash, Run, RunTurn, RunBrake, CrouchStart, Crouch, CrouchEnd, Shield.Main }
            .AddTransitions(JumpStart, ctx => ctx.Input.Jump.WasPressed && ctx.CanJump);
            new[] { JumpStart, JumpAerial }.AddTransitionTo(Jump);
            new[] { Jump, Fall }.AddTransitions(JumpAerial, ctx => ctx.Input.Jump.WasPressed && ctx.CanJump)
            .AddTransitions(EscapeAir, Input(i => i.Shield.WasPressed));
            Jump.AddTransition(Idle, ctx => ctx.NormalizedStateTime >= 1.0f && ctx.IsGrounded)
            .AddTransition(Fall, ctx => ctx.NormalizedStateTime >= 1.0f && !ctx.IsGrounded);
            EscapeAir.AddTransitionTo(FallHelpless);
            new[] { Fall, FallHelpless, EscapeAir }.AddTransitions(Land, ctx => ctx.IsGrounded);
            Land.AddTransitionTo(Idle);

            Func <Func <PlayerInputContext, DirectionalInput>, Func <CharacterContext, bool> >
            movementContext = func => {
                return(ctx => !DirectionInput(Direction.Down)(ctx) &&
                       Input(i => Mathf.Abs(func(i).Value.x) > DirectionalInput.DeadZone)(ctx));
            };

            // Running States
            Idle.AddTransition(Dash, movementContext(i => i.Smash));
            Dash.AddTransitionTo(Idle, DirectionInput(Direction.Neutral));
            new[] { Dash, RunTurn }.AddTransitionTo(Run);
            Run.AddTransition(RunBrake, DirectionInput(Direction.Neutral));
            Run.AddTransition(RunTurn,
                              ctx => !Mathf.Approximately(Mathf.Sign(ctx.Input.Movement.Value.x), Mathf.Sign(ctx.Direction)));
            RunBrake.AddTransitionTo(Idle);

            // Ground Movement
            new[] { Idle, Walk, Run }
            .AddTransitions(CrouchStart, DirectionInput(Direction.Down))
            .AddTransitions(Fall, ctx => !ctx.IsGrounded);

            Idle.AddTransition(Walk, movementContext(i => i.Movement));
            Walk.AddTransition(Idle, DirectionInput(Direction.Neutral));

            // Crouching States
            CrouchStart.AddTransitionTo(Crouch);
            CrouchEnd.AddTransitionTo(Idle);
            new[] { CrouchStart, Crouch, CrouchEnd }.AddTransitions(Fall, ctx => !ctx.IsGrounded);
            Crouch.AddTransition(CrouchEnd, Input(i => i.Movement.Direction != Direction.Down));

            // Ledge States
            new[] { Idle, Fall, FallHelpless }.AddTransitions(LedgeGrab, ctx => ctx.State.IsGrabbingLedge);
            LedgeGrab.AddTransitionTo(LedgeIdle);
            LedgeIdle.AddTransition(LedgeRelease, ctx => !ctx.State.IsGrabbingLedge)
            .AddTransition(LedgeClimb, DirectionInput(Direction.Up))
            .AddTransition(LedgeJump, ctx => ctx.Input.Jump.WasPressed && ctx.CanJump)
            .AddTransition(LedgeAttack, Attack());
            LedgeJump.AddTransitionTo(Jump);
            new[] { LedgeRelease, LedgeClimb, LedgeEscape, LedgeAttack }
            .AddTransitions(Idle, ctx => ctx.NormalizedStateTime >= 1.0f && ctx.IsGrounded)
            .AddTransitions(Fall, ctx => ctx.NormalizedStateTime >= 1.0f && !ctx.IsGrounded);

            // Shielding
            Idle.AddTransition(Shield.On, Input(i => i.Shield.Current));
            Shield.On.AddTransition(Shield.Perfect, ctx => ctx.State.IsHit)
            .AddTransitionTo(Shield.Main);
            Shield.Main.AddTransition(Shield.Broken, ctx => ctx.State.ShieldDamage <= 0)
            .AddTransition(Shield.Off, Input(i => !i.Shield.Current));
            Shield.Off.AddTransitionTo(Idle);
            new[] { Shield.Broken, Shield.Stunned, Idle }.Chain();

            // Rolls/Sidesteps
            Shield.Main
            .AddTransition(EscapeForward, ctx => {
                if (ctx.Direction > 0f)
                {
                    return(DirectionalSmash(Direction.Right)(ctx));
                }
                else
                {
                    return(DirectionalSmash(Direction.Left)(ctx));
                }
            })
            .AddTransition(EscapeBackward, ctx => {
                if (ctx.Direction > 0f)
                {
                    return(DirectionalSmash(Direction.Left)(ctx));
                }
                else
                {
                    return(DirectionalSmash(Direction.Right)(ctx));
                }
            })
            .AddTransition(Escape, DirectionInput(Direction.Down));
            new[] { Escape, EscapeForward, EscapeBackward }.AddTransitionTo(Shield.Main);

            Builder.WithDefaultState(Idle);
            BuildCharacterController();
            return(Builder.Build());
        }