/// <summary> /// Simple Collision Detection, return true if Collision /// </summary> /// <param name="vEntityPosition">Position of the Entity</param> /// <param name="uWidth">Width of the tEntity</param> /// <param name="uHeight">Height of the tEntity</param> protected bool SimpleCollisionDetection(Vector2f vEntityPosition, uint uWidth, uint uHeight) { Vector2f vEntityPos = vEntityPosition - MainMap.GetTileMapPosition(); int iTileNearY = (int)vEntityPos.Y / 50; int iTileNearX = (int)vEntityPos.X / 50; if (iTileNearY < 0) { iTileNearY++; } if (iTileNearX < 0) { iTileNearX++; } for (int y = iTileNearY; y < iTileNearY + 2; y++) { for (int x = iTileNearX; x < iTileNearX + 2; x++) { // COLLISIONDETECTION ON ENTITY BORDER if (TileArrayCreation.CollisionReturnerProjectiles(x, y)) { if (vEntityPos.Y < (y + 1) * 50 && vEntityPos.Y > y * 50 && vEntityPos.X < (x + 1) * 50 && vEntityPos.X > x * 50 || vEntityPos.Y + uHeight < (y + 1) * 50 && vEntityPos.Y + uHeight > y * 50 && vEntityPos.X < (x + 1) * 50 && vEntityPos.X > x * 50 || vEntityPos.Y < (y + 1) * 50 && vEntityPos.Y > y * 50 && vEntityPos.X + uWidth < (x + 1) * 50 && vEntityPos.X + uWidth > x * 50 || vEntityPos.Y + uHeight < (y + 1) * 50 && vEntityPos.Y + uHeight > y * 50 && vEntityPos.X + uWidth < (x + 1) * 50 && vEntityPos.X + uWidth > x * 50) { return(true); } } } } return(false); }
/// <summary> /// Updates Player Logic /// </summary> /// <param name="VirtualPlayerPosition">Virtual Player Position, aka Position if the Player would move, not the Map</param> /// <param name="up">Bool allowing up Movement</param> /// <param name="down">Bool allowing down Movement</param> /// <param name="right">Bool allowing right Movement</param> /// <param name="left">Bool allowing left Movement</param> public void Update(ref Vector2f VirtualPlayerPosition, ref bool up, ref bool down, ref bool right, ref bool left) { CollisionDetection(ref VirtualPlayerPosition, ref up, ref down, ref right, ref left, sCharacter.Radius * 2, sCharacter.Radius * 2); PlayerRotation(); if (Input.Shoot) { tShoot = cShoot.ElapsedTime; if (tShoot.AsMilliseconds() > 333) { cShoot.Restart(); Shoot(MainMap.GetTileMapPosition()); } } for (int x = 0; x < lProjectile.Count; x++) { lProjectile[x].Update(); } DisposeProjectile(lProjectile, uDamage); fProcentualHealth = (float)fHealth / (float)iHealthMax; if (fHealth >= 0) { sCharacter.FillColor = new Color(255, (byte)(0 + (255 * fProcentualHealth)), (byte)(0 + (255 * fProcentualHealth))); } tRegenerate = cRegenarate.ElapsedTime; if (tRegenerate.AsSeconds() > 3 && fHealth < iHealthMax) { fHealth += (float)100 / 1500; if (fHealth > iHealthMax) { fHealth = iHealthMax; } } }
/// <summary> /// Updates Enemy Logic /// </summary> public override void Update(ref Vector2f VirtualPlayerPosition, ref bool up, ref bool down, ref bool right, ref bool left) { tShooting = cShooting.ElapsedTime; PlayerEnemyCollision(ref VirtualPlayerPosition, ref up, ref down, ref right, ref left); DetectLogic(); UpdatingProjectiles(); fProcentualHealth = (float)iHealth / (float)iHealthMax; if (iHealth >= 0) { sEntity.Color = new Color(255, (byte)(0 + (255 * fProcentualHealth)), (byte)(0 + (255 * fProcentualHealth))); } sEntity.Rotation = fAngle; sEntity.Position = MainMap.GetTileMapPosition() + vEntityPosition + new Vector2f(25, 25); }
/// <summary> /// Updates only EnemyPosition, used to optimize performance /// </summary> public void PassiveUpdate() { sEntity.Position = MainMap.GetTileMapPosition() + vEntityPosition + new Vector2f(25, 25); }
/// <summary> /// Shows all the used Nodes in the Path Finding Algorithm /// </summary> protected void DrawPathFinder(Font ffont) { List <CircleShape> lCircles; lCircles = new List <CircleShape>(); for (int x = 0; x < Closed.Count; x++) { CircleShape cShape; Text tText; cShape = new CircleShape(25, 4); cShape.Origin = new Vector2f(25, 25); cShape.Rotation = 45; cShape.FillColor = Color.Cyan; cShape.Position = Closed[x].vPosition * 50 + MainMap.GetTileMapPosition() + new Vector2f(25, 25); lDrawList.Add(cShape); tText = new Text(Closed[x].iFCost.ToString(), ffont, 15); tText.Position = cShape.Position - new Vector2f(14f, 3f); tText.Color = Color.Black; lDrawList.Add(tText); tText = new Text(Closed[x].iGCost.ToString(), ffont, 10); tText.Position = cShape.Position - new Vector2f(18f, 15f); tText.Color = Color.Black; lDrawList.Add(tText); tText = new Text(Closed[x].iHCost.ToString(), ffont, 10); tText.Position = cShape.Position - new Vector2f(-2f, 15f); tText.Color = Color.Black; lDrawList.Add(tText); } for (int x = 0; x < Path.Count; x++) { CircleShape cShape; Text tText; cShape = new CircleShape(25, 4); cShape.Origin = new Vector2f(25, 25); cShape.Rotation = 45; cShape.FillColor = Color.Blue; cShape.Position = Path[x].vPosition + MainMap.GetTileMapPosition() + new Vector2f(25, 25); lDrawList.Add(cShape); tText = new Text(Path[x].iFCost.ToString(), ffont, 15); tText.Position = cShape.Position - new Vector2f(14f, 3f); tText.Color = Color.Black; lDrawList.Add(tText); tText = new Text(Path[x].iGCost.ToString(), ffont, 10); tText.Position = cShape.Position - new Vector2f(18f, 15f); tText.Color = Color.Black; lDrawList.Add(tText); tText = new Text(Path[x].iHCost.ToString(), ffont, 10); tText.Position = cShape.Position - new Vector2f(-2f, 15f); tText.Color = Color.Black; lDrawList.Add(tText); } if (Path.Count > 1) { CircleShape cShape; Text tText; cShape = new CircleShape(25, 4); cShape.Origin = new Vector2f(25, 25); cShape.Rotation = 45; cShape.FillColor = Color.Black; cShape.Position = Path[Path.Count - 1].vPosition + MainMap.GetTileMapPosition() + new Vector2f(25, 25); lDrawList.Add(cShape); tText = new Text(Path[Path.Count - 1].iFCost.ToString(), ffont, 15); tText.Position = cShape.Position - new Vector2f(14f, 3f); tText.Color = Color.White; lDrawList.Add(tText); tText = new Text(Path[Path.Count - 1].iGCost.ToString(), ffont, 10); tText.Position = cShape.Position - new Vector2f(18f, 15f); tText.Color = Color.White; lDrawList.Add(tText); tText = new Text(Path[Path.Count - 1].iHCost.ToString(), ffont, 10); tText.Position = cShape.Position - new Vector2f(-2f, 15f); tText.Color = Color.White; lDrawList.Add(tText); } }
// 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); }
/// <summary> /// Updates PathFinder Logic of the Archer. /// Moves the Enemy to the Player once the Pathfinding Algorithm was initiated. /// The Archer follows the created nodes, but still respects Collisions with Tiles. /// </summary> protected void PathfinderLogic() { bool MovingUp = false; bool MovingDown = false; bool MovingRight = false; bool MovingLeft = false; if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X - 1) / 50), (int)(vEntityPosition.Y / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X - 1) / 50), (int)((vEntityPosition.Y + 25) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X - 1) / 50), (int)((vEntityPosition.Y + 49) / 50))) { MovingLeft = true; } if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 50) / 50), (int)(vEntityPosition.Y / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 50) / 50), (int)((vEntityPosition.Y + 25) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 50) / 50), (int)((vEntityPosition.Y + 49) / 50))) { MovingRight = true; } if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X) / 50), (int)((vEntityPosition.Y - 1) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 25) / 50), (int)((vEntityPosition.Y - 1) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 49) / 50), (int)((vEntityPosition.Y - 1) / 50))) { MovingUp = true; } if (MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X) / 50), (int)((vEntityPosition.Y + 50) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 25) / 50), (int)((vEntityPosition.Y + 50) / 50)) || MainMap.GetTileManager().GetCollisionAt(((int)(vEntityPosition.X + 49) / 50), (int)((vEntityPosition.Y + 50) / 50))) { MovingDown = true; } if (Path.Count - 1 >= 0) { CurrentGoal = (Vector2i)Path[Path.Count - 1].vPosition + (Vector2i)MainMap.GetTileMapPosition() + new Vector2i(25, 25); CurrentGoalOrigin = CurrentGoal - (Vector2i)sEntity.Position; float MovementX = (CurrentGoalOrigin.X / Utilities.MakePositive(Utilities.DistanceToVectorFromOrigin(new Vector2f(CurrentGoalOrigin.X, 0)))); float MovementY = (CurrentGoalOrigin.Y / Utilities.MakePositive(Utilities.DistanceToVectorFromOrigin(new Vector2f(0, CurrentGoalOrigin.Y)))); int PositionX1 = (int)((vEntityPosition.X + MovementX) / 50); int PositionY1 = (int)((vEntityPosition.Y + MovementY) / 50); int PositionX = (int)((vEntityPosition.X) / 50); int PositionY = (int)((vEntityPosition.Y) / 50); if (!MovementX.Equals(0 / Zero)) { if (CurrentGoalOrigin.X > 0 && !MovingRight) { vEntityPosition.X += fSpeed; } if (CurrentGoalOrigin.X < 0 && !MovingLeft) { vEntityPosition.X -= fSpeed; } } if (!MovementY.Equals(0 / Zero)) { if (CurrentGoalOrigin.Y > 0 && !MovingDown) { vEntityPosition.Y += fSpeed; } if (CurrentGoalOrigin.Y < 0 && !MovingUp) { vEntityPosition.Y -= fSpeed; } } if (sEntity.Position.X - 15 <= CurrentGoal.X && sEntity.Position.X + 15 >= CurrentGoal.X && sEntity.Position.Y - 15 <= CurrentGoal.Y && sEntity.Position.Y + 15 >= CurrentGoal.Y) { Path.RemoveAt(Path.Count - 1); } RotateEnemy(ref fAngle, vRegisteredPlayerPosition + MainMap.GetTileMapPosition() + (vEnemyDirection - sEntity.Position)); } }
/// <summary> /// Detects the Entity Collision /// Returns 0 if no Collision /// </summary> protected int CollisionDetection(Vector2f vEntityPosition, uint uLength, uint uHeight) { Vector2f vEntityPos = vEntityPosition - MainMap.GetTileMapPosition(); vEntityPositionBottomLeft.Y = vEntityPos.Y + uHeight; vEntityPositionTopRight.X = vEntityPos.X + uLength; int iTileNearY = (int)vEntityPos.Y / 50; int iTileNearX = (int)vEntityPos.X / 50; if (iTileNearY < 0) { iTileNearY++; } if (iTileNearX < 0) { iTileNearX++; } for (int y = iTileNearY; y < iTileNearY + 2; y++) { for (int x = iTileNearX; x < iTileNearX + 2; x++) { // COLLISIONDETECTION ON ENTITY BORDER if (TileArrayCreation.CollisionReturner(x, y)) { if (((vEntityPos.Y < (y + 1) * 50 && vEntityPos.Y > y * 50 - 1) || (vEntityPos.Y < y * 50 && vEntityPos.Y > (y - 1) * 50))) { if (vEntityPos.X <= (x + 1) * 50 && vEntityPos.X >= x * 50) { return(1); } else if (vEntityPositionTopRight.X >= x * 50 && vEntityPositionTopRight.X <= (x + 1) * 50) { return(2); } } if (((vEntityPos.X < (x + 1) * 50 && vEntityPos.X > x * 50 - 1) || (vEntityPositionTopRight.X > x * 50 && vEntityPositionTopRight.X < (x + 1) * 50))) { if (vEntityPos.Y <= (y + 1) * 50 && vEntityPos.Y >= y * 50) { return(3); } else if (vEntityPositionBottomLeft.Y >= y * 50 && vEntityPositionBottomLeft.Y <= (y + 1) * 50) { return(4); } } } } } return(0); }