Updated weapon logic. Fixed player CheckMove logic.

This commit is contained in:
2026-08-24 19:46:04 -04:00
parent c1124a784d
commit e42b11c6fc
10 changed files with 279 additions and 73 deletions

View File

@@ -19,6 +19,10 @@ public abstract class Mine : MoveableSprite
protected float RotationSpeed { get; set; } = 1.5f;
protected double DistanceToPlayer { get; set; } = double.MaxValue;
private MineState State { get; set; } = MineState.Drifting;
private Vector2? CurrentTarget { get; set; }
public Mine(int x, int y) : base(x, y)
{
Origin = new(30, 33);
@@ -77,6 +81,19 @@ public abstract class Mine : MoveableSprite
}
Rotation = MathHelper.WrapAngle(Rotation + RotationSpeed * context.DeltaTime);
switch (State)
{
case MineState:
default:
break;
}
}
protected void Charge(Vector2 target)
{
State = MineState.Charging;
CurrentTarget = target;
}
private void UpdateDistanceToPlayer(SpriteUpdateContext context)

View File

@@ -0,0 +1,7 @@
namespace AlienAttack.MonoGame.Things.Enemies.Mines;
public enum MineState
{
Drifting,
Charging
}

View File

@@ -20,7 +20,25 @@ public class GreenShipTypeA : ShipTypeA
{
BoundBox = new Rectangle(0, 0, 64, 64);
YVelocity = 1;
ActiveWeapons.Add(new Minigun());
WeaponDef weaponDef = new()
{
Name = "Weapon 1",
Bullet = BulletDefinitions.MinigunSmall,
Pattern = ShotPatterns.ReverseDouble,
FireSfxKey = ""
};
WeaponState weasponState = new()
{
FireThreshold = 20,
SpeedMultiplier = 1f,
DamageBonus = 0
};
ConfigurableWeapon configurableWeapon = new(weaponDef, weasponState);
ActiveWeapons.Add(configurableWeapon);
//ActiveWeapons.Add(new FastMinigun());
}
@@ -36,21 +54,34 @@ public class GreenShipTypeA : ShipTypeA
protected override void TryFire(SpriteUpdateContext context)
{
if (CurrentFireThreshold > 0)
//if (CurrentFireThreshold > 0)
//{
// CurrentFireThreshold--;
//}
//if (CurrentFireThreshold == 0 && context.Random.Next(0, 100) == 1)
//{
// float originX = XPosition + (BoundBox.Width / 2) - (7 / 2);
// context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
// context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
// CurrentFireThreshold = FireThreshold;
// context.AudioManager.PlayEnemyFire();
//}
foreach (IWeapon weapon in ActiveWeapons)
{
CurrentFireThreshold--;
weapon.UpdateFireThreshold();
}
if (CurrentFireThreshold == 0 && context.Random.Next(0, 100) == 1)
if (context.Random.Next(0, 100) != 1)
return;
foreach (IWeapon weapon in ActiveWeapons)
{
float originX = XPosition + (BoundBox.Width / 2) - (7 / 2);
context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
CurrentFireThreshold = FireThreshold;
context.AudioManager.PlayEnemyFire();
weapon.TryFire(this, context);
}
}

View File

