Updated asteroids and mines. Updated ship class names. Added initial ship muzzle logic.

This commit is contained in:
2026-01-20 00:40:03 -05:00
parent e402c498d6
commit c1124a784d
15 changed files with 221 additions and 97 deletions

View File

@@ -330,43 +330,43 @@ internal class GameLoop : GameLoopBase
{ {
int randomNumber = _random.Next(0, 100); int randomNumber = _random.Next(0, 100);
if (randomNumber == 0) //if (randomNumber == 0)
{ //{
GreenEnemy enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64); // GreenEnemy enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 1) //else if (randomNumber == 1)
{ //{
RedEnemy enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64); // RedEnemy enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 2) //else if (randomNumber == 2)
{ //{
TealEnemy enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64); // TealEnemy enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 3) //else if (randomNumber == 3)
{ //{
Enemy02Green enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64); // Enemy02Green enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 4) //else if (randomNumber == 4)
{ //{
Enemy02Red enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64); // Enemy02Red enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 5) //else if (randomNumber == 5)
{ //{
Enemy02Teal enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64); // Enemy02Teal enemy = new(_random.Next(0, ViewTransform.ScreenWidth - 64), -64);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 6) if (randomNumber == 6)
{ {
GreenMine enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Mine.Width), -Mine.Height); GreenMine enemy = new(_random.Next(0, ViewTransform.ScreenWidth - Mine.Width), -Mine.Height);
Sprites.Add(enemy); Sprites.Add(enemy);
@@ -408,30 +408,30 @@ internal class GameLoop : GameLoopBase
// Sprites.Add(enemy); // Sprites.Add(enemy);
// _spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
//} //}
else if (randomNumber == 13) //else if (randomNumber == 13)
{ //{
AsteroidVariantA enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantA.Width), -AsteroidVariantA.Height); // AsteroidVariantA enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantA.Width), -AsteroidVariantA.Height);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 14) //else if (randomNumber == 14)
{ //{
AsteroidVariantB enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantB.Width), -AsteroidVariantB.Height); // AsteroidVariantB enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantB.Width), -AsteroidVariantB.Height);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 15) //else if (randomNumber == 15)
{ //{
AsteroidVariantC enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantC.Width), -AsteroidVariantC.Height); // AsteroidVariantC enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantC.Width), -AsteroidVariantC.Height);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
else if (randomNumber == 16) //else if (randomNumber == 16)
{ //{
AsteroidVariantD enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantD.Width), -AsteroidVariantD.Height); // AsteroidVariantD enemy = new(_random.Next(0, ViewTransform.ScreenWidth - AsteroidVariantD.Width), -AsteroidVariantD.Height);
Sprites.Add(enemy); // Sprites.Add(enemy);
_spawnNewEnemyThreshold = 100 + _random.Next(0, 100); // _spawnNewEnemyThreshold = 100 + _random.Next(0, 100);
} //}
} }
} }
} }

View File

@@ -16,5 +16,6 @@ public class AsteroidVariantB : Asteroid
BoundBox = new(0, 0, Width, Height); BoundBox = new(0, 0, Width, Height);
YVelocity = 2; YVelocity = 2;
XVelocity = 0; XVelocity = 0;
RotationSpeed = 4f;
} }
} }

View File

@@ -16,5 +16,6 @@ public class AsteroidVariantD : Asteroid
BoundBox = new(0, 0, Width, Height); BoundBox = new(0, 0, Width, Height);
YVelocity = .5f; YVelocity = .5f;
XVelocity = 0; XVelocity = 0;
RotationSpeed = .5f;
} }
} }

View File

