diff --git a/AlientAttack.MonoGame/AlienAttackGame.cs b/AlientAttack.MonoGame/AlienAttackGame.cs index 31bfb96..c1eea88 100644 --- a/AlientAttack.MonoGame/AlienAttackGame.cs +++ b/AlientAttack.MonoGame/AlienAttackGame.cs @@ -1,8 +1,10 @@ using AlienAttack.MonoGame.GameLoops; using AlienAttack.MonoGame.View; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Media; using System; using System.Runtime.InteropServices; @@ -44,6 +46,28 @@ public class AlienAttackGame : Game base.Initialize(); MaximizeWindow(); + + PlayBackgroundMusic(); + } + + private void PlayBackgroundMusic() + { + Song song = Content.Load($@"Music\Untitled"); + + // Set whether the song should repeat when finished + MediaPlayer.IsRepeating = true; + + // Adjust the volume (0.0f to 1.0f) + MediaPlayer.Volume = 0.5f; + + // Check if the media player is already playing, if so, stop it + if (MediaPlayer.State == MediaState.Playing) + { + MediaPlayer.Stop(); + } + + // Start playing the background music + MediaPlayer.Play(song); } private void ConfigureWindow() @@ -86,7 +110,7 @@ public class AlienAttackGame : Game GraphicsDevice.Clear(Color.Black); // TODO: Add your drawing code here - _gameLoop.Draw(); + _gameLoop.Draw(gameTime); base.Draw(gameTime); } diff --git a/AlientAttack.MonoGame/Content/Content.mgcb b/AlientAttack.MonoGame/Content/Content.mgcb index 086a9a6..adb44de 100644 --- a/AlientAttack.MonoGame/Content/Content.mgcb +++ b/AlientAttack.MonoGame/Content/Content.mgcb @@ -37,6 +37,150 @@ /processorParam:TextureFormat=Color /build:Background/PixelBackgroundSeamlessVertically.png +#begin Music/Untitled.mp3 +/importer:Mp3Importer +/processor:SongProcessor +/processorParam:Quality=Best +/build:Music/Untitled.mp3 + +#begin Sfx/Explosions/EXPLDsgn_Explosion Impact_01_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Explosions/EXPLDsgn_Explosion Impact_01_SFRMS_SCIWPNS.wav;Sfx/Explosions/EXPLDsgn_Explosion Impact_01_SFRMS_SCIWPNS + +#begin Sfx/Explosions/EXPLDsgn_Explosion Impact_02_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Explosions/EXPLDsgn_Explosion Impact_02_SFRMS_SCIWPNS.wav;Sfx/Explosions/EXPLDsgn_Explosion Impact_02_SFRMS_SCIWPNS + +#begin Sfx/Explosions/EXPLDsgn_Explosion Impact_03_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Explosions/EXPLDsgn_Explosion Impact_03_SFRMS_SCIWPNS.wav;Sfx/Explosions/EXPLDsgn_Explosion Impact_03_SFRMS_SCIWPNS + +#begin Sfx/Explosions/EXPLDsgn_Explosion Impact_04_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Explosions/EXPLDsgn_Explosion Impact_04_SFRMS_SCIWPNS.wav;Sfx/Explosions/EXPLDsgn_Explosion Impact_04_SFRMS_SCIWPNS + +#begin Sfx/Explosions/EXPLDsgn_Explosion Impact_05_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Explosions/EXPLDsgn_Explosion Impact_05_SFRMS_SCIWPNS.wav;Sfx/Explosions/EXPLDsgn_Explosion Impact_05_SFRMS_SCIWPNS + +#begin Sfx/Explosions/EXPLDsgn_Explosion Impact_06_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Explosions/EXPLDsgn_Explosion Impact_06_SFRMS_SCIWPNS.wav;Sfx/Explosions/EXPLDsgn_Explosion Impact_06_SFRMS_SCIWPNS + +#begin Sfx/GUNAuto_Assault Rifle A Fire_01_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNAuto_Assault Rifle A Fire_01_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNAuto_Assault Rifle A Fire_02_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNAuto_Assault Rifle A Fire_02_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNAuto_Assault Rifle A Fire_03_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNAuto_Assault Rifle A Fire_03_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNAuto_Assault Rifle A Fire_04_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNAuto_Assault Rifle A Fire_04_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNAuto_Assault Rifle A Fire_05_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNAuto_Assault Rifle A Fire_05_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNAuto_Assault Rifle A Fire_06_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNAuto_Assault Rifle A Fire_06_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNPis_Pistol Fire_01_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNPis_Pistol Fire_01_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNPis_Pistol Fire_02_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNPis_Pistol Fire_02_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNPis_Pistol Fire_03_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNPis_Pistol Fire_03_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNPis_Pistol Fire_04_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNPis_Pistol Fire_04_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNPis_Pistol Fire_05_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNPis_Pistol Fire_05_SFRMS_SCIWPNS.wav + +#begin Sfx/GUNPis_Pistol Fire_06_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/GUNPis_Pistol Fire_06_SFRMS_SCIWPNS.wav + +#begin Sfx/Shield/SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Shield/SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS.wav;Sfx/Shield/SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS + +#begin Sfx/Shield/SCIEnrg_Shield Activate_02_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Shield/SCIEnrg_Shield Activate_02_SFRMS_SCIWPNS.wav;Sfx/Shield/SCIEnrg_Shield Activate_02_SFRMS_SCIWPNS + +#begin Sfx/Shield/SCIEnrg_Shield Activate_03_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Shield/SCIEnrg_Shield Activate_03_SFRMS_SCIWPNS.wav;Sfx/Shield/SCIEnrg_Shield Activate_03_SFRMS_SCIWPNS + +#begin Sfx/Shield/SCIEnrg_Shield Activate_04_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Shield/SCIEnrg_Shield Activate_04_SFRMS_SCIWPNS.wav;Sfx/Shield/SCIEnrg_Shield Activate_04_SFRMS_SCIWPNS + +#begin Sfx/Shield/SCIEnrg_Shield Activate_05_SFRMS_SCIWPNS.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Sfx/Shield/SCIEnrg_Shield Activate_05_SFRMS_SCIWPNS.wav;Sfx/Shield/SCIEnrg_Shield Activate_05_SFRMS_SCIWPNS + #begin Sprites/Asteroid 01_png_processed.png /importer:TextureImporter /processor:TextureProcessor diff --git a/AlientAttack.MonoGame/Content/Music/Untitled.mp3 b/AlientAttack.MonoGame/Content/Music/Untitled.mp3 new file mode 100644 index 0000000..461aa00 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Music/Untitled.mp3 differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_01_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_01_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..8aaefe3 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_01_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_02_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_02_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..1e18ad9 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_02_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_03_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_03_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..2a23618 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_03_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_04_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_04_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..9e11dd1 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_04_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_05_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_05_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..da6c0e1 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_05_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_06_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_06_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..1218708 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Explosions/EXPLDsgn_Explosion Impact_06_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_01_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_01_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..bca2632 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_01_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_02_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_02_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..fb7c8fd Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_02_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_03_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_03_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..5f214fd Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_03_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_04_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_04_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..a30a293 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_04_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_05_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_05_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..c040ae2 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_05_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_06_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_06_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..ef72896 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNAuto_Assault Rifle A Fire_06_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_01_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_01_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..a0b0456 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_01_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_02_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_02_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..66fa9a2 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_02_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_03_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_03_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..d3ccaf2 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_03_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_04_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_04_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..bb9aa3a Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_04_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_05_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_05_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..87dedb7 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_05_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_06_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_06_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..12494bf Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/GUNPis_Pistol Fire_06_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..b884498 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_02_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_02_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..a5c27a6 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_02_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_03_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_03_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..31184e1 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_03_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_04_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_04_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..6f76045 Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_04_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_05_SFRMS_SCIWPNS.wav b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_05_SFRMS_SCIWPNS.wav new file mode 100644 index 0000000..24e60fa Binary files /dev/null and b/AlientAttack.MonoGame/Content/Sfx/Shield/SCIEnrg_Shield Activate_05_SFRMS_SCIWPNS.wav differ diff --git a/AlientAttack.MonoGame/GameLoops/GameLoop.cs b/AlientAttack.MonoGame/GameLoops/GameLoop.cs index 4e8d0aa..52cf1de 100644 --- a/AlientAttack.MonoGame/GameLoops/GameLoop.cs +++ b/AlientAttack.MonoGame/GameLoops/GameLoop.cs @@ -1,6 +1,7 @@ using AlienAttack.MonoGame.Things; using AlienAttack.MonoGame.Things.Enemies; using AlienAttack.MonoGame.Things.Stars; +using AlienAttack.MonoGame.View; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; @@ -15,7 +16,6 @@ internal class GameLoop : GameLoopBase private readonly Random _random = new(); private int _spawnNewEnemyThreshold = 100; - private float _backgroundYOffset = 0; private Starfield _starfield; private Texture2D _pixel; @@ -56,84 +56,87 @@ internal class GameLoop : GameLoopBase _starfield.Initialize(ViewTransform.ScreenWidth, ViewTransform.ScreenHeight); } - public override void OnDraw() + public override void OnDraw(GameTime gameTime) { _starfield.Draw(SpriteBatch, _pixel); //DrawBackground(); - DrawHud(); + DrawHud(gameTime); DrawSprites(); } - private void DrawBackground() + private void DrawHud(GameTime gameTime) { - Texture2D backgroundTexture = Content.Load($@"Background\PixelBackgroundSeamlessVertically"); - int blockCountY = (int)Math.Ceiling((decimal)ViewTransform.ScreenHeight / (decimal)backgroundTexture.Height); - int blockCountX = (int)Math.Ceiling((decimal)ViewTransform.ScreenWidth / (decimal)backgroundTexture.Width); - - for (int y = 0; y < blockCountY; y++) - { - float startY = (y * backgroundTexture.Height) + _backgroundYOffset; - _backgroundYOffset = _backgroundYOffset + 0.25f; - - if (_backgroundYOffset > ViewTransform.ScreenHeight) - { - _backgroundYOffset = 0; - } - - for (int x = 0; x < blockCountX; x++) - { - int width = backgroundTexture.Width; - - if (x * backgroundTexture.Width + backgroundTexture.Width > ViewTransform.ScreenWidth) - { - width = ViewTransform.ScreenWidth - (x * backgroundTexture.Width); - } - - Vector2 position = new(x * backgroundTexture.Width, startY); - SpriteBatch.Draw(backgroundTexture, position, new Rectangle(new Point(x, y), new Point(width, backgroundTexture.Height)), Color.White); - } - } + double t = gameTime.TotalGameTime.TotalSeconds; + DrawSideBars(SpriteBatch, ViewTransform.ScreenWidth, ViewTransform.ScreenHeight, _player.Health, _player.Shield, t); } - private void DrawHud() - { - DrawSideBars(SpriteBatch, ViewTransform.ScreenWidth, ViewTransform.ScreenHeight, _player.Health, _player.Shield); - } - - private void DrawSideBars(SpriteBatch sb, int screenW, int screenH, int health, int shield) + private void DrawSideBars(SpriteBatch sb, int screenW, int screenH, int health, int shield, double totalSeconds) { health = Math.Clamp(health, 0, 100); shield = Math.Clamp(shield, 0, 100); - // Tweak these to taste to match “Raptor-ish” proportions - int marginTop = 8; - int marginBottom = 8; - int barWidth = 10; // thin like the screenshot - int gap = 4; // small gap between segments + int marginTop = 10; + int marginBottom = 10; + int segments = 100; + int gap = 4; + + int barWidth = 10; // thickness of the colored segments + int borderPad = 2; // thickness around the bar (border area) + int borderW = barWidth + borderPad * 2; int barHeight = screenH - marginTop - marginBottom; - - // Compute segment height so 100 segments + gaps fit in the available height - // If your resolution is small, this could become 0; clamp to 1. int segHeight = Math.Max(1, (barHeight - gap * (segments - 1)) / segments); - - // Recompute barHeight actually used by segments (so we can bottom-align perfectly) int usedHeight = segments * segHeight + (segments - 1) * gap; - // Position bars along left/right edges - int leftX = 6; // a few pixels from edge - int rightX = screenW - 6 - barWidth; + int barTopY = marginTop; + int barBottomY = marginTop + usedHeight; - int bottomY = marginTop + usedHeight; // bottom of the bar area + // Put left / right bars near screen edges + int leftBorderX = 8; + int rightBorderX = screenW - 8 - borderW; - // Colors - Color healthOn = new Color(255, 140, 0); // orange-ish - Color shieldOn = new Color(60, 140, 255); // blue-ish - Color off = new Color(30, 30, 30); // dark "empty" segment + // Colors (tweak as desired) + Color healthOn = new Color(255, 140, 0); // orange + Color shieldOn = new Color(60, 140, 255); // blue - DrawSegmentedBar(sb, leftX, bottomY, barWidth, segHeight, gap, health, healthOn, off, segments); - DrawSegmentedBar(sb, rightX, bottomY, barWidth, segHeight, gap, shield, shieldOn, off, segments); + Color off = new Color(28, 28, 28); // empty segment base + + // Draw metallic frames (behind segments) + //DrawMetallicFrame(sb, new Rectangle(leftBorderX, barTopY - borderPad, borderW, usedHeight + borderPad * 2)); + //DrawMetallicFrame(sb, new Rectangle(rightBorderX, barTopY - borderPad, borderW, usedHeight + borderPad * 2)); + + // Segment drawing X starts inside the border + int leftSegX = leftBorderX + borderPad; + int rightSegX = rightBorderX + borderPad; + + // Low health pulse settings + bool lowHealth = health <= 20; + float pulse = lowHealth + ? (0.85f + 0.15f * (float)Math.Sin(totalSeconds * 6.0)) // subtle wobble + : 1f; + + DrawSegmentedBar( + sb, leftSegX, barBottomY, barWidth, segHeight, gap, + value0To100: health, + onColor: healthOn, + offColor: off, + segments: segments, + // pulse only on filled health segments + pulseMultiplier: pulse, + pulseFilledOnly: true + ); + + DrawSegmentedBar( + sb, rightSegX, barBottomY, barWidth, segHeight, gap, + value0To100: shield, + onColor: shieldOn, + offColor: off, + segments: segments, + // no pulse for shield by default + pulseMultiplier: 1f, + pulseFilledOnly: true + ); } private void DrawSegmentedBar( @@ -146,8 +149,11 @@ internal class GameLoop : GameLoopBase int value0To100, Color onColor, Color offColor, - int segments = 100) + int segments, + float pulseMultiplier, + bool pulseFilledOnly) { + // Gradient: bottom darker, top brighter float minBrightness = 0.55f; float maxBrightness = 1.00f; @@ -155,21 +161,76 @@ internal class GameLoop : GameLoopBase { int y = bottomY - (i + 1) * segHeight - i * gap; - // i = 0 bottom, i = segments-1 top + // i=0 bottom, i=segments-1 top float t = i / (float)(segments - 1); float brightness = MathHelper.Lerp(minBrightness, maxBrightness, t); - Color baseColor = (i < value0To100) ? onColor : offColor; + bool filled = i < value0To100; + Color baseColor = filled ? onColor : offColor; - // Apply brightness scaling - Color finalColor = new Color( - (byte)(baseColor.R * brightness), - (byte)(baseColor.G * brightness), - (byte)(baseColor.B * brightness), - baseColor.A - ); + // Apply pulse (usually only on the filled parts) + if (pulseMultiplier != 1f && (!pulseFilledOnly || filled)) + { + brightness *= pulseMultiplier; + brightness = Math.Min(brightness, 1.2f); // allow a tiny “pop”, still safe + } + Color finalColor = ScaleRgb(baseColor, brightness); sb.Draw(_pixel, new Rectangle(x, y, barWidth, segHeight), finalColor); + + // Optional: little “shine” line on filled segments (adds a nice DOS UI feel) + // Draw a 1px highlight on the left edge of lit segments. + if (filled && barWidth >= 3) + { + var shine = ScaleRgb(Color.White, 0.10f * brightness); + sb.Draw(_pixel, new Rectangle(x, y, 1, segHeight), shine); + } + } + } + + private static Color ScaleRgb(Color c, float mul) + { + mul = Math.Max(0f, mul); + byte r = (byte)Math.Clamp((int)(c.R * mul), 0, 255); + byte g = (byte)Math.Clamp((int)(c.G * mul), 0, 255); + byte b = (byte)Math.Clamp((int)(c.B * mul), 0, 255); + return new Color(r, g, b, c.A); + } + + private void DrawMetallicFrame(SpriteBatch sb, Rectangle outer) + { + // “Metal” palette + Color outerBorder = new Color(10, 10, 10); + Color fill = new Color(45, 45, 45); + + Color highlight = new Color(90, 90, 90); // top/left + Color shadow = new Color(20, 20, 20); // bottom/right + + // Outer border + sb.Draw(_pixel, outer, outerBorder); + + // Inner fill + var inner = new Rectangle(outer.X + 1, outer.Y + 1, outer.Width - 2, outer.Height - 2); + if (inner.Width > 0 && inner.Height > 0) + sb.Draw(_pixel, inner, fill); + + // Bevel lines (1px) + // Top highlight + sb.Draw(_pixel, new Rectangle(inner.X, inner.Y, inner.Width, 1), highlight); + // Left highlight + sb.Draw(_pixel, new Rectangle(inner.X, inner.Y, 1, inner.Height), highlight); + + // Bottom shadow + sb.Draw(_pixel, new Rectangle(inner.X, inner.Bottom - 1, inner.Width, 1), shadow); + // Right shadow + sb.Draw(_pixel, new Rectangle(inner.Right - 1, inner.Y, 1, inner.Height), shadow); + + // Optional: an even tighter inner “lip” for extra metal feel + var lip = new Rectangle(inner.X + 1, inner.Y + 1, inner.Width - 2, inner.Height - 2); + if (lip.Width > 0 && lip.Height > 0) + { + Color lipDark = new Color(35, 35, 35); + sb.Draw(_pixel, lip, lipDark); } } @@ -199,6 +260,7 @@ internal class GameLoop : GameLoopBase { Random = _random, GameTime = gameTime, + Content = Content, SpawnSprite = _spritesToAdd.Add }; @@ -219,7 +281,9 @@ internal class GameLoop : GameLoopBase SpriteCollisionContext context = new(Game) { Sprite = otherSprite, - SpawnSprite = _spritesToAdd.Add + SpawnSprite = _spritesToAdd.Add, + Random = _random, + Content = Content }; // TODO: If perfomed once; do not perform again @@ -282,4 +346,11 @@ internal class GameLoop : GameLoopBase } } } +} + +public record DrawContext +{ + public GameTime GameTime; + public SpriteBatch SpriteBatch; + public ViewTransform ViewTransoform; } \ No newline at end of file diff --git a/AlientAttack.MonoGame/GameLoops/GameLoopBase.cs b/AlientAttack.MonoGame/GameLoops/GameLoopBase.cs index 44be08f..d1696ff 100644 --- a/AlientAttack.MonoGame/GameLoops/GameLoopBase.cs +++ b/AlientAttack.MonoGame/GameLoops/GameLoopBase.cs @@ -12,11 +12,11 @@ internal abstract class GameLoopBase(AlienAttackGame game) : IGameLoop protected readonly SpriteBatch SpriteBatch = game.SpriteBatch; protected readonly ViewTransform ViewTransform = game.ViewTransform; - public void Draw() + public void Draw(GameTime gameTime) { SpriteBatch.Begin(transformMatrix: ViewTransform.ViewMatrix); - OnDraw(); + OnDraw(gameTime); SpriteBatch.End(); } @@ -26,6 +26,6 @@ internal abstract class GameLoopBase(AlienAttackGame game) : IGameLoop OnUpdate(gameTime); } - public abstract void OnDraw(); + public abstract void OnDraw(GameTime gameTime); public abstract void OnUpdate(GameTime gameTime); } \ No newline at end of file diff --git a/AlientAttack.MonoGame/GameLoops/IGameLoop.cs b/AlientAttack.MonoGame/GameLoops/IGameLoop.cs index a76ad85..1eb794c 100644 --- a/AlientAttack.MonoGame/GameLoops/IGameLoop.cs +++ b/AlientAttack.MonoGame/GameLoops/IGameLoop.cs @@ -4,6 +4,6 @@ namespace AlienAttack.MonoGame.GameLoops; internal interface IGameLoop { - void Draw(); + void Draw(GameTime gameTime); void Update(GameTime gameTime); } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Hud/Hud.cs b/AlientAttack.MonoGame/Hud/Hud.cs new file mode 100644 index 0000000..7189acf --- /dev/null +++ b/AlientAttack.MonoGame/Hud/Hud.cs @@ -0,0 +1,199 @@ +using AlienAttack.MonoGame.GameLoops; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; + +namespace AlienAttack.MonoGame.Hud; + +public record DrawHudContext : DrawContext +{ + public int Health; + public int Shield; +} + +internal class Hud +{ + private Texture2D _pixel; + + public Hud(Game game) + { + _pixel = new Texture2D(game.GraphicsDevice, 1, 1); + _pixel.SetData(new[] { Color.White }); + } + + public void Draw(DrawHudContext context) + { + DrawSideBars(context); + } + + private void DrawSideBars(DrawHudContext context) + { + SpriteBatch sb = context.SpriteBatch; + + int screenW = context.ViewTransoform.ScreenWidth; + int screenH = context.ViewTransoform.ScreenHeight; + + double totalSeconds = context.GameTime.TotalGameTime.TotalSeconds; + + int health = Math.Clamp(context.Health, 0, 100); + int shield = Math.Clamp(context.Shield, 0, 100); + + int marginTop = 10; + int marginBottom = 10; + + int segments = 100; + int gap = 4; + + int barWidth = 10; // thickness of the colored segments + int borderPad = 2; // thickness around the bar (border area) + int borderW = barWidth + borderPad * 2; + + int barHeight = screenH - marginTop - marginBottom; + int segHeight = Math.Max(1, (barHeight - gap * (segments - 1)) / segments); + int usedHeight = segments * segHeight + (segments - 1) * gap; + + int barTopY = marginTop; + int barBottomY = marginTop + usedHeight; + + // Put left / right bars near screen edges + int leftBorderX = 8; + int rightBorderX = screenW - 8 - borderW; + + // Colors (tweak as desired) + Color healthOn = new Color(255, 140, 0); // orange + Color shieldOn = new Color(60, 140, 255); // blue + + Color off = new Color(28, 28, 28); // empty segment base + + // Draw metallic frames (behind segments) + //DrawMetallicFrame(sb, new Rectangle(leftBorderX, barTopY - borderPad, borderW, usedHeight + borderPad * 2)); + //DrawMetallicFrame(sb, new Rectangle(rightBorderX, barTopY - borderPad, borderW, usedHeight + borderPad * 2)); + + // Segment drawing X starts inside the border + int leftSegX = leftBorderX + borderPad; + int rightSegX = rightBorderX + borderPad; + + // Low health pulse settings + bool lowHealth = health <= 20; + float pulse = lowHealth + ? (0.85f + 0.15f * (float)Math.Sin(totalSeconds * 6.0)) // subtle wobble + : 1f; + + DrawSegmentedBar( + sb, leftSegX, barBottomY, barWidth, segHeight, gap, + value0To100: health, + onColor: healthOn, + offColor: off, + segments: segments, + // pulse only on filled health segments + pulseMultiplier: pulse, + pulseFilledOnly: true + ); + + DrawSegmentedBar( + sb, rightSegX, barBottomY, barWidth, segHeight, gap, + value0To100: shield, + onColor: shieldOn, + offColor: off, + segments: segments, + // no pulse for shield by default + pulseMultiplier: 1f, + pulseFilledOnly: true + ); + } + + private void DrawSegmentedBar( + SpriteBatch sb, + int x, + int bottomY, + int barWidth, + int segHeight, + int gap, + int value0To100, + Color onColor, + Color offColor, + int segments, + float pulseMultiplier, + bool pulseFilledOnly) + { + // Gradient: bottom darker, top brighter + float minBrightness = 0.55f; + float maxBrightness = 1.00f; + + for (int i = 0; i < segments; i++) + { + int y = bottomY - (i + 1) * segHeight - i * gap; + + // i=0 bottom, i=segments-1 top + float t = i / (float)(segments - 1); + float brightness = MathHelper.Lerp(minBrightness, maxBrightness, t); + + bool filled = i < value0To100; + Color baseColor = filled ? onColor : offColor; + + // Apply pulse (usually only on the filled parts) + if (pulseMultiplier != 1f && (!pulseFilledOnly || filled)) + { + brightness *= pulseMultiplier; + brightness = Math.Min(brightness, 1.2f); // allow a tiny “pop”, still safe + } + + Color finalColor = ScaleRgb(baseColor, brightness); + sb.Draw(_pixel, new Rectangle(x, y, barWidth, segHeight), finalColor); + + // Optional: little “shine” line on filled segments (adds a nice DOS UI feel) + // Draw a 1px highlight on the left edge of lit segments. + if (filled && barWidth >= 3) + { + var shine = ScaleRgb(Color.White, 0.10f * brightness); + sb.Draw(_pixel, new Rectangle(x, y, 1, segHeight), shine); + } + } + } + + private static Color ScaleRgb(Color c, float mul) + { + mul = Math.Max(0f, mul); + byte r = (byte)Math.Clamp((int)(c.R * mul), 0, 255); + byte g = (byte)Math.Clamp((int)(c.G * mul), 0, 255); + byte b = (byte)Math.Clamp((int)(c.B * mul), 0, 255); + return new Color(r, g, b, c.A); + } + + private void DrawMetallicFrame(SpriteBatch sb, Rectangle outer) + { + // “Metal” palette + Color outerBorder = new Color(10, 10, 10); + Color fill = new Color(45, 45, 45); + + Color highlight = new Color(90, 90, 90); // top/left + Color shadow = new Color(20, 20, 20); // bottom/right + + // Outer border + sb.Draw(_pixel, outer, outerBorder); + + // Inner fill + var inner = new Rectangle(outer.X + 1, outer.Y + 1, outer.Width - 2, outer.Height - 2); + if (inner.Width > 0 && inner.Height > 0) + sb.Draw(_pixel, inner, fill); + + // Bevel lines (1px) + // Top highlight + sb.Draw(_pixel, new Rectangle(inner.X, inner.Y, inner.Width, 1), highlight); + // Left highlight + sb.Draw(_pixel, new Rectangle(inner.X, inner.Y, 1, inner.Height), highlight); + + // Bottom shadow + sb.Draw(_pixel, new Rectangle(inner.X, inner.Bottom - 1, inner.Width, 1), shadow); + // Right shadow + sb.Draw(_pixel, new Rectangle(inner.Right - 1, inner.Y, 1, inner.Height), shadow); + + // Optional: an even tighter inner “lip” for extra metal feel + var lip = new Rectangle(inner.X + 1, inner.Y + 1, inner.Width - 2, inner.Height - 2); + if (lip.Width > 0 && lip.Height > 0) + { + Color lipDark = new Color(35, 35, 35); + sb.Draw(_pixel, lip, lipDark); + } + } +} \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs b/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs index f5a434d..18c3b2d 100644 --- a/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs +++ b/AlientAttack.MonoGame/Things/Enemies/GreenEnemy.cs @@ -2,10 +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; @@ -43,7 +45,7 @@ internal class GreenEnemy : EnemyShip if (Health <= 0) { IsDead = true; - context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + SpawnExplosion(context); switch (context.Random.Next(0, 5)) { @@ -94,6 +96,16 @@ internal class GreenEnemy : EnemyShip base.Update(context); } + private void SpawnExplosion(SpriteUpdateContext context) + { + context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + + int number = context.Random.Next(1, 7); + + SoundEffect soundEffect = context.Content.Load(@$"Sfx\Explosions\EXPLDsgn_Explosion Impact_0{number}_SFRMS_SCIWPNS"); + soundEffect.Play(0.95f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0); + } + private void CheckFire(SpriteUpdateContext context) { //foreach (IWeapon weapon in ActiveWeapons) diff --git a/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs b/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs index 6c07e72..4154b04 100644 --- a/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs +++ b/AlientAttack.MonoGame/Things/Enemies/RedEnemy.cs @@ -1,5 +1,6 @@ using AlienAttack.MonoGame.Things.Bullets; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; namespace AlienAttack.MonoGame.Things.Enemies; @@ -53,7 +54,7 @@ internal class RedEnemy : EnemyShip if (Health <= 0) { IsDead = true; - context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + SpawnExplosion(context); return; } @@ -68,6 +69,16 @@ internal class RedEnemy : EnemyShip base.Update(context); } + private void SpawnExplosion(SpriteUpdateContext context) + { + context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + + int number = context.Random.Next(1, 7); + + SoundEffect soundEffect = context.Content.Load(@$"Sfx\Explosions\EXPLDsgn_Explosion Impact_0{number}_SFRMS_SCIWPNS"); + soundEffect.Play(0.95f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0); + } + private void TryFire(SpriteUpdateContext context) { if (CurrentFireThreshold > 0) diff --git a/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs b/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs index e42c6d5..325a012 100644 --- a/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs +++ b/AlientAttack.MonoGame/Things/Enemies/TealEnemy.cs @@ -1,5 +1,6 @@ using AlienAttack.MonoGame.Things.Bullets; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; namespace AlienAttack.MonoGame.Things.Enemies; @@ -45,7 +46,7 @@ internal class TealEnemy : EnemyShip if (Health <= 0) { IsDead = true; - context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + SpawnExplosion(context); return; } @@ -61,6 +62,16 @@ internal class TealEnemy : EnemyShip base.Update(context); } + private void SpawnExplosion(SpriteUpdateContext context) + { + context.SpawnSprite(new Explosion((int)XPosition, (int)YPosition, XVelocity, YVelocity)); + + int number = context.Random.Next(1, 7); + + SoundEffect soundEffect = context.Content.Load(@$"Sfx\Explosions\EXPLDsgn_Explosion Impact_0{number}_SFRMS_SCIWPNS"); + soundEffect.Play(0.95f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0); + } + private void TryFire(SpriteUpdateContext context) { if (CurrentFireThreshold > 0) diff --git a/AlientAttack.MonoGame/Things/Player.cs b/AlientAttack.MonoGame/Things/Player.cs index d085c42..de8f85f 100644 --- a/AlientAttack.MonoGame/Things/Player.cs +++ b/AlientAttack.MonoGame/Things/Player.cs @@ -3,6 +3,7 @@ using AlienAttack.MonoGame.Things.Enemies; 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; @@ -331,6 +332,13 @@ internal class Player : MoveableSprite if (context.Sprite is Shields) { + //SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS + + int number = context.Random.Next(1, 6); + + SoundEffect soundEffect = context.Content.Load(@$"Sfx\Shield\SCIEnrg_Shield Activate_0{number}_SFRMS_SCIWPNS"); + soundEffect.Play(0.85f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0); + GiveShield(20); } diff --git a/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs b/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs index a204670..d6ecb47 100644 --- a/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs +++ b/AlientAttack.MonoGame/Things/SpriteUpdateContext.cs @@ -1,5 +1,6 @@ using AlienAttack.MonoGame.View; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; using System; namespace AlienAttack.MonoGame.Things; @@ -10,6 +11,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 required ContentManager Content { get; init; } } public class SpriteCollisionContext(AlienAttackGame game) @@ -17,4 +19,6 @@ public class SpriteCollisionContext(AlienAttackGame game) public ViewTransform ViewTransform => game.ViewTransform; public required Sprite Sprite { get; init; } public required Action SpawnSprite { get; init; } + public required Random Random { get; init; } + public required ContentManager Content { get; init; } } \ No newline at end of file diff --git a/AlientAttack.MonoGame/Things/Weapons/Minigun.cs b/AlientAttack.MonoGame/Things/Weapons/Minigun.cs index 78d4003..918752f 100644 --- a/AlientAttack.MonoGame/Things/Weapons/Minigun.cs +++ b/AlientAttack.MonoGame/Things/Weapons/Minigun.cs @@ -1,4 +1,5 @@ using AlienAttack.MonoGame.Things.Bullets; +using Microsoft.Xna.Framework.Audio; namespace AlienAttack.MonoGame.Things.Weapons; @@ -20,6 +21,11 @@ public class Minigun : Weapon // Queue the bullets for spawning context.SpawnSprite(bullet1); context.SpawnSprite(bullet2); + + int number = context.Random.Next(1, 7); + + SoundEffect soundEffect = context.Content.Load(@$"Sfx\GUNAuto_Assault Rifle A Fire_0{number}_SFRMS_SCIWPNS"); + soundEffect.Play(0.25f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0); } }