/// <summary> /// Reduces Health of the Enemy, makes him rotate to the Player and registers his Position /// </summary> /// <param name="Damage">Damage that the Enemy takes</param> /// <param name="Direction">Direction of the impacted Projectile</param> public void ReduceHealth(uint Damage, Vector2f Direction) { iHealth -= (int)Damage; vRegisteredPlayerPosition = MainMap.GetVirtualCharacterPosition(); RotateEnemy(ref fAngle, Direction + MainMap.GetStartCharacterPosition() + new Vector2f(25, 25)); sEntity.Rotation = fAngle; }
/// <summary> /// Detects Collision between Player and Invisible Projectile, returns true if Collision occures /// </summary> /// <param name="iProjectile">Projectile that Collision is checked with</param> protected bool PlayerProjectileCollision(InvisibleProjectile iProjectile) { Vector2f vPlayerPosition = MainMap.GetStartCharacterPosition(); Vector2f b = MainMap.GetStartCharacterPosition() + new Vector2f(25, 25) - sEntity.Position; if (vPlayerPosition.Y < iProjectile.vEntityPosition.Y && vPlayerPosition.Y + 50 > iProjectile.vEntityPosition.Y && vPlayerPosition.X < iProjectile.vEntityPosition.X && vPlayerPosition.X + 50 > iProjectile.vEntityPosition.X) { return(true); } return(false); }
/// <summary> /// Reduces Health and Restarts Regenerate Timer of the Player if hit by EnemyProjectile /// </summary> /// <param name="iProjectile">Projectile that Collision with Player is checked</param> /// <param name="Damage">Damage inflicted to the Player if hit</param> /// <returns></returns> protected bool PlayerProjectileCollision(EnemyProjectile iProjectile, uint Damage) { Vector2f b = MainMap.GetStartCharacterPosition() + new Vector2f(25, 25); if (Utilities.DistanceBetweenVectors(iProjectile.vEntityPosition, b) <= 25) { Player.ReduceHealth(Damage); Player.RestartRegenerateTimer(); return(true); } return(false); }
// DECLARING METHODS: DETECTION /// <summary> /// Updates Detect Logic of the Archer. /// If it detects the Player, the Archer shoots Projectiles. /// If it is hit or has detected the Player previously it moves to the registered Position. /// </summary> protected void DetectLogic() { if (DetectPlayer()) { vRegisteredPlayerPosition = MainMap.GetVirtualCharacterPosition() + new Vector2f(25, 25); RotateEnemy(ref fAngle, MainMap.GetStartCharacterPosition() + new Vector2f(25, 25)); sEntity.Rotation = fAngle; cSuspecting.Restart(); Closed = new List <Node>(); Path = new List <Node>(); Move(); Alert(); if (tShooting.AsMilliseconds() >= 1200) { Shoot(); cShooting.Restart(); } if (bSuspecting) { bSuspecting = false; } } else if (Utilities.MakePositive(vRegisteredPlayerPosition.X) > 0) { if (!bSuspecting) { cSuspecting.Restart(); bSuspecting = true; PathFinder(vEntityPosition, vRegisteredPlayerPosition); } tSuspecting = cSuspecting.ElapsedTime; if (tSuspecting.AsMilliseconds() <= 100000) { PathfinderLogic(); } else { vRegisteredPlayerPosition = new Vector2f(); } } }
/// <summary> /// Constructor /// </summary> /// <param name="iAngle">Angle to be rotated to</param> /// <param name="vDirection">Direction of the Projectile</param> /// <param name="iVelocity">Velocity of the Projectile</param> public PlayerProjectile(float iAngle, Vector2f vDirection, float iVelocity) { // SYNCHRONISING WITH CONTENT LOADER tEntity = new Texture(ContentLoader.textureProjectileVector); // SINCHRONYSING VARIABLES this.vEntityPosition = MainMap.GetStartCharacterPosition() + new Vector2f(25, 25); StartPosition = vEntityPosition; this.iAngle = iAngle; this.iVelocity = iVelocity; // INSTANTITATING OBJECTS sEntity = new Sprite(tEntity); // SETTING PROJECTILE PARAMETERS sEntity.Rotation = iAngle; sEntity.Origin = new Vector2f(tEntity.Size.X / 2, tEntity.Size.Y / 2); // SETTING PLAYERMOVEMENT vPlayerMovement = new Vector2f(0, 0); if (Input.bMovingLeft) { vPlayerMovement.X += Input.fPlayerVelocity; } if (Input.bMovingRight) { vPlayerMovement.X -= Input.fPlayerVelocity; } if (Input.bMovingUp) { vPlayerMovement.Y += Input.fPlayerVelocity; } if (Input.bMovingDown) { vPlayerMovement.Y -= Input.fPlayerVelocity; } // CALCULATING DISTANCE FROM CHARACTERPOSITION TO MOUSE iDistance = Utilities.DistanceToVectorFromOrigin((Vector2f)vDirection); base.vDirection = vDirection / iDistance; }
// DECLARING METHODS: DEVELOPING STATE RELATED /// <summary> /// Shows all the used Vectors of the Enemy, including Sight Radius, Angle and Invisible Projectiles /// </summary> protected void ShowVectors() { CircleShape cEnemyDirection; CircleShape cCharacterPosition; CircleShape cEnemyPosition; CircleShape cEnemyRadius; RectangleShape rEnemyAngle1; RectangleShape rEnemyAngle2; Vector2f circlePosition; circlePosition.X = sEntity.Position.X - iDistanceDetection; circlePosition.Y = sEntity.Position.Y - iDistanceDetection; cEnemyDirection = new CircleShape(0.5f); cCharacterPosition = new CircleShape(0.5f); cEnemyPosition = new CircleShape(0.5f); cEnemyDirection.OutlineThickness = 1; cCharacterPosition.OutlineThickness = 1; cEnemyPosition.OutlineThickness = 1; cEnemyRadius = new CircleShape(iDistanceDetection); rEnemyAngle1 = new RectangleShape(new Vector2f(iDistanceDetection - 7, 1)); rEnemyAngle2 = new RectangleShape(new Vector2f(iDistanceDetection - 7, 1)); cEnemyDirection.Position = vEnemyDirection; cCharacterPosition.Position = MainMap.GetStartCharacterPosition() + new Vector2f(25, 25); cEnemyPosition.Position = vEnemyAngleOrigin; cEnemyRadius.Position = circlePosition; rEnemyAngle1.Position = vEnemyAngleOrigin; rEnemyAngle2.Position = vEnemyAngleOrigin; cEnemyDirection.FillColor = Color.Cyan; cCharacterPosition.FillColor = Color.Black; cEnemyPosition.FillColor = Color.Cyan; cEnemyRadius.FillColor = Color.Transparent; rEnemyAngle1.FillColor = Color.Cyan; rEnemyAngle2.FillColor = Color.Cyan; cEnemyDirection.OutlineColor = Color.Cyan; cCharacterPosition.OutlineColor = Color.Black; cEnemyPosition.OutlineColor = Color.Cyan; cEnemyRadius.OutlineColor = Color.Cyan; cEnemyRadius.OutlineThickness = 1; rEnemyAngle1.Rotation = 90 - fMaxPermittedAngle + fAngle; rEnemyAngle2.Rotation = 90 + fMaxPermittedAngle + fAngle; lDrawList.Add(cEnemyRadius); lDrawList.Add(rEnemyAngle1); lDrawList.Add(rEnemyAngle2); lDrawList.Add(cEnemyDirection); lDrawList.Add(cCharacterPosition); lDrawList.Add(cEnemyPosition); CustomList.AddProjectiles(lDrawList, lInvisibleProjectileLeft); CustomList.AddProjectiles(lDrawList, lInvisibleProjectileMiddle); CustomList.AddProjectiles(lDrawList, lInvisibleProjectileRight); if (Path.Count > 1) { CircleShape cShape; cShape = new CircleShape(5); cShape.FillColor = Color.White; cShape.Position = Path[Path.Count - 1].vPosition + MainMap.GetTileMapPosition() + new Vector2f(25, 25) - new Vector2f(cShape.Radius, cShape.Radius); lDrawList.Add(cShape); } }
// DECLARING METHODS: PLAYER-DETECTION RELATED /// <summary> /// Returns true if the Player is in the Radius and Angle of Sight of the Enemy and isn't hidden behind a Tile with Collision /// </summary> protected bool DetectPlayer() { DisposingInvisibleListLeft = false; DisposingInvisibleListMiddle = false; DisposingInvisibleListRight = false; // UPDATING vEnemyDirection vEnemyDirection = sEntity.Position + new Vector2f(0, 25); // Creating distance to Origin vEnemyDirection = Utilities.VectorRotation(fAngle / 57, vEnemyDirection, sEntity.Position); // Rotating to PlayerPosition // UPDATING vEnemyAngleOrigin vEnemyAngleOrigin = (vEnemyDirection - sEntity.Position) * 0.80f + sEntity.Position; // Calculating based on EnemyDirection1 // UPDATING vEnemyBottomRightPosition and vEnemyBottomLeftPosition vEnemyBottomRightPosition = Utilities.VectorRotation(fAngle / fNumberToCorrect, sEntity.Position + new Vector2f(25, 25), sEntity.Position); // Rotating to PlayerPosition vEnemyBottomLeftPosition = Utilities.VectorRotation(fAngle / fNumberToCorrect, sEntity.Position + new Vector2f(-25, 25), sEntity.Position); // Rotating to PlayerPosition // CALCULATING AngleEnemy fAngleEnemy = Utilities.AngleBetweenVectors180(vEnemyDirection - vEnemyAngleOrigin, new Vector2f(925, 525) - vEnemyAngleOrigin); if (fAngleEnemy.Equals(0 / Zero)) { fAngleEnemy = 0; } // CALCULATING MaxPermittedAngle fMaxPermittedAngle = Utilities.AngleBetweenVectors180(vEnemyDirection - vEnemyAngleOrigin, vEnemyBottomRightPosition - vEnemyAngleOrigin); tDetecting = cDetecting.ElapsedTime; if (fAngleEnemy == 0) { fAngleEnemy = 0.0001f; } if (Utilities.MakePositive(Utilities.DistanceBetweenVectors(MainMap.GetVirtualCharacterPosition(), vEntityPosition)) < iDistanceDetection && fAngleEnemy < fMaxPermittedAngle) { fAnglecopy = fAngle; RotateEnemy(ref fAnglecopy, MainMap.GetStartCharacterPosition() + new Vector2f(25, 25)); ShootInvisible(MainMap.GetTileMapPosition(), fAnglecopy); if (DisposeInvisibleProjectile(lInvisibleProjectileLeft)) { DisposingInvisibleListLeft = true; } //if (DisposeInvisibleProjectile(lInvisibleProjectileMiddle)) // DisposingInvisibleListMiddle = true; if (DisposeInvisibleProjectile(lInvisibleProjectileRight)) { DisposingInvisibleListRight = true; } if (DisposingInvisibleListLeft || DisposingInvisibleListMiddle || DisposingInvisibleListRight) { cDetecting.Restart(); tDetecting = cDetecting.ElapsedTime; bAlert = true; return(true); } if (tDetecting.AsMilliseconds() <= 500) { return(true); } } bAlert = false; return(false); }
// DECLARING METHODS: MOVEMENT /// <summary> /// Moves Archer Randomly, but always to a Position within the DetectionRadius and respecting Collision with Tiles. The Archer doesn't psush the Player around. /// </summary> protected override void Move() { bCollisionUp = false; bCollisionDown = false; bCollisionRight = false; bCollisionLeft = false; bool nearright = false; bool nearleft = false; bool nearup = false; bool neardown = false; bool bRepeat = false; int iRepeating = 0; Vector2f vCharacterPositionEnemyOrigin = MainMap.GetStartCharacterPosition() + new Vector2f(25, 25) - sEntity.Position; CollisionDetection(ref vEntityPosition, ref bCollisionUp, ref bCollisionDown, ref bCollisionRight, ref bCollisionLeft, tEntity.Size.X, tEntity.Size.Y); EnemyEnemyCollision(ref vEntityPosition, ref bCollisionUp, ref bCollisionDown, ref bCollisionRight, ref bCollisionLeft); tMoving = cMoving.ElapsedTime; if (tMoving.AsMilliseconds() > 500) { iRandomNumber = rRandom.Next(0, 4); cMoving.Restart(); } // Enemy does not Push the Player around if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X + fSpeed) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y) < 50) { bCollisionLeft = true; } if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X - fSpeed) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y) < 50) { bCollisionRight = true; } if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y + fSpeed) < 50) { bCollisionUp = true; } if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y - fSpeed) < 50) { bCollisionDown = true; } float CharacterPosEnemyOriginX = MainMap.GetVirtualCharacterPosition().X - vEntityPosition.X; float CharacterPosEnemyOriginY = MainMap.GetVirtualCharacterPosition().Y - vEntityPosition.Y; // Enemy does not accidently hide behind Tiles with Collision if (CharacterPosEnemyOriginX > 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight || CharacterPosEnemyOriginX < 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight) { bCollisionDown = true; } else if (CharacterPosEnemyOriginX > 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight || CharacterPosEnemyOriginX < 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight) { bCollisionUp = true; } if (CharacterPosEnemyOriginY > 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight || CharacterPosEnemyOriginY < 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight) { bCollisionLeft = true; } else if (CharacterPosEnemyOriginY > 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight || CharacterPosEnemyOriginY < 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight) { bCollisionRight = true; } // Enemy does not go outside a specific range of the Player if (vCharacterPositionEnemyOrigin.X > (-iDistanceDetection / 2) || vCharacterPositionEnemyOrigin.X < (iDistanceDetection / 2)) { if (vCharacterPositionEnemyOrigin.Y < (iDistanceDetection / 2)) { nearup = true; } if (vCharacterPositionEnemyOrigin.Y > (-iDistanceDetection / 2)) { neardown = true; } } if (vCharacterPositionEnemyOrigin.Y < (iDistanceDetection / 2) || vCharacterPositionEnemyOrigin.Y > (-iDistanceDetection / 2)) { if (vCharacterPositionEnemyOrigin.X > (-iDistanceDetection / 2)) { nearright = true; } if (vCharacterPositionEnemyOrigin.X < (iDistanceDetection / 2)) { nearleft = true; } } do { if (bRepeat) { bRepeat = false; iRandomNumber = rRandom.Next(0, 4); iRepeating++; } switch (iRandomNumber) { case (0): if (nearup && !bCollisionUp) { MoveUp(); } else { bRepeat = true; } break; case (1): if (neardown && !bCollisionDown) { MoveDown(); } else { bRepeat = true; } break; case (2): if (nearright && !bCollisionRight) { MoveRight(); } else { bRepeat = true; } break; case (3): if (nearleft && !bCollisionLeft) { MoveLeft(); } else { bRepeat = true; } break; } }while (bRepeat && iRepeating <= 2); }