Example #1
0
        protected override void PrepareLoadedEntity()
        {
            lock (animLock)
                playingAnim = null;

            base.PrepareLoadedEntity();

            var animComponent = PreviewEntity.Entity.Get <AnimationComponent>();

            // Don't play, if the animation is invalid
            if (animComponent.Animations["preview"] != null)
            {
                animComponent.Play("preview");

                lock (animLock)
                {
                    playingAnim            = animComponent.PlayingAnimations.Last();
                    playingAnim.RepeatMode = AnimationRepeatMode.LoopInfinite;
                }
            }
        }
        public override void Update()
        {
            int drawX = 800, drawY = 600;

            StopOrResumeAnimations(drawX, drawY += 20);

            AdjustAnimationSpeed(drawX, drawY += 20);

            DebugText.Print("I to start playing Idle", new Int2(drawX, drawY += 20));
            if (Input.IsKeyPressed(Keys.I))
            {
                latestAnimation            = animation.Play("Idle");
                latestAnimation.TimeFactor = AnimationSpeed;
            }

            DebugText.Print("R to crossfade to Run", new Int2(drawX, drawY += 20));
            if (Input.IsKeyPressed(Keys.R))
            {
                latestAnimation            = animation.Crossfade("Run", TimeSpan.FromSeconds(0.5));
                latestAnimation.TimeFactor = AnimationSpeed;
            }

            // We can crossfade to a punch animation, but only if it is not already playing
            DebugText.Print("P to crossfade to Punch and play it once", new Int2(drawX, drawY += 20));
            if (Input.IsKeyPressed(Keys.P) && !animation.IsPlaying("Punch"))
            {
                latestAnimation            = animation.Crossfade("Punch", TimeSpan.FromSeconds(0.1));
                latestAnimation.RepeatMode = AnimationRepeatMode.PlayOnce;
                latestAnimation.TimeFactor = AnimationSpeed;
            }

            // When the punch animation is the latest animation, but it is no longer playing, we set a new animation
            if (latestAnimation.Name == "Punch" && !animation.IsPlaying("Punch"))
            {
                latestAnimation            = animation.Play("Idle");
                latestAnimation.RepeatMode = AnimationRepeatMode.LoopInfinite;
                latestAnimation.TimeFactor = AnimationSpeed;
            }
        }
