From e8e31bb143706a65dbda7c874ea7b405a00c2c07 Mon Sep 17 00:00:00 2001 From: Brian Bicknell Date: Sat, 3 Jan 2026 21:49:27 -0500 Subject: [PATCH] Added configurable weapons. --- AlientAttack.MonoGame/Hud/Hud.cs | 2 +- .../Things/Bullets/Bullet.cs | 9 +- .../Things/Bullets/BulletDef.cs | 11 ++ .../Things/Bullets/BulletDefinitions.cs | 100 ++++++++++++++++++ .../Things/Bullets/LaserBulletLarge.cs | 2 +- .../Things/Bullets/LaserBulletMedium.cs | 2 +- .../Things/Bullets/LaserBulletSmall.cs | 2 +- .../Things/Bullets/MinigunBulletLarge.cs | 2 +- .../Things/Bullets/MinigunBulletMedium.cs | 2 +- .../Things/Bullets/MinigunBulletSmall.cs | 2 +- .../Things/Bullets/PlasmaBulletLarge.cs | 2 +- .../Things/Bullets/PlasmaBulletMedium.cs | 2 +- .../Things/Bullets/PlasmaBulletSmall.cs | 2 +- .../Things/Bullets/ProtonBulletLarge.cs | 2 +- .../Things/Bullets/ProtonBulletMedium.cs | 2 +- .../Things/Bullets/ProtonBulletSmall.cs | 2 +- .../Things/Enemies/GreenEnemy.cs | 6 +- .../Things/Enemies/RedEnemy.cs | 3 +- .../Things/Enemies/TealEnemy.cs | 3 +- AlientAttack.MonoGame/Things/Explosion.cs | 2 +- AlientAttack.MonoGame/Things/Items/Ammo.cs | 7 +- AlientAttack.MonoGame/Things/Items/Energy.cs | 7 +- AlientAttack.MonoGame/Things/Items/Health.cs | 7 +- AlientAttack.MonoGame/Things/Items/Item.cs | 7 +- AlientAttack.MonoGame/Things/Items/Rockets.cs | 7 +- AlientAttack.MonoGame/Things/Items/Shields.cs | 7 +- AlientAttack.MonoGame/Things/MiniExplosion.cs | 2 +- AlientAttack.MonoGame/Things/Player.cs | 63 ++++++++++- .../Things/Weapons/ConfigurableWeapon.cs | 36 +++++++ .../Things/Weapons/FireBulletContext.cs | 4 +- .../Things/Weapons/Minigun.cs | 36 +++---- AlientAttack.MonoGame/Things/Weapons/Shot.cs | 6 ++ .../Things/Weapons/ShotPattern.cs | 6 ++ .../Things/Weapons/ShotPatterns.cs | 43 ++++++++ .../Things/Weapons/Weapon.cs | 3 +- .../Things/Weapons/WeaponDef.cs | 11 ++ .../Things/Weapons/WeaponState.cs | 8 ++ 37 files changed, 332 insertions(+), 88 deletions(-) create mode 100644 AlientAttack.MonoGame/Things/Bullets/BulletDef.cs create mode 100644 AlientAttack.MonoGame/Things/Bullets/BulletDefinitions.cs create mode 100644 AlientAttack.MonoGame/Things/Weapons/ConfigurableWeapon.cs create mode 100644 AlientAttack.MonoGame/Things/Weapons/Shot.cs create mode 100644 AlientAttack.MonoGame/Things/Weapons/ShotPattern.cs create mode 100644 AlientAttack.MonoGame/Things/Weapons/ShotPatterns.cs create mode 100644 AlientAttack.MonoGame/Things/Weapons/WeaponDef.cs create mode 100644 AlientAttack.MonoGame/Things/Weapons/WeaponState.cs diff --git a/AlientAttack.MonoGame/Hud/Hud.cs b/AlientAttack.MonoGame/Hud/Hud.cs index 7189acf..55c8ed8 100644 --- a/AlientAttack.MonoGame/Hud/Hud.cs +++ b/AlientAttack.MonoGame/Hud/Hud.cs @@ -11,7 +11,7 @@ public record DrawHudContext : DrawContext public int Shield; } -internal class Hud +public class Hud { private Texture2D _pixel; diff --git a/AlientAttack.MonoGame/Things/Bullets/Bullet.cs b/AlientAttack.MonoGame/Things/Bullets/Bullet.cs index f3e3694..6707eec 100644 --- a/AlientAttack.MonoGame/Things/Bullets/Bullet.cs +++ b/AlientAttack.MonoGame/Things/Bullets/Bullet.cs @@ -1,8 +1,11 @@ using AlienAttack.MonoGame.Things.Items; +using AlienAttack.MonoGame.Things.Muzzles; +using Microsoft.Xna.Framework; +using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class Bullet(float x, float y, float xVel, float yVel, Sprite owner) : Sprite(x, y) +public class Bullet(float x, float y, float xVel, float yVel, Sprite owner) : Sprite(x, y) { protected float XVelocity = xVel; protected float YVelocity = yVel; @@ -32,7 +35,9 @@ internal class Bullet(float x, float y, float xVel, float yVel, Sprite owner) : public override void OnCollision(SpriteCollisionContext context) { - if (context.Sprite is Bullet || context.Sprite == Owner || context.Sprite is Item) + Sprite sprite = context.Sprite; + + if (sprite is Bullet || sprite == Owner || sprite is Item || sprite is Explosion) return; IsDead = true; diff --git a/AlientAttack.MonoGame/Things/Bullets/BulletDef.cs b/AlientAttack.MonoGame/Things/Bullets/BulletDef.cs new file mode 100644 index 0000000..c503a89 --- /dev/null +++ b/AlientAttack.MonoGame/Things/Bullets/BulletDef.cs @@ -0,0 +1,11 @@ +using System; + +namespace AlienAttack.MonoGame.Things.Bullets; + +public sealed class BulletDef +{ + public required BulletKind Kind { get; init; } + public required int Width { get; init; } + public required int Height { get; init; } + public required Func Create { get; init; } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Bullets/BulletDefinitions.cs b/AlientAttack.MonoGame/Things/Bullets/BulletDefinitions.cs new file mode 100644 index 0000000..f065dee --- /dev/null +++ b/AlientAttack.MonoGame/Things/Bullets/BulletDefinitions.cs @@ -0,0 +1,100 @@ +namespace AlienAttack.MonoGame.Things.Bullets; + +public static class BulletDefinitions +{ + public static readonly BulletDef LaserSmall = new() + { + Kind = BulletKind.LaserSmall, + Width = LaserBulletSmall.Width, + Height = LaserBulletSmall.Height, + Create = (x, y, vx, vy, o) => new LaserBulletSmall(x, y, vx, vy, o), + }; + + public static readonly BulletDef LaserMedium = new() + { + Kind = BulletKind.LaserMedium, + Width = LaserBulletMedium.Width, + Height = LaserBulletMedium.Height, + Create = (x, y, vx, vy, o) => new LaserBulletMedium(x, y, vx, vy, o), + }; + + public static readonly BulletDef LaserLarge = new() + { + Kind = BulletKind.LaserLarge, + Width = LaserBulletLarge.Width, + Height = LaserBulletLarge.Height, + Create = (x, y, vx, vy, o) => new LaserBulletLarge(x, y, vx, vy, o), + }; + + public static readonly BulletDef MinigunSmall = new() + { + Kind = BulletKind.MinigunSmall, + Width = MinigunBulletSmall.Width, + Height = MinigunBulletSmall.Height, + Create = (x, y, vx, vy, o) => new MinigunBulletSmall(x, y, vx, vy, o), + }; + + public static readonly BulletDef MinigunMedium = new() + { + Kind = BulletKind.MinigunMedium, + Width = MinigunBulletMedium.Width, + Height = MinigunBulletMedium.Height, + Create = (x, y, vx, vy, o) => new MinigunBulletMedium(x, y, vx, vy, o), + }; + + public static readonly BulletDef MinigunLarge = new() + { + Kind = BulletKind.MinigunLarge, + Width = MinigunBulletLarge.Width, + Height = MinigunBulletLarge.Height, + Create = (x, y, vx, vy, o) => new MinigunBulletLarge(x, y, vx, vy, o), + }; + + public static readonly BulletDef PlasmaSmall = new() + { + Kind = BulletKind.PlasmaSmall, + Width = PlasmaBulletSmall.Width, + Height = PlasmaBulletSmall.Height, + Create = (x, y, vx, vy, o) => new PlasmaBulletSmall(x, y, vx, vy, o), + }; + + public static readonly BulletDef PlasmaMedium = new() + { + Kind = BulletKind.PlasmaMedium, + Width = PlasmaBulletMedium.Width, + Height = PlasmaBulletMedium.Height, + Create = (x, y, vx, vy, o) => new PlasmaBulletMedium(x, y, vx, vy, o), + }; + + public static readonly BulletDef PlasmaLarge = new() + { + Kind = BulletKind.PlasmaLarge, + Width = PlasmaBulletLarge.Width, + Height = PlasmaBulletLarge.Height, + Create = (x, y, vx, vy, o) => new PlasmaBulletLarge(x, y, vx, vy, o), + }; + + public static readonly BulletDef ProtonSmall = new() + { + Kind = BulletKind.ProtonSmall, + Width = ProtonBulletSmall.Width, + Height = ProtonBulletSmall.Height, + Create = (x, y, vx, vy, o) => new ProtonBulletSmall(x, y, vx, vy, o), + }; + + public static readonly BulletDef ProtonMedium = new() + { + Kind = BulletKind.ProtonMedium, + Width = ProtonBulletMedium.Width, + Height = ProtonBulletMedium.Height, + Create = (x, y, vx, vy, o) => new ProtonBulletMedium(x, y, vx, vy, o), + }; + + public static readonly BulletDef ProtonLarge = new() + { + Kind = BulletKind.ProtonLarge, + Width = ProtonBulletLarge.Width, + Height = ProtonBulletLarge.Height, + Create = (x, y, vx, vy, o) => new ProtonBulletLarge(x, y, vx, vy, o), + }; +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Bullets/LaserBulletLarge.cs b/AlientAttack.MonoGame/Things/Bullets/LaserBulletLarge.cs index aa63f2d..babc976 100644 --- a/AlientAttack.MonoGame/Things/Bullets/LaserBulletLarge.cs +++ b/AlientAttack.MonoGame/Things/Bullets/LaserBulletLarge.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class LaserBulletLarge : Bullet +public class LaserBulletLarge : Bullet { public const int Width = 8; public const int Height = 28; diff --git a/AlientAttack.MonoGame/Things/Bullets/LaserBulletMedium.cs b/AlientAttack.MonoGame/Things/Bullets/LaserBulletMedium.cs index fc41588..4e85fdc 100644 --- a/AlientAttack.MonoGame/Things/Bullets/LaserBulletMedium.cs +++ b/AlientAttack.MonoGame/Things/Bullets/LaserBulletMedium.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class LaserBulletMedium : Bullet +public class LaserBulletMedium : Bullet { public const int Width = 7; public const int Height = 21; diff --git a/AlientAttack.MonoGame/Things/Bullets/LaserBulletSmall.cs b/AlientAttack.MonoGame/Things/Bullets/LaserBulletSmall.cs index 73c55ba..d947575 100644 --- a/AlientAttack.MonoGame/Things/Bullets/LaserBulletSmall.cs +++ b/AlientAttack.MonoGame/Things/Bullets/LaserBulletSmall.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class LaserBulletSmall : Bullet +public class LaserBulletSmall : Bullet { public const int Width = 6; public const int Height = 18; diff --git a/AlientAttack.MonoGame/Things/Bullets/MinigunBulletLarge.cs b/AlientAttack.MonoGame/Things/Bullets/MinigunBulletLarge.cs index 4fdb62d..5df7885 100644 --- a/AlientAttack.MonoGame/Things/Bullets/MinigunBulletLarge.cs +++ b/AlientAttack.MonoGame/Things/Bullets/MinigunBulletLarge.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class MinigunBulletLarge : Bullet +public class MinigunBulletLarge : Bullet { public const int Width = 9; public const int Height = 27; diff --git a/AlientAttack.MonoGame/Things/Bullets/MinigunBulletMedium.cs b/AlientAttack.MonoGame/Things/Bullets/MinigunBulletMedium.cs index 564ee02..125f33f 100644 --- a/AlientAttack.MonoGame/Things/Bullets/MinigunBulletMedium.cs +++ b/AlientAttack.MonoGame/Things/Bullets/MinigunBulletMedium.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class MinigunBulletMedium : Bullet +public class MinigunBulletMedium : Bullet { public const int Width = 11; public const int Height = 21; diff --git a/AlientAttack.MonoGame/Things/Bullets/MinigunBulletSmall.cs b/AlientAttack.MonoGame/Things/Bullets/MinigunBulletSmall.cs index 1c3d101..764c62a 100644 --- a/AlientAttack.MonoGame/Things/Bullets/MinigunBulletSmall.cs +++ b/AlientAttack.MonoGame/Things/Bullets/MinigunBulletSmall.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class MinigunBulletSmall : Bullet +public class MinigunBulletSmall : Bullet { public const int Width = 11; public const int Height = 21; diff --git a/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletLarge.cs b/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletLarge.cs index 72c283f..533350f 100644 --- a/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletLarge.cs +++ b/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletLarge.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class PlasmaBulletLarge : Bullet +public class PlasmaBulletLarge : Bullet { public const int Width = 9; public const int Height = 31; diff --git a/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletMedium.cs b/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletMedium.cs index 506c43a..4235804 100644 --- a/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletMedium.cs +++ b/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletMedium.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class PlasmaBulletMedium : Bullet +public class PlasmaBulletMedium : Bullet { public const int Width = 8; public const int Height = 26; diff --git a/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletSmall.cs b/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletSmall.cs index 36a07af..36981e9 100644 --- a/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletSmall.cs +++ b/AlientAttack.MonoGame/Things/Bullets/PlasmaBulletSmall.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class PlasmaBulletSmall : Bullet +public class PlasmaBulletSmall : Bullet { public const int Width = 7; public const int Height = 24; diff --git a/AlientAttack.MonoGame/Things/Bullets/ProtonBulletLarge.cs b/AlientAttack.MonoGame/Things/Bullets/ProtonBulletLarge.cs index d244091..609dfc8 100644 --- a/AlientAttack.MonoGame/Things/Bullets/ProtonBulletLarge.cs +++ b/AlientAttack.MonoGame/Things/Bullets/ProtonBulletLarge.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class ProtonBulletLarge : Bullet +public class ProtonBulletLarge : Bullet { public const int Width = 13; public const int Height = 13; diff --git a/AlientAttack.MonoGame/Things/Bullets/ProtonBulletMedium.cs b/AlientAttack.MonoGame/Things/Bullets/ProtonBulletMedium.cs index a08a4d5..5033130 100644 --- a/AlientAttack.MonoGame/Things/Bullets/ProtonBulletMedium.cs +++ b/AlientAttack.MonoGame/Things/Bullets/ProtonBulletMedium.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class ProtonBulletMedium : Bullet +public class ProtonBulletMedium : Bullet { public const int Width = 10; public const int Height = 10; diff --git a/AlientAttack.MonoGame/Things/Bullets/ProtonBulletSmall.cs b/AlientAttack.MonoGame/Things/Bullets/ProtonBulletSmall.cs index 1b9bd56..e5b718a 100644 --- a/AlientAttack.MonoGame/Things/Bullets/ProtonBulletSmall.cs +++ b/AlientAttack.MonoGame/Things/Bullets/ProtonBulletSmall.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Bullets; -internal class ProtonBulletSmall : Bullet +public class ProtonBulletSmall : Bullet { public const int Width = 6; public const int Height = 6; diff --git a/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs b/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs index fde7551..3dd21cb 100644 --- a/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs +++ b/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs @@ -2,16 +2,12 @@ using AlienAttack.MonoGame.Things.Items; using AlienAttack.MonoGame.Things.Weapons; using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; -using System; using System.Collections.Generic; -using static System.Runtime.InteropServices.JavaScript.JSType; namespace AlienAttack.MonoGame.Things.Enemies; -internal class GreenEnemy : EnemyShip +public class GreenEnemy : EnemyShip { //Enemy01_Green_Frame_1_png_processed diff --git a/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs b/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs index ac54c3c..29b47b1 100644 --- a/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs +++ b/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs @@ -1,11 +1,10 @@ using AlienAttack.MonoGame.Things.Bullets; using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; namespace AlienAttack.MonoGame.Things.Enemies; -internal class RedEnemy : EnemyShip +public class RedEnemy : EnemyShip { protected int FireThreshold => 20; protected int CurrentFireThreshold { get; set; } = 20; diff --git a/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs b/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs index c0afc86..0fdb29f 100644 --- a/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs +++ b/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs @@ -1,11 +1,10 @@ using AlienAttack.MonoGame.Things.Bullets; using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; namespace AlienAttack.MonoGame.Things.Enemies; -internal class TealEnemy : EnemyShip +public class TealEnemy : EnemyShip { protected int FireThreshold => 20; protected int CurrentFireThreshold { get; set; } = 20; diff --git a/AlientAttack.MonoGame/Things/Explosion.cs b/AlientAttack.MonoGame/Things/Explosion.cs index 620f906..3d0be80 100644 --- a/AlientAttack.MonoGame/Things/Explosion.cs +++ b/AlientAttack.MonoGame/Things/Explosion.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics; namespace AlienAttack.MonoGame.Things; -internal class Explosion(int x, int y, float xVel, float yVel) : Sprite(x, y) +public class Explosion(int x, int y, float xVel, float yVel) : Sprite(x, y) { protected int CurrentFrame { get; private set; } = 1; protected int MaxFrames => 9; diff --git a/AlientAttack.MonoGame/Things/Items/Ammo.cs b/AlientAttack.MonoGame/Things/Items/Ammo.cs index f774631..5386ace 100644 --- a/AlientAttack.MonoGame/Things/Items/Ammo.cs +++ b/AlientAttack.MonoGame/Things/Items/Ammo.cs @@ -1,6 +1,6 @@ namespace AlienAttack.MonoGame.Things.Items; -internal class Ammo : Item +public class Ammo : Item { protected override PickupKind Kind => PickupKind.Ammo; @@ -8,9 +8,4 @@ internal class Ammo : Item { TextureName = @$"Sprites\Powerup_Ammo"; } - - protected override void ApplyEffect(Player player) - { - - } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Items/Energy.cs b/AlientAttack.MonoGame/Things/Items/Energy.cs index 393a1b7..c821dc0 100644 --- a/AlientAttack.MonoGame/Things/Items/Energy.cs +++ b/AlientAttack.MonoGame/Things/Items/Energy.cs @@ -1,6 +1,6 @@ namespace AlienAttack.MonoGame.Things.Items; -internal class Energy : Item +public class Energy : Item { protected override PickupKind Kind => PickupKind.Plasma; @@ -8,9 +8,4 @@ internal class Energy : Item { TextureName = @$"Sprites\Powerup_Energy"; } - - protected override void ApplyEffect(Player player) - { - - } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Items/Health.cs b/AlientAttack.MonoGame/Things/Items/Health.cs index eb9934f..04d2eff 100644 --- a/AlientAttack.MonoGame/Things/Items/Health.cs +++ b/AlientAttack.MonoGame/Things/Items/Health.cs @@ -1,6 +1,6 @@ namespace AlienAttack.MonoGame.Things.Items; -internal class Health : Item +public class Health : Item { protected override PickupKind Kind => PickupKind.Health; @@ -8,9 +8,4 @@ internal class Health : Item { TextureName = @$"Sprites\Powerup_Health"; } - - protected override void ApplyEffect(Player player) - { - - } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Items/Item.cs b/AlientAttack.MonoGame/Things/Items/Item.cs index 2c87a82..aeeafa0 100644 --- a/AlientAttack.MonoGame/Things/Items/Item.cs +++ b/AlientAttack.MonoGame/Things/Items/Item.cs @@ -4,7 +4,7 @@ using System; namespace AlienAttack.MonoGame.Things.Items; -internal abstract class Item : MoveableSprite +public abstract class Item : MoveableSprite { private Vector2 _anchor; // the "center" the item orbits around private float _t; // radians @@ -59,13 +59,10 @@ internal abstract class Item : MoveableSprite public override void OnCollision(SpriteCollisionContext context) { - if (context.Sprite is Player player) + if (context.Sprite is Player) { IsDead = true; - ApplyEffect(player); context.AudioManager.PlayPickup(Kind); } } - - protected abstract void ApplyEffect(Player player); } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Items/Rockets.cs b/AlientAttack.MonoGame/Things/Items/Rockets.cs index 412d41b..d217710 100644 --- a/AlientAttack.MonoGame/Things/Items/Rockets.cs +++ b/AlientAttack.MonoGame/Things/Items/Rockets.cs @@ -1,6 +1,6 @@ namespace AlienAttack.MonoGame.Things.Items; -internal class Rockets : Item +public class Rockets : Item { protected override PickupKind Kind => PickupKind.Rockets; @@ -8,9 +8,4 @@ internal class Rockets : Item { TextureName = @$"Sprites\Powerup_Rockets"; } - - protected override void ApplyEffect(Player player) - { - - } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Items/Shields.cs b/AlientAttack.MonoGame/Things/Items/Shields.cs index 691f509..25284fd 100644 --- a/AlientAttack.MonoGame/Things/Items/Shields.cs +++ b/AlientAttack.MonoGame/Things/Items/Shields.cs @@ -1,6 +1,6 @@ namespace AlienAttack.MonoGame.Things.Items; -internal class Shields : Item +public class Shields : Item { protected override PickupKind Kind => PickupKind.Shield; @@ -8,9 +8,4 @@ internal class Shields : Item { TextureName = @$"Sprites\Powerup_Shields"; } - - protected override void ApplyEffect(Player player) - { - - } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/MiniExplosion.cs b/AlientAttack.MonoGame/Things/MiniExplosion.cs index 3e94f01..e187fa5 100644 --- a/AlientAttack.MonoGame/Things/MiniExplosion.cs +++ b/AlientAttack.MonoGame/Things/MiniExplosion.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics; namespace AlienAttack.MonoGame.Things; -internal class MiniExplosion(int x, int y, float xVel, float yVel) : Sprite(x, y) +public class MiniExplosion(int x, int y, float xVel, float yVel) : Sprite(x, y) { protected int CurrentFrame { get; private set; } = 1; protected int MaxFrames => 9; diff --git a/AlientAttack.MonoGame/Things/Player.cs b/AlientAttack.MonoGame/Things/Player.cs index 7aa03b3..68e1d2c 100644 --- a/AlientAttack.MonoGame/Things/Player.cs +++ b/AlientAttack.MonoGame/Things/Player.cs @@ -8,10 +8,11 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; using System.Collections.Generic; +using System.Linq; namespace AlienAttack.MonoGame.Things; -internal enum PlayerHorizontalMoveState +public enum PlayerHorizontalMoveState { None, Left, @@ -19,7 +20,7 @@ internal enum PlayerHorizontalMoveState } [Flags] -internal enum MoveFlag +public enum MoveFlag { None = 0, Left = 1, @@ -34,7 +35,7 @@ public class DrwaState } -internal class Player : MoveableSprite +public class Player : MoveableSprite { protected PlayerHorizontalMoveState MoveState = PlayerHorizontalMoveState.None; protected MoveFlag MoveFlags; @@ -61,10 +62,64 @@ internal class Player : MoveableSprite { BoundBox = new Rectangle(0, 0, 64, 64); //ActiveWeapons.Add(new Minigun()); - ActiveWeapons.Add(new MinigunTripleSpreadFast()); + //ActiveWeapons.Add(new MinigunTripleSpreadFast()); //ActiveWeapons.Add(new MinigunSpread()); Health = 100; Shield = 100; + + // Weapon 1 + WeaponDef weaponDef = new() + { + Name = "Weapon 1", + Bullet = BulletDefinitions.LaserLarge, + Pattern = ShotPatterns.TripleSpread, + FireSfxKey = "" + }; + + WeaponState weasponState = new() + { + FireThreshold = 15, + SpeedMultiplier = 1, + DamageBonus = 0 + }; + + ConfigurableWeapon configurableWeapon = new(weaponDef, weasponState); + + // Weapon 2 + //WeaponDef weaponDef2 = new() + //{ + // Name = "Weapon 2", + // Bullet = BulletDefinitions.MinigunSmall, + // Pattern = ShotPatterns.Single, + // FireSfxKey = "" + //}; + + //WeaponState weasponState2 = new() + //{ + // FireThreshold = 20, + // SpeedMultiplier = 2f, + // DamageBonus = 0 + //}; + + //ConfigurableWeapon configurableWeapon2 = new(weaponDef2, weasponState2); + + ActiveWeapons.Add(configurableWeapon); + //ActiveWeapons.Add(configurableWeapon2); + } + + public Vector2 GetMuzzleLocal(MuzzleId muzzle) + { + switch (muzzle) + { + case MuzzleId.Center: + return Muzzles[0].LocalPx; + case MuzzleId.Left: + return Muzzles[1].LocalPx; + case MuzzleId.Right: + return Muzzles[2].LocalPx; + } + + return new(); } //Texture2D texture = Game diff --git a/AlientAttack.MonoGame/Things/Weapons/ConfigurableWeapon.cs b/AlientAttack.MonoGame/Things/Weapons/ConfigurableWeapon.cs new file mode 100644 index 0000000..b015057 --- /dev/null +++ b/AlientAttack.MonoGame/Things/Weapons/ConfigurableWeapon.cs @@ -0,0 +1,36 @@ +using AlienAttack.MonoGame.Things.Muzzles; + +namespace AlienAttack.MonoGame.Things.Weapons; + +public class ConfigurableWeapon(WeaponDef def, WeaponState state) : Weapon +{ + public override int FireThreshold => state.FireThreshold; + + public override void Fire(Sprite owner, SpriteUpdateContext context) + { + if (owner is not Player player) return; + + foreach (var shot in def.Pattern.Shots) + { + // muzzle local -> world + var muzzleLocal = player.GetMuzzleLocal(shot.Muzzle); // make a fast lookup + var muzzleWorld = MuzzleMath.GetMuzzleWorld(player, muzzleLocal); + + // speed upgrade + float vx = shot.Velocity.X * state.SpeedMultiplier; + float vy = shot.Velocity.Y * state.SpeedMultiplier; + + // center bullet on muzzle + pattern offset + var pos = MuzzleMath.CenterBulletOn(muzzleWorld, def.Bullet.Width, def.Bullet.Height) + shot.Offset; + + var bullet = def.Bullet.Create(pos.X, pos.Y, vx, vy, owner); + + // optional: apply damage bonus generically + //bullet.Damage += state.DamageBonus; + + context.SpawnSprite(bullet); + } + + context.AudioManager.PlayPlayerFire(); // or use _def.FireSfxKey -> audio routing + } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Weapons/FireBulletContext.cs b/AlientAttack.MonoGame/Things/Weapons/FireBulletContext.cs index 393ed11..43e52b2 100644 --- a/AlientAttack.MonoGame/Things/Weapons/FireBulletContext.cs +++ b/AlientAttack.MonoGame/Things/Weapons/FireBulletContext.cs @@ -5,7 +5,7 @@ using System; namespace AlienAttack.MonoGame.Things.Weapons; -internal record FireBulletContext +public record FireBulletContext { public Sprite Owner { get; init; } public SpriteUpdateContext SpriteUpdateContext { get; init; } @@ -24,7 +24,7 @@ public record Shot public float YVelocity { get; init; } } -internal record FireBulletFromMuzzleContext +public record FireBulletFromMuzzleContext { public Sprite Owner { get; init; } public SpriteUpdateContext SpriteUpdateContext { get; init; } diff --git a/AlientAttack.MonoGame/Things/Weapons/Minigun.cs b/AlientAttack.MonoGame/Things/Weapons/Minigun.cs index 48107c3..6c0e025 100644 --- a/AlientAttack.MonoGame/Things/Weapons/Minigun.cs +++ b/AlientAttack.MonoGame/Things/Weapons/Minigun.cs @@ -3,7 +3,7 @@ using AlienAttack.MonoGame.Things.Muzzles; namespace AlienAttack.MonoGame.Things.Weapons; -internal class Minigun : Weapon +public class Minigun : Weapon { public override int FireThreshold => 15; @@ -26,7 +26,7 @@ internal class Minigun : Weapon } } -internal abstract class MinigunSingle : Weapon +public abstract class MinigunSingle : Weapon { public override void Fire(Sprite owner, SpriteUpdateContext context) { @@ -50,23 +50,23 @@ internal abstract class MinigunSingle : Weapon } } -internal class MinigunSingleSlow : MinigunSingle +public class MinigunSingleSlow : MinigunSingle { public override int FireThreshold => 20; } -internal class MinigunSingleAverage : MinigunSingle +public class MinigunSingleAverage : MinigunSingle { public override int FireThreshold => 15; } -internal class MinigunSingleFast : MinigunSingle +public class MinigunSingleFast : MinigunSingle { public override int FireThreshold => 10; } -internal abstract class MinigunDouble : Weapon +public abstract class MinigunDouble : Weapon { public override void Fire(Sprite owner, SpriteUpdateContext context) { @@ -91,23 +91,22 @@ internal abstract class MinigunDouble : Weapon } } -internal class MinigunDoubleSlow : MinigunDouble +public class MinigunDoubleSlow : MinigunDouble { public override int FireThreshold => 30; } -internal class MinigunDoubleAverage : MinigunDouble +public class MinigunDoubleAverage : MinigunDouble { public override int FireThreshold => 20; } - -internal class MinigunDoubleFast : MinigunDouble +public class MinigunDoubleFast : MinigunDouble { public override int FireThreshold => 15; } -internal abstract class MinigunTriple : Weapon +public abstract class MinigunTriple : Weapon { public override void Fire(Sprite owner, SpriteUpdateContext context) { @@ -133,23 +132,22 @@ internal abstract class MinigunTriple : Weapon } } -internal class MinigunTripleSlow : MinigunTriple +public class MinigunTripleSlow : MinigunTriple { public override int FireThreshold => 30; } -internal class MinigunTripleAverage : MinigunTriple +public class MinigunTripleAverage : MinigunTriple { public override int FireThreshold => 20; } - -internal class MinigunTripleFast : MinigunTriple +public class MinigunTripleFast : MinigunTriple { public override int FireThreshold => 15; } -internal abstract class MinigunTripleSpread : Weapon +public abstract class MinigunTripleSpread : Weapon { public override void Fire(Sprite owner, SpriteUpdateContext context) { @@ -175,18 +173,18 @@ internal abstract class MinigunTripleSpread : Weapon } } -internal class MinigunTripleSpreadSlow : MinigunTripleSpread +public class MinigunTripleSpreadSlow : MinigunTripleSpread { public override int FireThreshold => 30; } -internal class MinigunTripleSpreadAverage : MinigunTripleSpread +public class MinigunTripleSpreadAverage : MinigunTripleSpread { public override int FireThreshold => 20; } -internal class MinigunTripleSpreadFast : MinigunTripleSpread +public class MinigunTripleSpreadFast : MinigunTripleSpread { public override int FireThreshold => 15; } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Weapons/Shot.cs b/AlientAttack.MonoGame/Things/Weapons/Shot.cs new file mode 100644 index 0000000..dca3cce --- /dev/null +++ b/AlientAttack.MonoGame/Things/Weapons/Shot.cs @@ -0,0 +1,6 @@ +using AlienAttack.MonoGame.Things.Muzzles; +using Microsoft.Xna.Framework; + +namespace AlienAttack.MonoGame.Things.Weapons; + +public readonly record struct Shot2(MuzzleId Muzzle, Vector2 Velocity, Vector2 Offset); \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Weapons/ShotPattern.cs b/AlientAttack.MonoGame/Things/Weapons/ShotPattern.cs new file mode 100644 index 0000000..5cd32a4 --- /dev/null +++ b/AlientAttack.MonoGame/Things/Weapons/ShotPattern.cs @@ -0,0 +1,6 @@ +namespace AlienAttack.MonoGame.Things.Weapons; + +public sealed class ShotPattern +{ + public required Shot2[] Shots { get; init; } +} diff --git a/AlientAttack.MonoGame/Things/Weapons/ShotPatterns.cs b/AlientAttack.MonoGame/Things/Weapons/ShotPatterns.cs new file mode 100644 index 0000000..72bae3a --- /dev/null +++ b/AlientAttack.MonoGame/Things/Weapons/ShotPatterns.cs @@ -0,0 +1,43 @@ +using AlienAttack.MonoGame.Things.Muzzles; +using Microsoft.Xna.Framework; + +namespace AlienAttack.MonoGame.Things.Weapons; + +public static class ShotPatterns +{ + public static readonly ShotPattern Single = new() + { + Shots = + [ + new Shot2(MuzzleId.Center, new Vector2(0, -6), new Vector2(4, 0)) + ] + }; + + public static readonly ShotPattern Double = new() + { + Shots = + [ + new Shot2(MuzzleId.Left, new Vector2(0, -6), new Vector2(4, 0)), + new Shot2(MuzzleId.Right, new Vector2(0, -6), new Vector2(4, 0)) + ] + }; + + public static readonly ShotPattern DoubleSpread = new() + { + Shots = + [ + new Shot2(MuzzleId.Left, new Vector2(-1, -6), new Vector2(4, 0)), + new Shot2(MuzzleId.Right, new Vector2(1, -6), new Vector2(4, 0)) + ] + }; + + public static readonly ShotPattern TripleSpread = new() + { + Shots = + [ + new Shot2(MuzzleId.Left, new Vector2(-1, -6), new Vector2(4, 0)), + new Shot2(MuzzleId.Center, new Vector2(0, -6), new Vector2(4, 0)), + new Shot2(MuzzleId.Right, new Vector2(1, -6), new Vector2(4, 0)) + ] + }; +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Weapons/Weapon.cs b/AlientAttack.MonoGame/Things/Weapons/Weapon.cs index 9a2e8db..457b4a8 100644 --- a/AlientAttack.MonoGame/Things/Weapons/Weapon.cs +++ b/AlientAttack.MonoGame/Things/Weapons/Weapon.cs @@ -1,12 +1,11 @@ using AlienAttack.MonoGame.Things.Bullets; using AlienAttack.MonoGame.Things.Muzzles; using Microsoft.Xna.Framework; -using System; using System.Linq; namespace AlienAttack.MonoGame.Things.Weapons; -internal abstract class Weapon : IWeapon +public abstract class Weapon : IWeapon { public abstract int FireThreshold { get; } public int CurrentFireThreshold { get; private set; } diff --git a/AlientAttack.MonoGame/Things/Weapons/WeaponDef.cs b/AlientAttack.MonoGame/Things/Weapons/WeaponDef.cs new file mode 100644 index 0000000..fdd003d --- /dev/null +++ b/AlientAttack.MonoGame/Things/Weapons/WeaponDef.cs @@ -0,0 +1,11 @@ +using AlienAttack.MonoGame.Things.Bullets; + +namespace AlienAttack.MonoGame.Things.Weapons; + +public sealed class WeaponDef +{ + public required string Name { get; init; } + public required ShotPattern Pattern { get; init; } + public required BulletDef Bullet { get; init; } + public required string FireSfxKey { get; init; } = "player_fire"; +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Weapons/WeaponState.cs b/AlientAttack.MonoGame/Things/Weapons/WeaponState.cs new file mode 100644 index 0000000..a38ae8d --- /dev/null +++ b/AlientAttack.MonoGame/Things/Weapons/WeaponState.cs @@ -0,0 +1,8 @@ +namespace AlienAttack.MonoGame.Things.Weapons; + +public sealed class WeaponState +{ + public int FireThreshold { get; set; } + public float SpeedMultiplier { get; set; } = 1f; + public int DamageBonus { get; set; } = 0; +} \ No newline at end of file