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; } }
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"); } } } }
private void AddLowerAnimation(PlayingAnimation anim) { AnimationComponent.PlayingAnimations.Insert(LowerAnimCount, anim); }
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); }