Example #3
0
        public override async Task Execute()
        {
            spriteSheet          = BulletSheet;
            agentSpriteComponent = Entity.Get <SpriteComponent>();
            var animComponent = Entity.Get <AnimationComponent>();
            PlayingAnimation playingAnimation = null;

            // Calculate offset of the bullet from the Agent if he is facing left and right side // TODO improve this
            var bulletOffset = new Vector3(1.3f, 1.65f, 0f);

            // Initialize game entities
            if (!IsLiveReloading)
            {
                shootDelayCounter     = 0f;
                isAgentFacingRight    = true;
                currentAgentAnimation = AgentAnimation.Idle;
            }
            CurrentAgentAnimation = currentAgentAnimation;

            var normalScaleX = Entity.Transform.Scale.X;

            var bulletCS = BulletColliderShape;

            Task animTask = null;

            while (Game.IsRunning)
            {
                await Script.NextFrame();

                var inputState = GetKeyboardInputState();

                if (inputState == InputState.None)
                {
                    inputState = GetPointerInputState();
                }

                if (inputState == InputState.RunLeft || inputState == InputState.RunRight)
                {
                    // Update Agent's position
                    var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds;

                    Entity.Transform.Position.X += ((inputState == InputState.RunRight) ? AgentMoveDistance : -AgentMoveDistance) * dt;

                    if (Entity.Transform.Position.X < -gameWidthHalfX)
                    {
                        Entity.Transform.Position.X = -gameWidthHalfX;
                    }

                    if (Entity.Transform.Position.X > gameWidthHalfX)
                    {
                        Entity.Transform.Position.X = gameWidthHalfX;
                    }

                    isAgentFacingRight = inputState == InputState.RunRight;

                    // If agent face left, flip the sprite
                    Entity.Transform.Scale.X = isAgentFacingRight ? normalScaleX : -normalScaleX;

                    // Update the sprite animation and state
                    CurrentAgentAnimation = AgentAnimation.Run;
                    if (playingAnimation == null || playingAnimation.Name != "Run")
                    {
                        playingAnimation = animComponent.Play("Run");
                    }
                }
                else if (inputState == InputState.Shoot)
                {
                    if (animTask != null && !animTask.IsCompleted)
                    {
                        continue;
                    }
                    if (animTask != null && animTask.IsCompleted)
                    {
                        playingAnimation = null;
                    }

                    animTask = null;

                    var rb = new RigidbodyComponent {
                        CanCollideWith = CollisionFilterGroupFlags.CustomFilter1, CollisionGroup = CollisionFilterGroups.DefaultFilter
                    };
                    rb.ColliderShapes.Add(new ColliderShapeAssetDesc {
                        Shape = bulletCS
                    });

                    // Spawns a new bullet
                    var bullet = new Entity
                    {
                        new SpriteComponent {
                            SpriteProvider = SpriteFromSheet.Create(spriteSheet, "bullet")
                        },
                        rb,
                        new BeamScript()
                    };
                    bullet.Name = "bullet";

                    bullet.Transform.Position = (isAgentFacingRight) ? Entity.Transform.Position + bulletOffset : Entity.Transform.Position + (bulletOffset * new Vector3(-1, 1, 1));
                    bullet.Transform.UpdateWorldMatrix();

                    SceneSystem.SceneInstance.RootScene.Entities.Add(bullet);

                    rb.LinearFactor  = new Vector3(1, 0, 0);
                    rb.AngularFactor = new Vector3(0, 0, 0);
                    rb.ApplyImpulse(isAgentFacingRight ? new Vector3(25, 0, 0) : new Vector3(-25, 0, 0));

                    // Start animation for shooting
                    CurrentAgentAnimation = AgentAnimation.Shoot;
                    if (playingAnimation == null || playingAnimation.Name != "Attack")
                    {
                        playingAnimation = animComponent.Play("Attack");
                        animTask         = animComponent.Ended(playingAnimation);
                    }
                }
                else
                {
                    CurrentAgentAnimation = AgentAnimation.Idle;
                    if (playingAnimation == null || playingAnimation.Name != "Stance")
                    {
                        playingAnimation = animComponent.Play("Stance");
                    }
                }
            }
        }
Example #4
0
 private void AddLowerAnimation(PlayingAnimation anim)
 {
     AnimationComponent.PlayingAnimations.Insert(LowerAnimCount, anim);
 }
