diff --git a/AlientAttack.MonoGame/Content/Content.mgcb b/AlientAttack.MonoGame/Content/Content.mgcb index 54c0766..ff50621 100644 --- a/AlientAttack.MonoGame/Content/Content.mgcb +++ b/AlientAttack.MonoGame/Content/Content.mgcb @@ -1781,7 +1781,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_01_png_processed.png +/build:Sprites/Explosion01_Frame_01_png_processed.png;Sprites/Explosion01_Frame_01.png #begin Sprites/Explosion01_Frame_02_png_processed.png /importer:TextureImporter @@ -1793,7 +1793,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_02_png_processed.png +/build:Sprites/Explosion01_Frame_02_png_processed.png;Sprites/Explosion01_Frame_02.png #begin Sprites/Explosion01_Frame_03_png_processed.png /importer:TextureImporter @@ -1805,7 +1805,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_03_png_processed.png +/build:Sprites/Explosion01_Frame_03_png_processed.png;Sprites/Explosion01_Frame_03.png #begin Sprites/Explosion01_Frame_04_png_processed.png /importer:TextureImporter @@ -1817,7 +1817,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_04_png_processed.png +/build:Sprites/Explosion01_Frame_04_png_processed.png;Sprites/Explosion01_Frame_04.png #begin Sprites/Explosion01_Frame_05_png_processed.png /importer:TextureImporter @@ -1829,7 +1829,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_05_png_processed.png +/build:Sprites/Explosion01_Frame_05_png_processed.png;Sprites/Explosion01_Frame_05.png #begin Sprites/Explosion01_Frame_06_png_processed.png /importer:TextureImporter @@ -1841,7 +1841,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_06_png_processed.png +/build:Sprites/Explosion01_Frame_06_png_processed.png;Sprites/Explosion01_Frame_06.png #begin Sprites/Explosion01_Frame_07_png_processed.png /importer:TextureImporter @@ -1853,7 +1853,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_07_png_processed.png +/build:Sprites/Explosion01_Frame_07_png_processed.png;Sprites/Explosion01_Frame_07.png #begin Sprites/Explosion01_Frame_08_png_processed.png /importer:TextureImporter @@ -1865,7 +1865,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_08_png_processed.png +/build:Sprites/Explosion01_Frame_08_png_processed.png;Sprites/Explosion01_Frame_08.png #begin Sprites/Explosion01_Frame_09_png_processed.png /importer:TextureImporter @@ -1877,7 +1877,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion01_Frame_09_png_processed.png +/build:Sprites/Explosion01_Frame_09_png_processed.png;Sprites/Explosion01_Frame_09.png #begin Sprites/Explosion02_Frame_01_png_processed.png /importer:TextureImporter @@ -1889,7 +1889,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_01_png_processed.png +/build:Sprites/Explosion02_Frame_01_png_processed.png;Sprites/Explosion02_Frame_01.png #begin Sprites/Explosion02_Frame_02_png_processed.png /importer:TextureImporter @@ -1901,7 +1901,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_02_png_processed.png +/build:Sprites/Explosion02_Frame_02_png_processed.png;Sprites/Explosion02_Frame_02.png #begin Sprites/Explosion02_Frame_03_png_processed.png /importer:TextureImporter @@ -1913,7 +1913,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_03_png_processed.png +/build:Sprites/Explosion02_Frame_03_png_processed.png;Sprites/Explosion02_Frame_03.png #begin Sprites/Explosion02_Frame_04_png_processed.png /importer:TextureImporter @@ -1925,7 +1925,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_04_png_processed.png +/build:Sprites/Explosion02_Frame_04_png_processed.png;Sprites/Explosion02_Frame_04.png #begin Sprites/Explosion02_Frame_05_png_processed.png /importer:TextureImporter @@ -1937,7 +1937,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_05_png_processed.png +/build:Sprites/Explosion02_Frame_05_png_processed.png;Sprites/Explosion02_Frame_05.png #begin Sprites/Explosion02_Frame_06_png_processed.png /importer:TextureImporter @@ -1949,7 +1949,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_06_png_processed.png +/build:Sprites/Explosion02_Frame_06_png_processed.png;Sprites/Explosion02_Frame_06.png #begin Sprites/Explosion02_Frame_07_png_processed.png /importer:TextureImporter @@ -1961,7 +1961,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_07_png_processed.png +/build:Sprites/Explosion02_Frame_07_png_processed.png;Sprites/Explosion02_Frame_07.png #begin Sprites/Explosion02_Frame_08_png_processed.png /importer:TextureImporter @@ -1973,7 +1973,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_08_png_processed.png +/build:Sprites/Explosion02_Frame_08_png_processed.png;Sprites/Explosion02_Frame_08.png #begin Sprites/Explosion02_Frame_09_png_processed.png /importer:TextureImporter @@ -1985,7 +1985,7 @@ /processorParam:ResizeToPowerOfTwo=False /processorParam:MakeSquare=False /processorParam:TextureFormat=Color -/build:Sprites/Explosion02_Frame_09_png_processed.png +/build:Sprites/Explosion02_Frame_09_png_processed.png;Sprites/Explosion02_Frame_09.png #begin Sprites/GunTurret_ExampleGun_png_processed.png /importer:TextureImporter diff --git a/AlientAttack.MonoGame/GameLoops/GameLoop.cs b/AlientAttack.MonoGame/GameLoops/GameLoop.cs index 6c50c93..62b5842 100644 --- a/AlientAttack.MonoGame/GameLoops/GameLoop.cs +++ b/AlientAttack.MonoGame/GameLoops/GameLoop.cs @@ -384,33 +384,51 @@ internal class GameLoop : GameLoopBase Sprites.Add(enemy); _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); } - else if (randomNumber == 9) - { - GreenTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); - Sprites.Add(enemy); - _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); - } - else if (randomNumber == 10) - { - RedTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); - Sprites.Add(enemy); - _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); - } - else if (randomNumber == 11) - { - OrangeTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); - Sprites.Add(enemy); - _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); - } - else if (randomNumber == 12) - { - TealTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); - Sprites.Add(enemy); - _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); - } + //else if (randomNumber == 9) + //{ + // GreenTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); + // Sprites.Add(enemy); + // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); + //} + //else if (randomNumber == 10) + //{ + // RedTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); + // Sprites.Add(enemy); + // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); + //} + //else if (randomNumber == 11) + //{ + // OrangeTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); + // Sprites.Add(enemy); + // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); + //} + //else if (randomNumber == 12) + //{ + // TealTurret enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Turret.MountWidth), -Turret.MountHeight); + // Sprites.Add(enemy); + // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); + //} else if (randomNumber == 13) { - Asteroid enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Asteroid.Width), -Asteroid.Height); + AsteroidVariantA enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantA.Width), -AsteroidVariantA.Height); + Sprites.Add(enemy); + _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); + } + else if (randomNumber == 14) + { + AsteroidVariantB enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantB.Width), -AsteroidVariantB.Height); + Sprites.Add(enemy); + _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); + } + else if (randomNumber == 15) + { + AsteroidVariantC enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantC.Width), -AsteroidVariantC.Height); + Sprites.Add(enemy); + _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); + } + else if (randomNumber == 16) + { + AsteroidVariantD enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantD.Width), -AsteroidVariantD.Height); Sprites.Add(enemy); _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); } diff --git a/AlientAttack.MonoGame/Textures/TextureId.cs b/AlientAttack.MonoGame/Textures/TextureId.cs index 630fa4b..04366fe 100644 --- a/AlientAttack.MonoGame/Textures/TextureId.cs +++ b/AlientAttack.MonoGame/Textures/TextureId.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace AlienAttack.MonoGame.Textures; +namespace AlienAttack.MonoGame.Textures; //public enum TextureId //{ @@ -39,4 +33,12 @@ public static class TextureNames public const string ProtonMedium = "Sprites/Proton_Medium"; public const string ProtonLarge = "Sprites/Proton_Large"; } + + public static class Asteriods + { + public const string VariantA = "Sprites/Asteroid 01"; + public const string VariantB = "Sprites/Asteroid 02"; + public const string VariantC = "Sprites/Asteroid 03"; + public const string VariantD = "Sprites/Asteroid 04"; + } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Asteroids/Asteroid.cs b/AlientAttack.MonoGame/Things/Asteroids/Asteroid.cs index 0115e1b..186a916 100644 --- a/AlientAttack.MonoGame/Things/Asteroids/Asteroid.cs +++ b/AlientAttack.MonoGame/Things/Asteroids/Asteroid.cs @@ -1,27 +1,28 @@ -using Microsoft.Xna.Framework; +using AlienAttack.MonoGame.Things.Bullets; +using AlienAttack.MonoGame.Things.Explosions; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace AlienAttack.MonoGame.Things.Asteroids; -public class Asteroid : MoveableSprite +public abstract class Asteroid : MoveableSprite { - public const int Width = 39; - public const int Height = 37; + protected abstract int MaxHealth { get; } + protected abstract string TextureName { get; } - protected float Rotation = 0; + protected int Health { get; set; } + protected float RotationSpeed { get; set; } = 1f; public Asteroid(int x, int y) : base(x, y) { - Origin = new(Width / 2, Height / 2); - BoundBox = new(0, 0, Width, Height); - YVelocity = 1; - XVelocity = 0; + Health = MaxHealth; + RotationSpeed = 1f; } public override void Draw(SpriteDrawArgs args) { - Texture2D texture = args.Content.Load("Sprites/Asteroid 01"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, Origin, 1f, SpriteEffects.None, 1); + Texture2D texture = args.Textures.Get(TextureName); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, Origin, Scale, SpriteEffects.None, 1); base.Draw(args); } @@ -32,17 +33,33 @@ public class Asteroid : MoveableSprite CollisionBox = new Rectangle((int)XPosition + BoundBox.X - (int)Origin.X, (int)YPosition + BoundBox.Y - (int)Origin.Y, BoundBox.Width, BoundBox.Height); + if (Health <= 0) + { + IsDead = true; + context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + context.AudioManager.PlayExplosion(); + return; + } + if (YPosition - Origin.Y > context.ViewTransform.ScreenHeight) { IsDead = true; return; } - Rotation += 0.01f; + Rotation = MathHelper.WrapAngle(Rotation + RotationSpeed * context.DeltaTime); + } - if (Rotation > 360f) + public override void OnCollision(SpriteCollisionContext context) + { + if (context.Sprite is Bullet bullet && bullet.Owner is Player) { - Rotation = 0; + Health -= bullet.Damage; + } + + if (context.Sprite is Player) + { + Health = 0; } } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantA.cs b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantA.cs new file mode 100644 index 0000000..faba89a --- /dev/null +++ b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantA.cs @@ -0,0 +1,20 @@ +using AlienAttack.MonoGame.Textures; + +namespace AlienAttack.MonoGame.Things.Asteroids; + +public class AsteroidVariantA : Asteroid +{ + public const int Width = 39; + public const int Height = 37; + + protected override string TextureName => TextureNames.Asteriods.VariantA; + protected override int MaxHealth => 8; + + public AsteroidVariantA(int x, int y) : base(x, y) + { + Origin = new(Width / 2, Height / 2); + BoundBox = new(0, 0, Width, Height); + YVelocity = 1; + XVelocity = 0; + } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantB.cs b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantB.cs new file mode 100644 index 0000000..bec3f40 --- /dev/null +++ b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantB.cs @@ -0,0 +1,20 @@ +using AlienAttack.MonoGame.Textures; + +namespace AlienAttack.MonoGame.Things.Asteroids; + +public class AsteroidVariantB : Asteroid +{ + public const int Width = 26; + public const int Height = 28; + + protected override string TextureName => TextureNames.Asteriods.VariantB; + protected override int MaxHealth => 4; + + public AsteroidVariantB(int x, int y) : base(x, y) + { + Origin = new(Width / 2, Height / 2); + BoundBox = new(0, 0, Width, Height); + YVelocity = 2; + XVelocity = 0; + } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantC.cs b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantC.cs new file mode 100644 index 0000000..63d93d3 --- /dev/null +++ b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantC.cs @@ -0,0 +1,20 @@ +using AlienAttack.MonoGame.Textures; + +namespace AlienAttack.MonoGame.Things.Asteroids; + +public class AsteroidVariantC : Asteroid +{ + public const int Width = 37; + public const int Height = 36; + + protected override string TextureName => TextureNames.Asteriods.VariantC; + protected override int MaxHealth => 5; + + public AsteroidVariantC(int x, int y) : base(x, y) + { + Origin = new(Width / 2, Height / 2); + BoundBox = new(0, 0, Width, Height); + YVelocity = 1.5f; + XVelocity = 0; + } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantD.cs b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantD.cs new file mode 100644 index 0000000..025e96c --- /dev/null +++ b/AlientAttack.MonoGame/Things/Asteroids/AsteroidVariantD.cs @@ -0,0 +1,20 @@ +using AlienAttack.MonoGame.Textures; + +namespace AlienAttack.MonoGame.Things.Asteroids; + +public class AsteroidVariantD : Asteroid +{ + public const int Width = 44; + public const int Height = 35; + + protected override string TextureName => TextureNames.Asteriods.VariantD; + protected override int MaxHealth => 10; + + public AsteroidVariantD(int x, int y) : base(x, y) + { + Origin = new(Width / 2, Height / 2); + BoundBox = new(0, 0, Width, Height); + YVelocity = .5f; + XVelocity = 0; + } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Bullets/Bullet.cs b/AlientAttack.MonoGame/Things/Bullets/Bullet.cs index 204a86d..e4abac9 100644 --- a/AlientAttack.MonoGame/Things/Bullets/Bullet.cs +++ b/AlientAttack.MonoGame/Things/Bullets/Bullet.cs @@ -1,4 +1,4 @@ -using AlienAttack.MonoGame.Textures; +using AlienAttack.MonoGame.Things.Explosions; using AlienAttack.MonoGame.Things.Items; using Microsoft.Xna.Framework.Graphics; using System; diff --git a/AlientAttack.MonoGame/Things/Enemies/Enemy.cs b/AlientAttack.MonoGame/Things/Enemies/Enemy.cs index 7f33c29..e2db637 100644 --- a/AlientAttack.MonoGame/Things/Enemies/Enemy.cs +++ b/AlientAttack.MonoGame/Things/Enemies/Enemy.cs @@ -1,4 +1,5 @@ using AlienAttack.MonoGame.Things.Bullets; +using AlienAttack.MonoGame.Things.Explosions; using AlienAttack.MonoGame.Things.Items; namespace AlienAttack.MonoGame.Things.Enemies; diff --git a/AlientAttack.MonoGame/Things/Enemies/EnemyShip.cs b/AlientAttack.MonoGame/Things/Enemies/EnemyShip.cs index 120ecc6..973c382 100644 --- a/AlientAttack.MonoGame/Things/Enemies/EnemyShip.cs +++ b/AlientAttack.MonoGame/Things/Enemies/EnemyShip.cs @@ -1,4 +1,5 @@ using AlienAttack.MonoGame.Things.Bullets; +using AlienAttack.MonoGame.Things.Explosions; using Microsoft.Xna.Framework; namespace AlienAttack.MonoGame.Things.Enemies; diff --git a/AlientAttack.MonoGame/Things/Enemies/Mines/BlueMine.cs b/AlientAttack.MonoGame/Things/Enemies/Mines/BlueMine.cs index ef1e0ba..105498a 100644 --- a/AlientAttack.MonoGame/Things/Enemies/Mines/BlueMine.cs +++ b/AlientAttack.MonoGame/Things/Enemies/Mines/BlueMine.cs @@ -3,4 +3,6 @@ public class BlueMine(int x, int y) : Mine(x, y) { protected override string CoverColor => "Blue"; + protected override float ExplodeRadius => 100f; + protected override int MaxHealth => 10; } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Enemies/Mines/GreenMine.cs b/AlientAttack.MonoGame/Things/Enemies/Mines/GreenMine.cs index 0ad1e54..8bbb18a 100644 --- a/AlientAttack.MonoGame/Things/Enemies/Mines/GreenMine.cs +++ b/AlientAttack.MonoGame/Things/Enemies/Mines/GreenMine.cs @@ -3,4 +3,6 @@ public class GreenMine(int x, int y) : Mine(x, y) { protected override string CoverColor => "Green"; + protected override float ExplodeRadius => 100f; + protected override int MaxHealth => 10; } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Enemies/Mines/Mine.cs b/AlientAttack.MonoGame/Things/Enemies/Mines/Mine.cs index 28e9894..4b1dfe9 100644 --- a/AlientAttack.MonoGame/Things/Enemies/Mines/Mine.cs +++ b/AlientAttack.MonoGame/Things/Enemies/Mines/Mine.cs @@ -1,4 +1,6 @@ -using Microsoft.Xna.Framework; +using AlienAttack.MonoGame.Things.Bullets; +using AlienAttack.MonoGame.Things.Explosions; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; @@ -9,7 +11,13 @@ public abstract class Mine : MoveableSprite public const int Width = 65; public const int Height = 64; + protected abstract int MaxHealth { get; } protected abstract string CoverColor { get; } + protected abstract float ExplodeRadius { get; } + + protected int Health { get; set; } + protected float RotationSpeed { get; set; } = 1.5f; + protected double DistanceToPlayer { get; set; } = double.MaxValue; public Mine(int x, int y) : base(x, y) { @@ -17,38 +25,45 @@ public abstract class Mine : MoveableSprite BoundBox = new(10, 14, 40, 38); YVelocity = 1; XVelocity = 0; + Health = MaxHealth; } public override void Draw(SpriteDrawArgs args) { DrawRotor(args); DrawCover(args); + + base.Draw(args); } private void DrawRotor(SpriteDrawArgs args) { Texture2D texture = args.Content.Load("Sprites/Rotor"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, Origin, 1f, SpriteEffects.None, 1); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, Origin, Scale, SpriteEffects.None, 1); } private void DrawCover(SpriteDrawArgs args) { Texture2D texture = args.Content.Load($"Sprites/Cover_{CoverColor}"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, Origin, 1f, SpriteEffects.None, 1); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, Origin, Scale, SpriteEffects.None, 1); } public override sealed void Update(SpriteUpdateContext context) { base.Update(context); - CollisionBox = new Rectangle((int)XPosition + BoundBox.X - (int)Origin.X, (int)YPosition + BoundBox.Y - (int)Origin.Y, BoundBox.Width, BoundBox.Height); + if (Health <= 0) + { + IsDead = true; + SpawnExplosion(context); + //OnKilled(context); + return; + } - float xDiff = (XPosition + Origin.X) - (context.Player.XPosition + context.Player.Origin.X); - float yDiff = (YPosition + Origin.Y) - (context.Player.YPosition + context.Player.Origin.Y); + UpdateDistanceToPlayer(context); + OnUpdate(context); - double distance = Math.Sqrt(xDiff * xDiff + yDiff * yDiff); - - if (distance < 100) + if (DistanceToPlayer <= ExplodeRadius) { IsDead = true; SpawnExplosion(context); @@ -61,17 +76,38 @@ public abstract class Mine : MoveableSprite return; } - Rotation += 0.01f; + Rotation = MathHelper.WrapAngle(Rotation + RotationSpeed * context.DeltaTime); + } - if (Rotation > 360f) + private void UpdateDistanceToPlayer(SpriteUpdateContext context) + { + float xDiff = (XPosition + Origin.X) - (context.Player.XPosition + context.Player.Origin.X); + float yDiff = (YPosition + Origin.Y) - (context.Player.YPosition + context.Player.Origin.Y); + + DistanceToPlayer = Math.Sqrt(xDiff * xDiff + yDiff * yDiff); + } + + protected virtual void OnUpdate(SpriteUpdateContext context) + { + + } + + public override void OnCollision(SpriteCollisionContext context) + { + if (context.Sprite is Bullet bullet && bullet.Owner is Player) { - Rotation = 0; + Health -= bullet.Damage; + } + + if (context.Sprite is Player) + { + Health = 0; } } - private void SpawnExplosion(SpriteUpdateContext context) + protected void SpawnExplosion(SpriteUpdateContext context) { - context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + context.SpawnSprite(new MineExplosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); context.AudioManager.PlayExplosion(); } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Enemies/Mines/RedMine.cs b/AlientAttack.MonoGame/Things/Enemies/Mines/RedMine.cs index 9c38aca..09a994e 100644 --- a/AlientAttack.MonoGame/Things/Enemies/Mines/RedMine.cs +++ b/AlientAttack.MonoGame/Things/Enemies/Mines/RedMine.cs @@ -1,6 +1,78 @@ -namespace AlienAttack.MonoGame.Things.Enemies.Mines; +using AlienAttack.MonoGame.Things.Bullets; +using Microsoft.Xna.Framework; + +namespace AlienAttack.MonoGame.Things.Enemies.Mines; public class RedMine(int x, int y) : Mine(x, y) { + protected bool IsCharging = false; + protected Vector2 TargetCenter; protected override string CoverColor => "Red"; + protected override float ExplodeRadius => 18f; + protected override int MaxHealth => 10; + + // Tunables + private const float DetectRange = 200f; + private const float ChargeSpeed = 5f; // try 3.5–6.0 + + protected override void OnUpdate(SpriteUpdateContext context) + { + // If not charging yet, see if we should lock on + if (!IsCharging) + { + if (DistanceToPlayer > DetectRange) + return; + + Charge(context.Player); + } + + // We are charging: steer directly toward the locked target point + Vector2 toTarget = TargetCenter - new Vector2(XPosition + Origin.X, YPosition + Origin.Y); + + float dist = toTarget.Length(); + + if (dist <= ExplodeRadius) + { + IsDead = true; + + // Optionally: explode at target (top-left adjustment) + XPosition = TargetCenter.X - Origin.X; + YPosition = TargetCenter.Y - Origin.Y; + + SpawnExplosion(context); // uses current XPosition/YPosition + return; + } + + // Normalize direction (avoid NaN if dist == 0) + Vector2 dir = toTarget / dist; + + // Set velocities for base.Update to apply next frame + XVelocity = dir.X * ChargeSpeed; + YVelocity = dir.Y * ChargeSpeed; + + // Optional: if you want it to stop “floating down” once charging + // (it will anyway, because we overwrite YVelocity) + } + + public override void OnCollision(SpriteCollisionContext context) + { + base.OnCollision(context); + + if (context.Sprite is Bullet bullet && bullet.Owner is Player player && IsCharging == false) + { + Charge(player); + } + } + + private void Charge(Sprite target) + { + IsCharging = true; + + float x = target.XPosition + target.Origin.X; + float y = target.YPosition + target.Origin.Y; + + TargetCenter = new Vector2(x, y); + + RotationSpeed *= ChargeSpeed; + } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Enemies/Turrets/Turret.cs b/AlientAttack.MonoGame/Things/Enemies/Turrets/Turret.cs index fe9bd2f..3c337b7 100644 --- a/AlientAttack.MonoGame/Things/Enemies/Turrets/Turret.cs +++ b/AlientAttack.MonoGame/Things/Enemies/Turrets/Turret.cs @@ -37,19 +37,19 @@ public abstract class Turret : MoveableSprite private void DrawMount(SpriteDrawArgs args) { Texture2D texture = args.Content.Load("Sprites/GunTurretMount"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, MountOrigin, 1f, SpriteEffects.None, 1); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, MountOrigin, Scale, SpriteEffects.None, 1); } private void DrawTurret(SpriteDrawArgs args) { Texture2D texture = args.Content.Load($"Sprites/GunTurret_{TurretColor}"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, TurretOrigin, 1f, SpriteEffects.None, 1); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, TurretOrigin, Scale, SpriteEffects.None, 1); } private void DrawGun(SpriteDrawArgs args) { Texture2D texture = args.Content.Load("Sprites/GunTurret_ExampleGun"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, GunOrigin, 1f, SpriteEffects.None, 1); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, Rotation, GunOrigin, Scale, SpriteEffects.None, 1); } public override sealed void Update(SpriteUpdateContext context) diff --git a/AlientAttack.MonoGame/Things/Explosion.cs b/AlientAttack.MonoGame/Things/Explosions/Explosion.cs similarity index 69% rename from AlientAttack.MonoGame/Things/Explosion.cs rename to AlientAttack.MonoGame/Things/Explosions/Explosion.cs index 6467733..e94f5b4 100644 --- a/AlientAttack.MonoGame/Things/Explosion.cs +++ b/AlientAttack.MonoGame/Things/Explosions/Explosion.cs @@ -1,13 +1,12 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Graphics; -namespace AlienAttack.MonoGame.Things; +namespace AlienAttack.MonoGame.Things.Explosions; public class Explosion : MoveableSprite { protected int CurrentFrame { get; private set; } = 1; protected int MaxFrames => 9; - protected int AnimationThreshold => 3; //5; + protected int AnimationThreshold => 3; protected int CurrentThreshold { get; private set; } = 5; public Explosion(int x, int y, float xVel, float yVel) : base(x, y) @@ -19,9 +18,8 @@ public class Explosion : MoveableSprite public override void Draw(SpriteDrawArgs args) { - Texture2D texture = args.Content.Load(@$"Sprites\Explosion01_Frame_0{CurrentFrame}_png_processed"); - //args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, new Vector2(0, 0), 1f, SpriteEffects.None, 1); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, Origin, 1f, SpriteEffects.None, 1); + Texture2D texture = args.Content.Load(@$"Sprites\Explosion01_Frame_0{CurrentFrame}"); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, Origin, Scale, SpriteEffects.None, 1); base.Draw(args); } @@ -30,9 +28,6 @@ public class Explosion : MoveableSprite { base.Update(context); - //XPosition += XVelocity; - //YPosition += YVelocity; - if (CurrentThreshold > 0) { CurrentThreshold--; diff --git a/AlientAttack.MonoGame/Things/Explosions/MineExplosion.cs b/AlientAttack.MonoGame/Things/Explosions/MineExplosion.cs new file mode 100644 index 0000000..1064a9c --- /dev/null +++ b/AlientAttack.MonoGame/Things/Explosions/MineExplosion.cs @@ -0,0 +1,11 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace AlienAttack.MonoGame.Things.Explosions; + +public class MineExplosion : Explosion +{ + public MineExplosion(int x, int y, float xVel, float yVel) : base(x, y, xVel, yVel) + { + Scale = new(2, 2); + } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/MiniExplosion.cs b/AlientAttack.MonoGame/Things/Explosions/MiniExplosion.cs similarity index 81% rename from AlientAttack.MonoGame/Things/MiniExplosion.cs rename to AlientAttack.MonoGame/Things/Explosions/MiniExplosion.cs index 686b45e..a18f7c8 100644 --- a/AlientAttack.MonoGame/Things/MiniExplosion.cs +++ b/AlientAttack.MonoGame/Things/Explosions/MiniExplosion.cs @@ -1,12 +1,12 @@ using Microsoft.Xna.Framework.Graphics; -namespace AlienAttack.MonoGame.Things; +namespace AlienAttack.MonoGame.Things.Explosions; public class MiniExplosion : MoveableSprite { protected int CurrentFrame { get; private set; } = 1; protected int MaxFrames => 9; - protected int AnimationThreshold => 3; //5; + protected int AnimationThreshold => 3; protected int CurrentThreshold { get; private set; } = 5; public MiniExplosion(int x, int y, float xVel, float yVel) : base(x, y) @@ -14,12 +14,13 @@ public class MiniExplosion : MoveableSprite Origin = new(32.5f, 32); XVelocity = xVel; YVelocity = yVel; + Scale = new(.25f, .25f); } public override void Draw(SpriteDrawArgs args) { - Texture2D texture = args.Content.Load(@$"Sprites\Explosion01_Frame_0{CurrentFrame}_png_processed"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, Origin, .25f, SpriteEffects.None, 1); + Texture2D texture = args.Content.Load(@$"Sprites\Explosion01_Frame_0{CurrentFrame}"); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, Origin, Scale, SpriteEffects.None, 1); base.Draw(args); } @@ -28,9 +29,6 @@ public class MiniExplosion : MoveableSprite { base.Update(context); - //XPosition += xVel; - //YPosition += yVel; - if (CurrentThreshold > 0) { CurrentThreshold--; diff --git a/AlientAttack.MonoGame/Things/Player.cs b/AlientAttack.MonoGame/Things/Player.cs index b9bb04a..b4fb4b5 100644 --- a/AlientAttack.MonoGame/Things/Player.cs +++ b/AlientAttack.MonoGame/Things/Player.cs @@ -151,7 +151,7 @@ public class Player : MoveableSprite Texture2D texture = args.Content.Load(@$"Sprites\PlayerRed_Frame_{frameNumber}"); //args.SpriteBatch.Draw(texture, Position, DrawColor); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, Origin, 1, spriteEffects, 1); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, Origin, Scale, spriteEffects, 1); base.Draw(args); } @@ -159,7 +159,7 @@ public class Player : MoveableSprite private void DrawExhaust(SpriteDrawArgs args) { Texture2D texture = args.Content.Load(@$"Sprites\Exhaust_Frame_0{CurrentExhaustFrame}_png_processed"); - args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, new Vector2(0, 0), 1, SpriteEffects.None, 1); + args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, Origin, Scale, SpriteEffects.None, 1); } private string GetPlayerTextureName() diff --git a/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs b/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs index c39490e..73dfad5 100644 --- a/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs +++ b/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs @@ -12,6 +12,7 @@ public class SpriteUpdateContext(AlienAttackGame game) public required Action SpawnSprite { get; init; } public required Random Random { get; init; } public required GameTime GameTime { get; init; } + public float DeltaTime => (float)GameTime.ElapsedGameTime.TotalSeconds; public required ContentManager Content { get; init; } public AudioManager AudioManager => game.Audio; public required Player Player { get; init; }