@@ -1,6 +1,8 @@
using AlienAttack.MonoGame.Things.Bullets;
using AlienAttack.MonoGame.Things.Weapons;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeA;
@@ -9,11 +11,31 @@ public class RedShipTypeA : ShipTypeA
protected int FireThreshold => 20;
protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5;
protected ICollection<IWeapon> ActiveWeapons = [];
public RedShipTypeA(int x, int y) : base(x, y)
{
BoundBox = new Rectangle(0, 0, 64, 64);
YVelocity = 1.5f;
WeaponDef weaponDef = new()
{
Name = "Weapon 1",
Bullet = BulletDefinitions.MinigunSmall,
Pattern = ShotPatterns.ReverseTripleSpread,
FireSfxKey = ""
};
WeaponState weasponState = new()
{
FireThreshold = 20,
SpeedMultiplier = 1f,
DamageBonus = 0
};
ConfigurableWeapon configurableWeapon = new(weaponDef, weasponState);
ActiveWeapons.Add(configurableWeapon);
}
public override void Draw(SpriteDrawArgs args)
@@ -53,22 +75,35 @@ public class RedShipTypeA : ShipTypeA
protected override void TryFire(SpriteUpdateContext context)
{
if (CurrentFireThreshold > 0)
//if (CurrentFireThreshold > 0)
//{
// CurrentFireThreshold--;
//}
//if (CurrentFireThreshold == 0 && context.Random.Next(0, 50) == 1)
//{
// float originX = XPosition + (BoundBox.Width / 2) - (7 / 2);
// context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, -1, 2 + YVelocity, this));
// context.SpawnSprite(new MinigunBulletSmall(originX + 3, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
// context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 1, 2 + YVelocity, this));
// CurrentFireThreshold = FireThreshold;
// context.AudioManager.PlayEnemyFire();
//}
foreach (IWeapon weapon in ActiveWeapons)
{
CurrentFireThreshold--;
weapon.UpdateFireThreshold();
}
if (CurrentFireThreshold == 0 && context.Random.Next(0, 50) == 1)
if (context.Random.Next(0, 50) != 1)
return;
foreach (IWeapon weapon in ActiveWeapons)
{
float originX = XPosition + (BoundBox.Width / 2) - (7 / 2);
context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, -1, 2 + YVelocity, this));
context.SpawnSprite(new MinigunBulletSmall(originX + 3, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 1, 2 + YVelocity, this));
CurrentFireThreshold = FireThreshold;
context.AudioManager.PlayEnemyFire();
weapon.TryFire(this, context);
}
}
}

View File

@@ -1,6 +1,8 @@
using AlienAttack.MonoGame.Things.Bullets;
using AlienAttack.MonoGame.Things.Weapons;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeA;
@@ -9,12 +11,32 @@ public class TealShipTypeA : ShipTypeA
protected int FireThreshold => 20;
protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5;
protected ICollection<IWeapon> ActiveWeapons = [];
public TealShipTypeA(int x, int y) : base(x, y)
{
BoundBox = new Rectangle(0, 0, 64, 64);
YVelocity = 1;
XVelocity = 3;
WeaponDef weaponDef = new()
{
Name = "Weapon 1",
Bullet = BulletDefinitions.ProtonLarge,
Pattern = ShotPatterns.ReverseTripleSpread,
FireSfxKey = ""
};
WeaponState weasponState = new()
{
FireThreshold = 20,
SpeedMultiplier = 1f,
DamageBonus = 0
};
ConfigurableWeapon configurableWeapon = new(weaponDef, weasponState);
ActiveWeapons.Add(configurableWeapon);
}
public override void Draw(SpriteDrawArgs args)
@@ -45,25 +67,38 @@ public class TealShipTypeA : ShipTypeA
protected override void TryFire(SpriteUpdateContext context)
{
if (CurrentFireThreshold > 0)
//if (CurrentFireThreshold > 0)
//{
// CurrentFireThreshold--;
//}
//if (CurrentFireThreshold == 0 && context.Random.Next(0, 50) == 1)
//{
// float originX = XPosition + (BoundBox.Width / 2) - (7 / 2);
// //context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
// //context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
// context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, -1, 2 + YVelocity, this));
// context.SpawnSprite(new MinigunBulletSmall(originX + 3, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
// context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 1, 2 + YVelocity, this));
// CurrentFireThreshold = FireThreshold;
// context.AudioManager.PlayEnemyFire();
//}
foreach (IWeapon weapon in ActiveWeapons)
{
CurrentFireThreshold--;
weapon.UpdateFireThreshold();
}
if (CurrentFireThreshold == 0 && context.Random.Next(0, 50) == 1)
if (context.Random.Next(0, 50) != 1)
return;
foreach (IWeapon weapon in ActiveWeapons)
{
float originX = XPosition + (BoundBox.Width / 2) - (7 / 2);
//context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
//context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
context.SpawnSprite(new MinigunBulletSmall(originX - 9, YPosition + BoundBox.Height - 12, -1, 2 + YVelocity, this));
context.SpawnSprite(new MinigunBulletSmall(originX + 3, YPosition + BoundBox.Height - 12, 0, 2 + YVelocity, this));
context.SpawnSprite(new MinigunBulletSmall(originX + 14, YPosition + BoundBox.Height - 12, 1, 2 + YVelocity, this));
CurrentFireThreshold = FireThreshold;
context.AudioManager.PlayEnemyFire();
weapon.TryFire(this, context);
}
}
}