@@ -1,8 +1,98 @@
namespace AlienAttack.MonoGame.Things.Enemies.Mines; using Microsoft.Xna.Framework;
using System;
namespace AlienAttack.MonoGame.Things.Enemies.Mines;
public class BlueMine(int x, int y) : Mine(x, y) public class BlueMine(int x, int y) : Mine(x, y)
{ {
protected override string CoverColor => "Blue"; protected override string CoverColor => "Blue";
protected override float ExplodeRadius => 100f; protected override float ExplodeRadius => 100f;
protected override int MaxHealth => 10; protected override int MaxHealth => 10;
protected int IdleThreshold = 100;
protected int CurrentIdleThreshold = 100;
protected bool IsCharging = false;
protected bool TargetReached = false;
protected Vector2 TargetOrigin;
private const float DriftSpeed = 1f;
private const float ChargeSpeed = 4f;
protected override void OnUpdate(SpriteUpdateContext context)
{
// During drift
if (!IsCharging)
{
XVelocity = 0;
YVelocity = DriftSpeed;
CurrentIdleThreshold--;
if (CurrentIdleThreshold > 0)
return;
// Time to pick a target and charge
TargetOrigin = PickTargetBelow(context);
IsCharging = true;
RotationSpeed *= ChargeSpeed;
return;
}
// During charge
Vector2 mineCenter = new(XPosition + Origin.X, YPosition + Origin.Y);
Vector2 toTarget = TargetOrigin - mineCenter;
float dist = toTarget.Length();
// "Arrive" cleanly: if we can reach it this frame, snap + stop charging
float step = ChargeSpeed; // since you're using per-frame velocities
if (dist <= step || dist <= 0.001f)
{
XPosition = TargetOrigin.X - Origin.X;
YPosition = TargetOrigin.Y - Origin.Y;
IsCharging = false;
RotationSpeed = 1.5f;
CurrentIdleThreshold = IdleThreshold;
XVelocity = 0;
YVelocity = DriftSpeed;
return;
}
Vector2 dir = toTarget / dist;
XVelocity = dir.X * ChargeSpeed;
YVelocity = dir.Y * ChargeSpeed;
}
private Vector2 PickTargetBelow(SpriteUpdateContext context)
{
// Mine center in world coords
float mineCenterX = XPosition + Origin.X;
float mineCenterY = YPosition + Origin.Y;
int screenW = context.ViewTransform.ScreenWidth;
int screenH = context.ViewTransform.ScreenHeight;
// Anywhere horizontally:
float x = context.Random.Next(0, screenW);
// Somewhere below the mine, but still on-screen.
// Clamp minY so Random doesn't throw if we're near bottom.
int minY = (int)MathF.Min(mineCenterY + 32f, screenH - 1);
int maxY = screenH;
// If we're already basically at the bottom, just pick the bottom row
float y = (minY < maxY) ? context.Random.Next(minY, maxY) : (screenH - 1);
return new Vector2(x, y);
}
private Vector2 GetTargetDirection()
{
Vector2 toTarget = TargetOrigin - new Vector2(XPosition + Origin.X, YPosition + Origin.Y);
float dist = toTarget.Length();
return toTarget / dist;
}
} }

View File

