private void LightningUpdateBehavior(ref Vector2 explosionPosition) { completeMobileList = LevelScene.DamageableMobiles.ToList(); //While it is still inside the map while (Topography.IsInsideMapBoundaries(Position) && Position.Y >= Topography.FirstCollidableBlockY) { //Check if there is any mobile whithin the extraExplosionRadius to receive the electrical extra dmaage CheckAffectedMobiles(); //If it collides with the ground or with another mobile, reset all previous affected mobiles and save the new explosion position if (Topography.CheckCollision(Position) || LevelScene.MobileList.Any((m) => m.CollisionBox.CheckCollision(Position))) { mobileList.Clear(); explosionPosition = Position; } Position += positionOffset; } }
private void ThorUpdateBehavior(ref Vector2 explosionPosition) { completeMobileList = LevelScene.MobileList.ToList(); //While it is still inside the map while ( Topography.IsInsideMapBoundaries(Position) && Position.Y >= Topography.FirstCollidableBlockY && Helper.SquaredEuclideanDistance(finalPosition, Position) > Parameter.ProjectileThorBeamDistanceThreshold) { //Check if there is any mobile whithin the extraExplosionRadius to receive the electrical extra dmaage CheckAffectedMobiles(); //If it collides with the ground or with another mobile, reset all previous affected mobiles and save the new explosion position if (Topography.CheckCollision(Position) || LevelScene.MobileList.Any((m) => m.CollisionBox.CheckCollision(Position))) { mobileList.Clear(); explosionPosition = Position; } Position += positionOffset; } }
public void ApplyGravity() { if (Topography.IsNotInsideMapYBoundaries(Mobile.Position - new Vector2(0, Mobile.MobileFlipbook.SpriteHeight))) { if (Mobile.IsAlive) { Mobile.RequestDeath(CausaMortis.Bungee); } return; } int[] relPos = Topography.GetRelativePosition(Mobile.Position); //Compute the where is the next collidable block bellow the pawn int yPosition = 0; for (; yPosition < Math.Max(Parameter.TankMovementMinYStepping, GravitySpeed); yPosition++) { if (relPos[1] + yPosition >= Topography.CollidableForegroundMatrix.Length) { continue; } if (relPos[0] > 0 && relPos[0] < Topography.MapHeight && Topography.CollidableForegroundMatrix[relPos[1] + yPosition][relPos[0]]) { break; } } //If the unit isn't on the ground if (yPosition > 0) { //Update gravity values on the pawn if (IsFalling) { gravityDelayTimer += Parameter.ProjectileMovementFixedElapedTime; if (gravityDelayTimer > Parameter.TankMovementGravityDelay) { //Wind-changing accumulated offset Vector2 wForce = (LevelScene.MatchMetadata != null) ? LevelScene.MatchMetadata.WindForceComponents().ToVector2() : Vector2.Zero; windForceAccumulator = MathHelper.Clamp(windForceAccumulator + wForce.X / 45, -1, 1); //Add interpolated movement Vector2 newPosition = Mobile.Position + new Vector2((int)windForceAccumulator, Math.Min((int)GravitySpeed, yPosition)); //In case the mobile collides in walls the X axis stop updating in order to prevent wall clipping if (Topography.IsInsideMapBoundaries(newPosition) && !Topography.CheckCollision(newPosition)) { windForceAccumulator = 0; } Mobile.Position += new Vector2((int)windForceAccumulator, Math.Min((int)GravitySpeed, yPosition)); GravitySpeed += Parameter.TankMovementGravityFactor; //Reseting the accumulator if (Math.Abs(windForceAccumulator) >= 1) { windForceAccumulator = 0; } } } else { gravityDelayTimer = 0; GravitySpeed = Parameter.TankMovementInitialGravity; } //Reset the rotation BufferRotationInDegrees = 0; //Set the state to falling if (!IsFalling) { Mobile.ForceSynchronize = true; IsFalling = true; } IsMoving = false; //desiredPosition.Y = Mobile.Position.Y; Mobile.ChangeFlipbookState(ActorFlipbookState.Falling, true); } else { //Set the the falling state to false if (IsFalling == true) { IsFalling = false; windForceAccumulator = 0; Mobile.ChangeFlipbookState(ActorFlipbookState.Stand, true); } } }
/// <summary> /// Instances all Flipbooks in position and set it's animations /// </summary> public virtual void Initialize(string texturePath, Vector2 startingPosition, WeatherAnimationType animationType, int extraSpawns = 0, float layerDepth = DepthParameter.WeatherEffect) { Vector2 endingPosition = new Vector2(Topography.MapWidth, Topography.MapHeight) / 2; //Creates the initial offset and 'subtracts' the pivot influence of the element. Vector2 currentOffset = startingPosition + Vector2.Transform(new Vector2(0, flipbookPivot.Y), Matrix.CreateRotationZ(rotation)) * Scale; int startingFrame = 0; Vector2 temporaryOffset = Vector2.Zero; do { currentOffset += temporaryOffset; //FixedAnimationsFrames is used on random //VariableAnimationFrame is used on tornado, weakness and force AnimationInstance animation = new AnimationInstance() { TimePerFrame = 1 / 15f }; switch (animationType) { case WeatherAnimationType.FixedAnimationFrame: animation.StartingFrame = animation.EndingFrame = startingFrame % numberOfFrames; break; case WeatherAnimationType.VariableAnimationFrame: animation.EndingFrame = numberOfFrames - 1; break; } startingFrame++; Flipbook fb = new Flipbook(currentOffset, flipbookPivot, (int)flipbookPivot.X * 2, (int)flipbookPivot.Y * 2, texturePath, animation, DepthParameter.WeatherEffect, rotation); fb.Scale *= Scale; flipbookList.Add(fb); fb.SetCurrentFrame(startingFrame % numberOfFrames); if (temporaryOffset == Vector2.Zero) { temporaryOffset = Vector2.Transform(new Vector2(0, fb.SpriteHeight), Matrix.CreateRotationZ(rotation)) * Scale; } //While it is inside the map boundaries and extraSpawns is not 0 } while (Topography.IsInsideMapBoundaries(currentOffset) || extraSpawns-- > 0); //If the rotation isn't 0 it means there are no good reasons for collision boxes if (rotation == 0) { collisionRectangle = new Rectangle((int)(startingPosition.X - collisionRectangleOffset.X * Scale), (int)startingPosition.Y, (int)(collisionRectangleOffset.X * 2 * Scale), (int)(endingPosition.Y - startingPosition.Y)); outerCollisionRectangle = new Rectangle(collisionRectangle.X - (int)outerCollisionRectangleOffset.X, collisionRectangle.Y - (int)outerCollisionRectangleOffset.Y, collisionRectangle.Width + (int)outerCollisionRectangleOffset.X * 2, collisionRectangle.Height + 10 * 2); #if DEBUG debugRectangle = new DebugRectangle(Color.Blue); debugRectangle.Update(collisionRectangle); DebugHandler.Instance.Add(debugRectangle); outerDebugRectangle = new DebugRectangle(Color.Red); outerDebugRectangle.Update(outerCollisionRectangle); DebugHandler.Instance.Add(outerDebugRectangle); #endif } }