View File

@@ -36,7 +36,7 @@ public record DrawState
public SpriteEffects SpriteEffects { get; init; }
}
public class Player : MoveableSprite
public class Player : Ship
{
protected PlayerHorizontalMoveState MoveState = PlayerHorizontalMoveState.None;
protected MoveFlag MoveFlags;
@@ -125,7 +125,7 @@ public class Player : MoveableSprite
//ActiveWeapons.Add(configurableWeapon2);
}
public Vector2 GetMuzzleLocal(MuzzleId muzzle)
public override Vector2 GetMuzzleLocal(MuzzleId muzzle)
{
switch (muzzle)
{
@@ -283,24 +283,24 @@ public class Player : MoveableSprite
XVelocity *= 1.5f;
}
if (XPosition < 0)
if (XPosition - Origin.X < 0)
{
XPosition = 0;
XPosition = 0 + Origin.X;
}
if (XPosition + BoundBox.Width > context.ViewTransform.ScreenWidth)
if (XPosition + BoundBox.Width - Origin.X > context.ViewTransform.ScreenWidth)
{
XPosition = context.ViewTransform.ScreenWidth - BoundBox.Width;
XPosition = context.ViewTransform.ScreenWidth - BoundBox.Width + Origin.X;
}
if (YPosition < 0)
if (YPosition - Origin.Y < 0)
{
YPosition = 0;
YPosition = 0 + Origin.Y;
}
if (YPosition + BoundBox.Height > context.ViewTransform.ScreenHeight)
if (YPosition + BoundBox.Height - Origin.Y > context.ViewTransform.ScreenHeight)
{
YPosition = context.ViewTransform.ScreenHeight - BoundBox.Height;
YPosition = context.ViewTransform.ScreenHeight - BoundBox.Height + Origin.Y;
}
}

View File

@@ -1,4 +1,5 @@
using AlienAttack.MonoGame.Things.Muzzles;
using AlienAttack.MonoGame.Things.Enemies.Ships;
using AlienAttack.MonoGame.Things.Muzzles;
namespace AlienAttack.MonoGame.Things.Weapons;
@@ -8,13 +9,13 @@ public class ConfigurableWeapon(WeaponDef def, WeaponState state) : Weapon
public override void Fire(Sprite owner, SpriteUpdateContext context)
{
if (owner is not Player player) return;
if (owner is not Ship ship) 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);
var muzzleLocal = ship.GetMuzzleLocal(shot.Muzzle); // make a fast lookup
var muzzleWorld = MuzzleMath.GetMuzzleWorld(ship, muzzleLocal);
// speed upgrade
float vx = shot.Velocity.X * state.SpeedMultiplier;
@@ -32,6 +33,14 @@ public class ConfigurableWeapon(WeaponDef def, WeaponState state) : Weapon
}
//context.AudioManager.PlayPlayerFire(); // or use _def.FireSfxKey -> audio routing
context.AudioManager.PlayPlayerFire(def.Bullet.Kind);
if (owner is Player)
{
context.AudioManager.PlayPlayerFire(def.Bullet.Kind);
}
else
{
context.AudioManager.PlayEnemyFire(def.Bullet.Kind);
}
}
}

View File

@@ -40,4 +40,40 @@ public static class ShotPatterns
new Shot2(MuzzleId.Right, new Vector2(1, -6), new Vector2(4, 0))
]
};
public static readonly ShotPattern ReverseSingle = new()
{
Shots =
[
new Shot2(MuzzleId.Center, new Vector2(0, 6), new Vector2(4, 0))
]
};
public static readonly ShotPattern ReverseDouble = 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 ReverseDoubleSpread = 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 ReverseTripleSpread = 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))
]
};
}