Example #5
0
        private void InitializeLowerStateMachine()
        {
            lowerStateMachine = new FiniteStateMachine("SoldierAnimationLower");

            Action <State, string, string> startIdleOrRun = (from, newAnimNameLow, newAnimNameAim) =>
            {
                // Select the proper animation to play
                lowerAnimation = NewAnimation(HasAdditiveAnimation ? newAnimNameAim : newAnimNameLow);
                if (from != null)
                {
                    // Blend in if needed
                    lowerAnimation.Weight                 = 0.0f;
                    lowerAnimation.WeightTarget           = 1.0f;
                    lowerAnimation.CrossfadeRemainingTime = TimeSpan.FromSeconds(0.2);
                }
                // Add the animation
                InsertLowerAnimation(0, lowerAnimation);
            };

            Action updateLowerIdleOrRun = () =>
            {
                // Swap between the low animation (used if no additive animation) and the aim animation (used only for additive animation)
                if (HasAdditiveAnimation)
                {
                    SwapLowerAnimation(AnimKeys.IdleLow, AnimKeys.IdleAim, false);
                    SwapLowerAnimation(AnimKeys.RunLow, AnimKeys.RunAim, false);
                }
                else
                {
                    SwapLowerAnimation(AnimKeys.IdleAim, AnimKeys.IdleLow, true);
                    SwapLowerAnimation(AnimKeys.RunAim, AnimKeys.RunLow, true);
                }
            };

            Action <State> exitLowerIdleOrRun = to =>
            {
                // Blend away the remaining animation
                lowerAnimation.WeightTarget           = 0.0f;
                lowerAnimation.CrossfadeRemainingTime = TimeSpan.FromSeconds(0.2);
            };

            Action <State> startLowerWalk = from =>
            {
                // Add all the animations used for walking, enable only Idle at start
                AddLowerAnimation(NewAnimation(AnimKeys.IdleAim));
                AddLowerAnimation(NewAnimation(AnimKeys.WalkForward, 0.0f));
                AddLowerAnimation(NewAnimation(AnimKeys.WalkBackward, 0.0f));
                AddLowerAnimation(NewAnimation(AnimKeys.WalkLeft, 0.0f));
                AddLowerAnimation(NewAnimation(AnimKeys.WalkRight, 0.0f));
            };

            Action updateLowerWalk = () =>
            {
                var    dot = Vector3.Dot(moveDirection, aimDirection);
                string lowerAnimToPlay;
                var    forwardThreshold  = Math.Cos(MathUtil.DegreesToRadians(WalkAngleThreshold.X));
                var    backwardThreshold = Math.Cos(MathUtil.DegreesToRadians(WalkAngleThreshold.Y));
                var    crossfadeFactor   = Game.UpdateTime.Elapsed.TotalSeconds / WalkCrossfadeDuration;
                // Find out which anim should be played
                if (moveDirection == Vector3.Zero)
                {
                    lowerAnimToPlay = AnimKeys.IdleAim;
                }
                else if (dot > forwardThreshold)
                {
                    lowerAnimToPlay = AnimKeys.WalkForward;
                }
                else if (dot < backwardThreshold)
                {
                    lowerAnimToPlay = AnimKeys.WalkBackward;
                }
                else
                {
                    var cross = Vector3.Cross(aimDirection, moveDirection);
                    lowerAnimToPlay = cross.Y <= 0 ? AnimKeys.WalkLeft : AnimKeys.WalkRight;
                }

                foreach (var anim in AnimationComponent.PlayingAnimations.Take(LowerAnimCount))
                {
                    if (anim.Name == lowerAnimToPlay)
                    {
                        anim.Weight = (float)Math.Min(anim.Weight + crossfadeFactor, 1.0f);
                    }
                    else
                    {
                        anim.Weight = (float)Math.Max(anim.Weight - crossfadeFactor, 0.0f);
                    }
                }
            };

            Action <State> exitWalk = to =>
            {
                PlayingAnimation crossfadeAnim = null;
                var maxWeight = float.MinValue;

                foreach (var anim in AnimationComponent.PlayingAnimations.Take(LowerAnimCount).ToList())
                {
                    if (anim.Weight > maxWeight)
                    {
                        crossfadeAnim = anim;
                        maxWeight     = anim.Weight;
                    }
                    // Remove all walking animation...
                    AnimationComponent.PlayingAnimations.Remove(anim);
                }
                // ... except the current one that will be blended away
                if (crossfadeAnim != null)
                {
                    InsertLowerAnimation(0, crossfadeAnim);
                    crossfadeAnim.WeightTarget           = 0.0f;
                    crossfadeAnim.CrossfadeRemainingTime = TimeSpan.FromSeconds(0.2);
                }
            };

            var idleState = new State(LowerIdleState)
            {
                EnterMethod  = State.ToTask(from => startIdleOrRun(from, AnimKeys.IdleLow, AnimKeys.IdleAim)),
                UpdateMethod = updateLowerIdleOrRun,
                ExitMethod   = State.ToTask(to => exitLowerIdleOrRun(to))
            };

            var runState = new State(LowerRunState)
            {
                EnterMethod  = State.ToTask(from => startIdleOrRun(from, AnimKeys.RunLow, AnimKeys.RunAim)),
                UpdateMethod = updateLowerIdleOrRun,
                ExitMethod   = State.ToTask(to => exitLowerIdleOrRun(to))
            };

            var walkState = new State(LowerWalkState)
            {
                EnterMethod  = State.ToTask(startLowerWalk),
                UpdateMethod = updateLowerWalk,
                ExitMethod   = State.ToTask(to => exitWalk(to))
            };

            lowerStateMachine.RegisterState(idleState);
            lowerStateMachine.RegisterState(runState);
            lowerStateMachine.RegisterState(walkState);
            lowerStateMachine.Start(Script, LowerIdleState);
        }