@@ -1,13 +1,11 @@
using AlienAttack.MonoGame.Things.Bullets; using AlienAttack.MonoGame.Things.Bullets;
using AlienAttack.MonoGame.Things.Explosions; using AlienAttack.MonoGame.Things.Explosions;
using Microsoft.Xna.Framework;
namespace AlienAttack.MonoGame.Things.Enemies; namespace AlienAttack.MonoGame.Things.Enemies.Ships;
public abstract class EnemyShip : MoveableSprite public abstract class EnemyShip : Ship
{ {
protected abstract int Health { get; set; } protected abstract int Health { get; set; }
public virtual int CrashDamage => 10; public virtual int CrashDamage => 10;
public EnemyShip(int x, int y) : base(x, y) public EnemyShip(int x, int y) : base(x, y)

View File

@@ -0,0 +1,9 @@
using AlienAttack.MonoGame.Things.Muzzles;
using Microsoft.Xna.Framework;
namespace AlienAttack.MonoGame.Things.Enemies.Ships;
public abstract class Ship(int x, int y) : MoveableSprite(x, y)
{
public abstract Vector2 GetMuzzleLocal(MuzzleId muzzle);
}

View File

@@ -5,9 +5,9 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic; using System.Collections.Generic;
namespace AlienAttack.MonoGame.Things.Enemies; namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeA;
public class GreenEnemy : EnemyShip public class GreenShipTypeA : ShipTypeA
{ {
//Enemy01_Green_Frame_1_png_processed //Enemy01_Green_Frame_1_png_processed
@@ -16,7 +16,7 @@ public class GreenEnemy : EnemyShip
protected int CurrentFireThreshold { get; set; } = 20; protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5; protected override int Health { get; set; } = 5;
public GreenEnemy(int x, int y) : base(x, y) public GreenShipTypeA(int x, int y) : base(x, y)
{ {
BoundBox = new Rectangle(0, 0, 64, 64); BoundBox = new Rectangle(0, 0, 64, 64);
YVelocity = 1; YVelocity = 1;

View File

@@ -2,15 +2,15 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
namespace AlienAttack.MonoGame.Things.Enemies; namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeA;
public class RedEnemy : EnemyShip public class RedShipTypeA : ShipTypeA
{ {
protected int FireThreshold => 20; protected int FireThreshold => 20;
protected int CurrentFireThreshold { get; set; } = 20; protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5; protected override int Health { get; set; } = 5;
public RedEnemy(int x, int y) : base(x, y) public RedShipTypeA(int x, int y) : base(x, y)
{ {
BoundBox = new Rectangle(0, 0, 64, 64); BoundBox = new Rectangle(0, 0, 64, 64);
YVelocity = 1.5f; YVelocity = 1.5f;

View File

@@ -0,0 +1,18 @@
using AlienAttack.MonoGame.Things.Muzzles;
using Microsoft.Xna.Framework;
namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeA;
public abstract class ShipTypeA(int x, int y) : EnemyShip(x, y)
{
public override Vector2 GetMuzzleLocal(MuzzleId muzzle)
{
return muzzle switch
{
MuzzleId.Left => new(20, 49),
MuzzleId.Center => new(31.5f, 49),
MuzzleId.Right => new(43, 49),
_ => new(),
};
}
}

View File

@@ -2,15 +2,15 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
namespace AlienAttack.MonoGame.Things.Enemies; namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeA;
public class TealEnemy : EnemyShip public class TealShipTypeA : ShipTypeA
{ {
protected int FireThreshold => 20; protected int FireThreshold => 20;
protected int CurrentFireThreshold { get; set; } = 20; protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5; protected override int Health { get; set; } = 5;
public TealEnemy(int x, int y) : base(x, y) public TealShipTypeA(int x, int y) : base(x, y)
{ {
BoundBox = new Rectangle(0, 0, 64, 64); BoundBox = new Rectangle(0, 0, 64, 64);
YVelocity = 1; YVelocity = 1;

View File

@@ -1,10 +1,9 @@
using AlienAttack.MonoGame.Things.Bullets; using AlienAttack.MonoGame.Things.Bullets;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
namespace AlienAttack.MonoGame.Things.Enemies; namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeB;
public class Enemy02Green : EnemyShip public class GreenShipTypeB : ShipTypeB
{ {
public const int Width = 64; public const int Width = 64;
public const int Height = 64; public const int Height = 64;
@@ -13,7 +12,7 @@ public class Enemy02Green : EnemyShip
protected int CurrentFireThreshold { get; set; } = 20; protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5; protected override int Health { get; set; } = 5;
public Enemy02Green(int x, int y) : base(x, y) public GreenShipTypeB(int x, int y) : base(x, y)
{ {
BoundBox = new(0, 0, Width, Height); BoundBox = new(0, 0, Width, Height);
YVelocity = 2; YVelocity = 2;

View File

@@ -1,10 +1,9 @@
using AlienAttack.MonoGame.Things.Bullets; using AlienAttack.MonoGame.Things.Bullets;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
namespace AlienAttack.MonoGame.Things.Enemies; namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeB;
public class Enemy02Red : EnemyShip public class RedShipTypeB : ShipTypeB
{ {
public const int Width = 64; public const int Width = 64;
public const int Height = 64; public const int Height = 64;
@@ -13,7 +12,7 @@ public class Enemy02Red : EnemyShip
protected int CurrentFireThreshold { get; set; } = 20; protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5; protected override int Health { get; set; } = 5;
public Enemy02Red(int x, int y) : base(x, y) public RedShipTypeB(int x, int y) : base(x, y)
{ {
BoundBox = new(0, 0, Width, Height); BoundBox = new(0, 0, Width, Height);
YVelocity = 3; YVelocity = 3;

View File

@@ -0,0 +1,19 @@
using AlienAttack.MonoGame.Things.Muzzles;
using Microsoft.Xna.Framework;
namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeB;
public abstract class ShipTypeB(int x, int y) : EnemyShip(x, y)
{
// TODO
public override Vector2 GetMuzzleLocal(MuzzleId muzzle)
{
return muzzle switch
{
MuzzleId.Left => new(20, 49),
MuzzleId.Center => new(31.5f, 49),
MuzzleId.Right => new(43, 49),
_ => new(),
};
}
}

View File

@@ -1,10 +1,9 @@
using AlienAttack.MonoGame.Things.Bullets; using AlienAttack.MonoGame.Things.Bullets;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
namespace AlienAttack.MonoGame.Things.Enemies; namespace AlienAttack.MonoGame.Things.Enemies.Ships.TypeB;
public class Enemy02Teal : EnemyShip public class TealShipTypeB : ShipTypeB
{ {
public const int Width = 64; public const int Width = 64;
public const int Height = 64; public const int Height = 64;
@@ -13,7 +12,7 @@ public class Enemy02Teal : EnemyShip
protected int CurrentFireThreshold { get; set; } = 20; protected int CurrentFireThreshold { get; set; } = 20;
protected override int Health { get; set; } = 5; protected override int Health { get; set; } = 5;
public Enemy02Teal(int x, int y) : base(x, y) public TealShipTypeB(int x, int y) : base(x, y)
{ {
BoundBox = new(0, 0, Width, Height); BoundBox = new(0, 0, Width, Height);
YVelocity = 1; YVelocity = 1;

View File

@@ -1,5 +1,5 @@
using AlienAttack.MonoGame.Things.Bullets; using AlienAttack.MonoGame.Things.Bullets;
using AlienAttack.MonoGame.Things.Enemies; using AlienAttack.MonoGame.Things.Enemies.Ships;
using AlienAttack.MonoGame.Things.Items; using AlienAttack.MonoGame.Things.Items;
using AlienAttack.MonoGame.Things.Muzzles; using AlienAttack.MonoGame.Things.Muzzles;
using AlienAttack.MonoGame.Things.Weapons; using AlienAttack.MonoGame.Things.Weapons;
@@ -415,15 +415,6 @@ public class Player : MoveableSprite
if (context.Sprite is Shields) if (context.Sprite is Shields)
{ {
//SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS
//int number = context.Random.Next(1, 6);
//SoundEffect soundEffect = context.Content.Load<SoundEffect>(@$"Sfx\Shield\SCIEnrg_Shield Activate_0{number}_SFRMS_SCIWPNS");
//soundEffect.Play(0.85f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0);
//context.AudioManager.PlayPickup(PickupKind.Shield);
GiveShield(20); GiveShield(20);
} }