diff --git a/shmupgame2022.sln b/shmupgame2022.sln new file mode 100644 index 0000000000000000000000000000000000000000..e234d143a7adb6b3b78da9cc940cf85d797d1bf0 --- /dev/null +++ b/shmupgame2022.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32228.343 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "shmupgame2022", "shmupgame2022\shmupgame2022.csproj", "{AC9D58F9-A2DB-45EA-9B91-517E5B09857C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shmupgame2022Tests", "shmupgame2022Tests\shmupgame2022Tests.csproj", "{749E8F48-CD46-4A07-AB23-B230B7AE27D5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AC9D58F9-A2DB-45EA-9B91-517E5B09857C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC9D58F9-A2DB-45EA-9B91-517E5B09857C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC9D58F9-A2DB-45EA-9B91-517E5B09857C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC9D58F9-A2DB-45EA-9B91-517E5B09857C}.Release|Any CPU.Build.0 = Release|Any CPU + {749E8F48-CD46-4A07-AB23-B230B7AE27D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {749E8F48-CD46-4A07-AB23-B230B7AE27D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {749E8F48-CD46-4A07-AB23-B230B7AE27D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {749E8F48-CD46-4A07-AB23-B230B7AE27D5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {168A0637-FC67-40DF-9729-0B8DA918FF7F} + EndGlobalSection +EndGlobal diff --git a/shmupgame2022/Content/Content.mgcb b/shmupgame2022/Content/Content.mgcb new file mode 100644 index 0000000000000000000000000000000000000000..7e825c5d28d1d32333390eeb6a922cc0d560347c --- /dev/null +++ b/shmupgame2022/Content/Content.mgcb @@ -0,0 +1,81 @@ + +#----------------------------- Global Properties ----------------------------# + +/outputDir:bin/$(Platform) +/intermediateDir:obj/$(Platform) +/platform:DesktopGL +/config: +/profile:Reach +/compress:False + +#-------------------------------- References --------------------------------# + + +#---------------------------------- Content ---------------------------------# + +#begin Explosion.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Explosion.wav + +#begin gameover.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:gameover.png + +#begin laser_shoot_enemy.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:laser_shoot_enemy.wav + +#begin Laser_Shoot_player.wav +/importer:WavImporter +/processor:SoundEffectProcessor +/processorParam:Quality=Best +/build:Laser_Shoot_player.wav + +#begin sovproj2022_bullet_ph_sprite.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:sovproj2022_bullet_ph_sprite.png + +#begin sovproj2022_enemy1_ph_sprite.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:sovproj2022_enemy1_ph_sprite.png + +#begin sovproj2022_player_ph_sprite.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:sovproj2022_player_ph_sprite.png + diff --git a/shmupgame2022/Content/Explosion.wav b/shmupgame2022/Content/Explosion.wav new file mode 100644 index 0000000000000000000000000000000000000000..f99f61f1f4202024ad7c6085630c1e278fdbade4 Binary files /dev/null and b/shmupgame2022/Content/Explosion.wav differ diff --git a/shmupgame2022/Content/Laser_Shoot_player.wav b/shmupgame2022/Content/Laser_Shoot_player.wav new file mode 100644 index 0000000000000000000000000000000000000000..978a14905c22f123653756299f499ea368f91489 Binary files /dev/null and b/shmupgame2022/Content/Laser_Shoot_player.wav differ diff --git a/shmupgame2022/Content/gameover.png b/shmupgame2022/Content/gameover.png new file mode 100644 index 0000000000000000000000000000000000000000..16f4a4e79947c3a2d03d657fcb80b7d867f5da3b Binary files /dev/null and b/shmupgame2022/Content/gameover.png differ diff --git a/shmupgame2022/Content/laser_shoot_enemy.wav b/shmupgame2022/Content/laser_shoot_enemy.wav new file mode 100644 index 0000000000000000000000000000000000000000..ecb4b743ac8c1f3d9d83269d42d278c5b8b7d486 Binary files /dev/null and b/shmupgame2022/Content/laser_shoot_enemy.wav differ diff --git a/shmupgame2022/Content/sovproj2022_bullet_ph_sprite.png b/shmupgame2022/Content/sovproj2022_bullet_ph_sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..aa387eca45dd4ee806f063c5c6c69588add9659f Binary files /dev/null and b/shmupgame2022/Content/sovproj2022_bullet_ph_sprite.png differ diff --git a/shmupgame2022/Content/sovproj2022_enemy1_ph_sprite.png b/shmupgame2022/Content/sovproj2022_enemy1_ph_sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..c175c5b63afe95a8397fc37b1229e9d2037fe4be Binary files /dev/null and b/shmupgame2022/Content/sovproj2022_enemy1_ph_sprite.png differ diff --git a/shmupgame2022/Content/sovproj2022_player_ph_sprite.png b/shmupgame2022/Content/sovproj2022_player_ph_sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..d88319fd60b5aa083b2e7775452a08b8b06867ba Binary files /dev/null and b/shmupgame2022/Content/sovproj2022_player_ph_sprite.png differ diff --git a/shmupgame2022/EnemyBullet.cs b/shmupgame2022/EnemyBullet.cs new file mode 100644 index 0000000000000000000000000000000000000000..9e7e25f425ef1a3bf45a992c93f3ca05a1bbe13a --- /dev/null +++ b/shmupgame2022/EnemyBullet.cs @@ -0,0 +1,52 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + class EnemyBullet : IGameEntity + { + public const float DEFAULT_SPEED = 2f; + public const float PLAYER_BULLET_SIZE = 4f; + + private TextureManager _textureAssetManager; + + public Vector2 Position { get; set; } + public Vector2 Speed { get; set; } + public int DrawOrder { get; set; } = 9; + public EntityType entityType { get; set; } = EntityType.ENEMY; + public bool IsDead { get; set; } = false; + public float Size { get; set; } = PLAYER_BULLET_SIZE; + + public void Draw(GameTime GameTime, SpriteBatch SpriteBatch) + { + SpriteBatch.Draw(_textureAssetManager.PlayerBulletTexture, this.Position, Color.Red); + } + + public void Update(GameTime GameTime, PlayerShip player) + { + this.Position = this.Position + this.Speed; + } + + public bool Collide(IGameEntity other) + { + if (other.entityType == EntityType.PLAYER) + { + this.IsDead = true; + return true; + } + else + return false; + } + + public EnemyBullet(Vector2 spawnLocation, Vector2 initialSpeed, TextureManager textureManager) + { + this.Position = spawnLocation; + this.Speed = initialSpeed * DEFAULT_SPEED; + this._textureAssetManager = textureManager; + this._textureAssetManager.ShootSoundEnemy.Play(); + } + } +} diff --git a/shmupgame2022/EnemyShip.cs b/shmupgame2022/EnemyShip.cs new file mode 100644 index 0000000000000000000000000000000000000000..98f99f918f7ee36c68023c1b91b83547891a618c --- /dev/null +++ b/shmupgame2022/EnemyShip.cs @@ -0,0 +1,56 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + public class EnemyShip : IGameEntity + { + private TextureManager _textureAssetManager; + + public const float DEFAULT_SPEED = 0.3f; + public const float DEFAULT_RANDOMNESS = 0.4f; + + public int DrawOrder { get; set; } = 8; + public Vector2 Speed { get; set; } = new Vector2(0, DEFAULT_SPEED); + public Vector2 Position { get; set; } + public EntityType entityType { get; set; } = EntityType.ENEMY; + public bool IsDead { get; set; } = false; + public float Size { get; set; } = 10f; + public float ShootingCooldown { get; set; } = 2f; + private Random RandomGenerator { get; set; } + + public void Draw(GameTime GameTime, SpriteBatch SpriteBatch) + { + SpriteBatch.Draw(this._textureAssetManager.EnemyShipTexture, this.Position - new Vector2(10,10), Color.White); + } + + public void Update(GameTime GameTime, PlayerShip player) + { + this.Position = this.Position + this.Speed; + this.ShootingCooldown = this.ShootingCooldown - (float)GameTime.ElapsedGameTime.TotalSeconds; + } + + public bool Collide(IGameEntity other) + { + if(other.entityType == EntityType.PLAYER) + { + this.IsDead = true; + return true; + } + return false; + } + + + public EnemyShip(TextureManager textureManager, Vector2 spawnPosition) + { + this.RandomGenerator = new Random(); + this.Speed = this.Speed + new Vector2(0, DEFAULT_RANDOMNESS * ((float)this.RandomGenerator.NextDouble())); + this.ShootingCooldown = this.ShootingCooldown + (float)this.RandomGenerator.NextDouble(); + this._textureAssetManager = textureManager; + this.Position = spawnPosition; + } + } +} diff --git a/shmupgame2022/EnemyWave.cs b/shmupgame2022/EnemyWave.cs new file mode 100644 index 0000000000000000000000000000000000000000..b341608ebe0b09f3b24983a59ea6b5ff49b42f43 --- /dev/null +++ b/shmupgame2022/EnemyWave.cs @@ -0,0 +1,14 @@ +namespace shmupgame2022 +{ + internal class EnemyWave + { + public int EnemyNumber { get; set; } + public float SecondsToEncounter { get; set; } + + public EnemyWave(int n, float seconds) + { + this.EnemyNumber = n; + this.SecondsToEncounter = seconds; + } + } +} \ No newline at end of file diff --git a/shmupgame2022/EnemyWaveManager.cs b/shmupgame2022/EnemyWaveManager.cs new file mode 100644 index 0000000000000000000000000000000000000000..a1512b475350864d8ee0a869e583f4a10c3abfde --- /dev/null +++ b/shmupgame2022/EnemyWaveManager.cs @@ -0,0 +1,63 @@ +using Microsoft.Xna.Framework; +using System.Collections.Generic; + +namespace shmupgame2022 +{ + internal class EnemyWaveManager + { + public const float ENEMY_WAVE_INTERVAL = 10f; + public const int ENEMY_WAVE_COUNT = 1; + public const int ENEMY_PER_WAVE = 4; + + public List<EnemyWave> WaveQueue { get; set; } + + public void addWave (EnemyWave wave) + { + this.WaveQueue.Add(wave); + } + + public EnemyWave PopFirstWave() + { + if (this.WaveQueue.Count > 0) + { + EnemyWave wave = this.WaveQueue[0]; + this.WaveQueue.RemoveAt(0); + return wave; + } + else + return null; + } + + public bool TimeToSpawnNextWave() + { + if (this.WaveQueue.Count > 0 && this.WaveQueue[0].SecondsToEncounter <= 0) + { + return true; + } + else + return false; + } + + public void Update(GameTime gameTime) + { + if(this.WaveQueue.Count > 0) + { + this.WaveQueue[0].SecondsToEncounter = this.WaveQueue[0].SecondsToEncounter - (float)gameTime.ElapsedGameTime.TotalSeconds; + } + else + { + + this.addWave(new EnemyWave(ENEMY_PER_WAVE, ENEMY_WAVE_INTERVAL)); + } + } + + public EnemyWaveManager() + { + this.WaveQueue = new List<EnemyWave>(); + for (int i = ENEMY_WAVE_COUNT; i > 0; i--) + { + this.addWave(new EnemyWave(ENEMY_PER_WAVE, ENEMY_WAVE_INTERVAL)); + } + } + } +} \ No newline at end of file diff --git a/shmupgame2022/EntityManager.cs b/shmupgame2022/EntityManager.cs new file mode 100644 index 0000000000000000000000000000000000000000..50ebac98af91f7933a296baa04ae6ab31dac3ea2 --- /dev/null +++ b/shmupgame2022/EntityManager.cs @@ -0,0 +1,159 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + class EntityManager + { + List<IGameEntity> _gameEntities; + List<IGameEntity> _playerEntities; + List<IGameEntity> _enemyEntities; + InputController _inputController; + TextureManager _textureAssetManager; + PlayerShip _playerShip; + private Random _random; + private EnemyWaveManager _enemyWaveManager; + + public const float STATIC_ENEMY_SHOOTING_INTERVAL = 4f; + + public void AddEntity(IGameEntity Entity) + { + _gameEntities.Add(Entity); + if (Entity.entityType == EntityType.PLAYER) + _playerEntities.Add(Entity); + if (Entity.entityType == EntityType.ENEMY) + _enemyEntities.Add(Entity); + } + + public void RemoveEntity(IGameEntity Entity) + { + _gameEntities.Remove(Entity); + if (Entity.entityType == EntityType.PLAYER) + _playerEntities.Remove(Entity); + if (Entity.entityType == EntityType.ENEMY) + _enemyEntities.Remove(Entity); + } + + public void UpdateEntities(GameTime gameTime) + { + _inputController.PollControls(); + + foreach (IGameEntity e in _gameEntities) + { + e.Update(gameTime, _playerShip); + } + foreach (IGameEntity e in _playerEntities) + { + if(e.entityType == EntityType.PLAYER) + { + foreach (IGameEntity entity in _enemyEntities) + { + if(CollisionDetected(e, entity)) + { + e.Collide(entity); + entity.Collide(e); + } + } + } + } + List<IGameEntity> shoot_list = new List<IGameEntity>(); + foreach (IGameEntity e in _enemyEntities) + { + if (e is EnemyShip) + { + EnemyShip eship = (EnemyShip)e; + if (eship.ShootingCooldown <= 0) + { + Vector2 initialspeed = (_playerShip.Position - eship.Position); + initialspeed.Normalize(); + shoot_list.Add(new EnemyBullet(eship.Position, initialspeed, _textureAssetManager)); + eship.ShootingCooldown = eship.ShootingCooldown + (float)_random.NextDouble() * 3f + STATIC_ENEMY_SHOOTING_INTERVAL; + } + } + } + foreach (IGameEntity e in shoot_list) + { + this.AddEntity(e); + } + + List<IGameEntity> kill_list = new List<IGameEntity>(); + foreach (IGameEntity e in _gameEntities) + { + if (e.IsDead || e.Position.Y > 650) + { + kill_list.Add(e); + } + } + if(kill_list.Count > 0) + { + _textureAssetManager.ExplosionSound.Play(); + } + foreach (IGameEntity e in kill_list) + { + this.RemoveEntity(e); + if (e is PlayerShip) + { + this.AddEntity(new GameOverUI(_textureAssetManager)); + } + } + + _enemyWaveManager.Update(gameTime); + + if(_enemyWaveManager.TimeToSpawnNextWave()) + { + this.SpawnEnemyWave(_enemyWaveManager.PopFirstWave().EnemyNumber); + } + } + + public void DrawEntities(SpriteBatch spriteBatch, GameTime gameTime) + { + if(spriteBatch != null) + { + foreach (IGameEntity e in _gameEntities) + { + e.Draw(gameTime, spriteBatch); + } + } + } + + public void SpawnPlayer() + { + PlayerShip ship = new PlayerShip(_textureAssetManager); + _inputController.playerShip = ship; + _playerShip = ship; + this.AddEntity(ship); + } + + public void SpawnEnemyWave(int number) + { + for (int i = number; i > 0; i--) + { + this.AddEntity(new EnemyShip(_textureAssetManager, new Vector2((float)_random.NextDouble()*300, -10))); + } + } + + public bool CollisionDetected(IGameEntity a, IGameEntity b) + { + if (Vector2.Distance(a.Position, b.Position) < (a.Size+b.Size)) + { + return true; + } + return false; + } + + public EntityManager(TextureManager textureManager) + { + _random = new Random(); + _enemyWaveManager = new EnemyWaveManager(); + _gameEntities = new List<IGameEntity>(); + _playerEntities = new List<IGameEntity>(); + _enemyEntities = new List<IGameEntity>(); + _textureAssetManager = textureManager; + _inputController = new InputController(this, _textureAssetManager); + + } + } +} diff --git a/shmupgame2022/GameOverUI.cs b/shmupgame2022/GameOverUI.cs new file mode 100644 index 0000000000000000000000000000000000000000..ade1c891e1eba48b11a01c6fa7574f4b3b7908a5 --- /dev/null +++ b/shmupgame2022/GameOverUI.cs @@ -0,0 +1,41 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + class GameOverUI : IGameEntity + { + public int DrawOrder { get; set; } = 12; + public EntityType entityType { get; set; } = EntityType.NONE; + public bool IsDead { get; set; } = false; + public Vector2 Position { get; set; } + public float Size { get; set; } + + private TextureManager _textureAssetManager; + + public bool Collide(IGameEntity other) + { + // doesn't collide in any way + return false; + } + + public void Draw(GameTime GameTime, SpriteBatch SpriteBatch) + { + SpriteBatch.Draw(_textureAssetManager.GameOverUITexture, this.Position, Color.White); + } + + public void Update(GameTime GameTime, PlayerShip player) + { + // doesn't update in any way + } + + public GameOverUI(TextureManager textureManager) + { + this._textureAssetManager = textureManager; + this.Position = new Vector2(75, 300); + } + } +} diff --git a/shmupgame2022/IGameEntity.cs b/shmupgame2022/IGameEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..2ec24c37aa48767d8dba62fc56c59e9a8aae9193 --- /dev/null +++ b/shmupgame2022/IGameEntity.cs @@ -0,0 +1,22 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + public enum EntityType { NONE, PLAYER, ENEMY} + + public interface IGameEntity + { + void Update(GameTime GameTime, PlayerShip player); + void Draw(GameTime GameTime, SpriteBatch SpriteBatch); + int DrawOrder { get; set; } + bool Collide(IGameEntity other); + EntityType entityType { get; set; } + bool IsDead { get; set; } + public Vector2 Position { get; set; } + public float Size { get; set; } + } +} diff --git a/shmupgame2022/Icon.bmp b/shmupgame2022/Icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2b481653e241818d2894e4ef33234eaff9aad701 Binary files /dev/null and b/shmupgame2022/Icon.bmp differ diff --git a/shmupgame2022/Icon.ico b/shmupgame2022/Icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7d9dec18704053ee43cd7c956022ddbdb34d8de1 Binary files /dev/null and b/shmupgame2022/Icon.ico differ diff --git a/shmupgame2022/InputController.cs b/shmupgame2022/InputController.cs new file mode 100644 index 0000000000000000000000000000000000000000..861271dd319731fc77c5bc8d49e9bfa52451c678 --- /dev/null +++ b/shmupgame2022/InputController.cs @@ -0,0 +1,75 @@ +using Microsoft.Xna.Framework.Input; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + class InputController + { + private EntityManager _entityManager; + private TextureManager _textureAssetManager; + + // this can be null, watch out! + public PlayerShip playerShip { get; set; } + + public InputController(EntityManager entityManager, TextureManager textureManager) + { + this._entityManager = entityManager; + this._textureAssetManager = textureManager; + + } + + internal void PollControls() + { + if (playerShip != null) + { + if (Keyboard.GetState().IsKeyDown(Keys.Up)) + { + playerShip.IsMovingUp = true; + } + else + { + playerShip.IsMovingUp = false; + } + + if (Keyboard.GetState().IsKeyDown(Keys.Down)) + { + playerShip.IsMovingDown = true; + } + else + { + playerShip.IsMovingDown = false; + } + + if (Keyboard.GetState().IsKeyDown(Keys.Left)) + { + playerShip.IsMovingLeft = true; + } + else + { + playerShip.IsMovingLeft = false; + } + + if (Keyboard.GetState().IsKeyDown(Keys.Right)) + { + playerShip.IsMovingRight = true; + } + else + { + playerShip.IsMovingRight = false; + } + + if (Keyboard.GetState().IsKeyDown(Keys.Space)) + { + if(playerShip.ShootingCooldown <= 0) + { + playerShip.ShootingCooldown = 0.2f; + _entityManager.AddEntity(new PlayerBullet(playerShip.Position, _textureAssetManager)); + } + } + + } + } + } +} diff --git a/shmupgame2022/PlayerBullet.cs b/shmupgame2022/PlayerBullet.cs new file mode 100644 index 0000000000000000000000000000000000000000..f10fe89937f485dcc99c6778d92c9e3858d5260d --- /dev/null +++ b/shmupgame2022/PlayerBullet.cs @@ -0,0 +1,51 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + class PlayerBullet : IGameEntity + { + public const float DEFAULT_SPEED = 10f; + public const float PLAYER_BULLET_SIZE = 4f; + + private TextureManager _textureAssetManager; + + public Vector2 Position { get; set; } + public Vector2 Speed { get; set; } = new Vector2(0, -DEFAULT_SPEED); + public int DrawOrder { get; set; } = 9; + public EntityType entityType { get; set; } = EntityType.PLAYER; + public bool IsDead { get; set; } = false; + public float Size { get; set; } = PLAYER_BULLET_SIZE; + + public void Draw(GameTime GameTime, SpriteBatch SpriteBatch) + { + SpriteBatch.Draw(_textureAssetManager.PlayerBulletTexture, this.Position, Color.White); + } + + public void Update(GameTime GameTime, PlayerShip player) + { + this.Position = this.Position + this.Speed; + } + + public bool Collide(IGameEntity other) + { + if (other.entityType == EntityType.ENEMY) + { + this.IsDead = true; + return true; + } + else + return false; + } + + public PlayerBullet(Vector2 spawnLocation, TextureManager textureManager) + { + this.Position = spawnLocation; + this._textureAssetManager = textureManager; + this._textureAssetManager.ShootSoundPlayer.Play(); + } + } +} diff --git a/shmupgame2022/PlayerShip.cs b/shmupgame2022/PlayerShip.cs new file mode 100644 index 0000000000000000000000000000000000000000..8f9733579ab44afe63153629a3a567a74a6b9581 --- /dev/null +++ b/shmupgame2022/PlayerShip.cs @@ -0,0 +1,89 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + public class PlayerShip : IGameEntity + { + public const int SHIP_HEIGHT = 20; + public const int SHIP_WIDTH = 20; + public const float SHIP_SPEED = 100f; + + public const int DEFAULT_X = 150; + public const int DEFAULT_Y = 400; + + public const int SHIP_DRAW_ORDER = 10; + + private TextureManager _textureAssetsManager; + public int DrawOrder { get; set; } = SHIP_DRAW_ORDER; + + // Note: you can add vectors together + public Vector2 Position { get; set; } = new Vector2(DEFAULT_X, DEFAULT_Y); + + // Note: This method needs more advanced setters (never set to below zero), define later + public float ShootingCooldown { get; set; } + + public Vector2 Speed { get; set; } + + public bool IsMovingDown { get; set; } = false; + public bool IsMovingUp { get; set; } = false; + public bool IsMovingLeft { get; set; } = false; + public bool IsMovingRight { get; set; } = false; + public EntityType entityType { get; set; } = EntityType.PLAYER; + public bool IsDead { get; set; } = false; + public float Size { get; set; } = 10f; + + public bool Die() + { + this.IsDead = true; + return true; + } + + public void Update(GameTime gameTime, PlayerShip player) + { + this.Speed = Vector2.Zero; + + if (this.IsMovingUp) + this.Speed = this.Speed + new Vector2(0, -SHIP_SPEED); + if (this.IsMovingDown) + this.Speed = this.Speed + new Vector2(0, SHIP_SPEED); + if (this.IsMovingLeft) + this.Speed = this.Speed + new Vector2(-SHIP_SPEED, 0); + if (this.IsMovingRight) + this.Speed = this.Speed + new Vector2(SHIP_SPEED, 0); + + this.Position = this.Position + new Vector2(this.Speed.X, this.Speed.Y) * (float)gameTime.ElapsedGameTime.TotalSeconds; + + this.ShootingCooldown = this.ShootingCooldown - (float)gameTime.ElapsedGameTime.TotalSeconds; + } + + public void Draw(GameTime gameTime, SpriteBatch spriteBatch) + { + if (spriteBatch != null) + { + spriteBatch.Draw(this._textureAssetsManager.PlayerShipTexture, this.Position - new Vector2(13,13), Color.White); + } + + } + + public bool Collide(IGameEntity other) + { + if(other.entityType == EntityType.ENEMY) + { + this.Die(); + return true; + } + return false; + } + + public PlayerShip(TextureManager textureManager) + { + this.Position = new Vector2(DEFAULT_X, DEFAULT_Y); + this._textureAssetsManager = textureManager; + } + + } +} diff --git a/shmupgame2022/Program.cs b/shmupgame2022/Program.cs new file mode 100644 index 0000000000000000000000000000000000000000..ad2e956fb2c7fbec80b706d4bbd48ad9b04f8997 --- /dev/null +++ b/shmupgame2022/Program.cs @@ -0,0 +1,14 @@ +using System; + +namespace shmupgame2022 +{ + public static class Program + { + [STAThread] + static void Main() + { + using (var game = new SHMUPgame()) + game.Run(); + } + } +} diff --git a/shmupgame2022/SHMUPgame.cs b/shmupgame2022/SHMUPgame.cs new file mode 100644 index 0000000000000000000000000000000000000000..de062f059583ed022ca4cc85e73d9895e2494375 --- /dev/null +++ b/shmupgame2022/SHMUPgame.cs @@ -0,0 +1,101 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; + +namespace shmupgame2022 +{ + public class SHMUPgame : Game + { + EntityManager _entityManager; + + private const string ASSET_NAME_BULLET_SPRITE = "sovproj2022_bullet_ph_sprite"; + private const string ASSET_NAME_ENEMY1_SPRITE = "sovproj2022_enemy1_ph_sprite"; + private const string ASSET_NAME_PLAYER_SPRITE = "sovproj2022_player_ph_sprite"; + private const string ASSET_NAME_GAME_OVER_SPRITE = "gameover"; + + private const string ASSET_NAME_EXPLOSION_SOUND = "Explosion"; + private const string ASSET_NAME_PLAYER_SHOOT_SOUND = "Laser_Shoot_player"; + private const string ASSET_NAME_ENEMY_SHOOT_SOUND = "laser_shoot_enemy"; + + private GraphicsDeviceManager _graphics; + private SpriteBatch _spriteBatch; + + //this is how to use sound effects in monogame + //private SoundEffect _sfx_shoot; + + private TextureManager _textureManager; + + + public SHMUPgame() + { + _graphics = new GraphicsDeviceManager(this); + _textureManager = new TextureManager(); + Content.RootDirectory = "Content"; + IsMouseVisible = true; + } + + protected override void Initialize() + { + _graphics.PreferredBackBufferWidth = 300; // set this value to the desired width of your window + _graphics.PreferredBackBufferHeight = 600; // set this value to the desired height of your window + _graphics.ApplyChanges(); + // TODO: Add your initialization logic here + _entityManager = new EntityManager(_textureManager); + + base.Initialize(); + } + + protected override void LoadContent() + { + _spriteBatch = new SpriteBatch(GraphicsDevice); + + // TODO: use this.Content to load your game content here + + _textureManager.PlayerBulletTexture = Content.Load<Texture2D>(ASSET_NAME_BULLET_SPRITE); + _textureManager.EnemyShipTexture = Content.Load<Texture2D>(ASSET_NAME_ENEMY1_SPRITE); + _textureManager.PlayerShipTexture = Content.Load<Texture2D>(ASSET_NAME_PLAYER_SPRITE); + _textureManager.GameOverUITexture = Content.Load<Texture2D>(ASSET_NAME_GAME_OVER_SPRITE); + + _textureManager.ShootSoundPlayer = Content.Load<SoundEffect>(ASSET_NAME_PLAYER_SHOOT_SOUND); + _textureManager.ShootSoundEnemy = Content.Load<SoundEffect>(ASSET_NAME_ENEMY_SHOOT_SOUND); + _textureManager.ExplosionSound = Content.Load<SoundEffect>(ASSET_NAME_EXPLOSION_SOUND); + + // It's very awkward to tell the EntityManager to spawn the player entity here, but it's the only way to do it after assets are loaded + // This is probably due to threading + _entityManager.SpawnPlayer(); + _entityManager.SpawnEnemyWave(7); + + } + + protected override void Update(GameTime gameTime) + { + // we leave this here for now + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) + Exit(); + + // TODO: Add your update logic here + _entityManager.UpdateEntities(gameTime); + base.Update(gameTime); + } + + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.Black); + + _spriteBatch.Begin(); + // TODO: Add your drawing code here + + // just for testing purposes, let's render the 3 loaded sprites on the screen + //_spriteBatch.Draw(_bulletSprite, new Vector2(20, 20), Color.White); + //_spriteBatch.Draw(_enemy1Sprite, new Vector2(40, 20), Color.White); + //_spriteBatch.Draw(_playerSprite, new Vector2(60, 20), Color.White); + + _entityManager.DrawEntities(_spriteBatch, gameTime); + + _spriteBatch.End(); + + base.Draw(gameTime); + } + } +} diff --git a/shmupgame2022/Sovproj 2022.ncp b/shmupgame2022/Sovproj 2022.ncp new file mode 100644 index 0000000000000000000000000000000000000000..3f8ae0f2176a4d4ffb7f80200926979ff02d417f --- /dev/null +++ b/shmupgame2022/Sovproj 2022.ncp @@ -0,0 +1,229 @@ +<Project> + <Name>Sovproj 2022</Name> + <ProjectItem type="NClass.DiagramEditor.ClassDiagram.Diagram" assembly="NClass.DiagramEditor, Version=2.4.1823.0, Culture=neutral, PublicKeyToken=null"> + <Name>SHMUP game</Name> + <Language>CSharp</Language> + <Entities> + <Entity type="Class"> + <Name>SHMUPgame</Name> + <Access>Public</Access> + <Location left="36" top="177" /> + <Size width="326" height="216" /> + <Collapsed>False</Collapsed> + <Member type="Field">EntityManager _entityManager</Member> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>PlayerShip</Name> + <Access>Public</Access> + <Location left="438" top="769" /> + <Size width="221" height="399" /> + <Collapsed>False</Collapsed> + <Member type="Field">private const int SHIP_HEIGHT = 20</Member> + <Member type="Field">private float SHIP_SPEED = 5f</Member> + <Member type="Field">private int SHIP_WIDTH = 20</Member> + <Member type="Property">public bool IsAlive { get; set; }</Member> + <Member type="Property">public Vector2 Position { get; set; }</Member> + <Member type="Property">public float ShootingCooldown { get; set; }</Member> + <Member type="Property">public Vector2 Speed { get; set; }</Member> + <Member type="Method">public bool IsMovingDown()</Member> + <Member type="Method">public bool IsMovingLeft()</Member> + <Member type="Method">public bool IsMovingRight()</Member> + <Member type="Method">public bool IsMovingUp()</Member> + <Member type="Method">public bool Die()</Member> + <Member type="Method">public void Draw(gameTime GameTime, spriteBatch SpriteBatch)</Member> + <Member type="Method">public bool Shoot()</Member> + <Member type="Method">public void Update(gameTime GameTime)</Member> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>EnemyShip</Name> + <Access>Public</Access> + <Location left="693" top="788" /> + <Size width="162" height="216" /> + <Collapsed>False</Collapsed> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>Bullet</Name> + <Access>Public</Access> + <Location left="895" top="88" /> + <Size width="162" height="216" /> + <Collapsed>False</Collapsed> + <Modifier>Abstract</Modifier> + </Entity> + <Entity type="Interface"> + <Name>IGameEntity</Name> + <Access>Public</Access> + <Location left="438" top="290" /> + <Size width="372" height="216" /> + <Collapsed>False</Collapsed> + <Member type="Method">void Update(GameTime gameTime)</Member> + <Member type="Method">void Draw(gameTime GameTime, SpriteBatch spriteBatch)</Member> + <Member type="Property">int DrawOrder { get; }</Member> + </Entity> + <Entity type="Class"> + <Name>Boss</Name> + <Access>Public</Access> + <Location left="980" top="769" /> + <Size width="162" height="216" /> + <Collapsed>False</Collapsed> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>BossSegment</Name> + <Access>Public</Access> + <Location left="1181" top="769" /> + <Size width="162" height="216" /> + <Collapsed>False</Collapsed> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>Game</Name> + <Access>Public</Access> + <Location left="36" top="29" /> + <Size width="162" height="216" /> + <Collapsed>True</Collapsed> + <Modifier>Abstract</Modifier> + </Entity> + <Entity type="Class"> + <Name>BossBar</Name> + <Access>Public</Access> + <Location left="895" top="340" /> + <Size width="269" height="216" /> + <Collapsed>False</Collapsed> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>InputController</Name> + <Access>Public</Access> + <Location left="783" top="1030" /> + <Size width="298" height="216" /> + <Collapsed>False</Collapsed> + <Member type="Field">private PlayerShip _playerShip</Member> + <Member type="Method">public void ProcessControls(gameTime GameTime)</Member> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>EntityManager</Name> + <Access>Public</Access> + <Location left="36" top="488" /> + <Size width="365" height="216" /> + <Collapsed>False</Collapsed> + <Member type="Field">private List<IGameEntity> _gameEntities</Member> + <Member type="Method">public void AddEntity(IGameEntity entity)</Member> + <Member type="Method">public void RemoveEntity(IGameEntity entity)</Member> + <Member type="Method">public void UpdateEntities(GameTime gameTime)</Member> + <Member type="Method">public void DrawEntities(SpriteBatch spriteBatch, GameTime gameTime)</Member> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>EnemyWaveManager</Name> + <Access>Public</Access> + <Location left="47" top="788" /> + <Size width="235" height="216" /> + <Collapsed>False</Collapsed> + <Member type="Method">public bool NextWave(GameTime gameTime)</Member> + <Member type="Property">public List<EnemyWave> WaveQueue { get; set; }</Member> + <Member type="Method">public void AddWave(EnemyWave enemyWave)</Member> + <Member type="Method">public EnemyWave RemoveWave()</Member> + <Modifier>None</Modifier> + </Entity> + <Entity type="Class"> + <Name>EnemyWave</Name> + <Access>Public</Access> + <Location left="47" top="1073" /> + <Size width="162" height="216" /> + <Collapsed>False</Collapsed> + <Member type="Property">public int EnemyNumber { get; set; }</Member> + <Member type="Property">public float SecondsToWave { get; set; }</Member> + <Modifier>None</Modifier> + </Entity> + </Entities> + <Relationships> + <Relationship type="Realization" first="1" second="4"> + <StartOrientation>Vertical</StartOrientation> + <EndOrientation>Vertical</EndOrientation> + <BendPoint relativeToStartShape="False"> + <X>478</X> + <Y>531</Y> + </BendPoint> + </Relationship> + <Relationship type="Realization" first="2" second="4"> + <StartOrientation>Vertical</StartOrientation> + <EndOrientation>Vertical</EndOrientation> + <BendPoint relativeToStartShape="False"> + <X>551</X> + <Y>535</Y> + </BendPoint> + </Relationship> + <Relationship type="Realization" first="3" second="4"> + <StartOrientation>Horizontal</StartOrientation> + <EndOrientation>Horizontal</EndOrientation> + <BendPoint relativeToStartShape="False"> + <X>835</X> + <Y>317</Y> + </BendPoint> + </Relationship> + <Relationship type="Generalization" first="0" second="7"> + <StartOrientation>Vertical</StartOrientation> + <EndOrientation>Vertical</EndOrientation> + <BendPoint relativeToStartShape="False"> + <X>139</X> + <Y>116</Y> + </BendPoint> + </Relationship> + <Relationship type="Realization" first="8" second="4"> + <StartOrientation>Horizontal</StartOrientation> + <EndOrientation>Horizontal</EndOrientation> + </Relationship> + <Relationship type="Association" first="9" second="1"> + <Label>controls</Label> + <StartOrientation>Horizontal</StartOrientation> + <EndOrientation>Horizontal</EndOrientation> + <Direction>Unidirectional</Direction> + <AssociationType>Aggregation</AssociationType> + </Relationship> + <Relationship type="Association" first="10" second="4"> + <Label> + </Label> + <StartOrientation>Vertical</StartOrientation> + <EndOrientation>Horizontal</EndOrientation> + <BendPoint relativeToStartShape="True"> + <X>235</X> + <Y>433</Y> + </BendPoint> + <Direction>Unidirectional</Direction> + <AssociationType>Aggregation</AssociationType> + </Relationship> + <Relationship type="Association" first="0" second="10"> + <Label> + </Label> + <StartOrientation>Vertical</StartOrientation> + <EndOrientation>Vertical</EndOrientation> + <BendPoint relativeToStartShape="True"> + <X>88</X> + <Y>418</Y> + </BendPoint> + <Direction>Unidirectional</Direction> + <AssociationType>Composition</AssociationType> + </Relationship> + <Relationship type="Association" first="11" second="12"> + <Label> + </Label> + <StartOrientation>Vertical</StartOrientation> + <EndOrientation>Vertical</EndOrientation> + <Direction>Unidirectional</Direction> + <AssociationType>Composition</AssociationType> + </Relationship> + <Relationship type="Association" first="10" second="11"> + <Label> + </Label> + <StartOrientation>Vertical</StartOrientation> + <EndOrientation>Vertical</EndOrientation> + <Direction>Unidirectional</Direction> + <AssociationType>Composition</AssociationType> + </Relationship> + </Relationships> + </ProjectItem> +</Project> \ No newline at end of file diff --git a/shmupgame2022/TextureManager.cs b/shmupgame2022/TextureManager.cs new file mode 100644 index 0000000000000000000000000000000000000000..446e633c3b23a94bcbde2752dc9123c7c82eabd9 --- /dev/null +++ b/shmupgame2022/TextureManager.cs @@ -0,0 +1,27 @@ +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022 +{ + public class TextureManager + { + public Texture2D PlayerShipTexture { get; set; } + public Texture2D PlayerBulletTexture { get; set; } + public Texture2D EnemyShipTexture { get; set; } + public Texture2D GameOverUITexture { get; set; } + + public SoundEffect ExplosionSound { get; set; } + public SoundEffect ShootSoundPlayer { get; set; } + public SoundEffect ShootSoundEnemy { get; set; } + + + public TextureManager() + { + + } + + } +} diff --git a/shmupgame2022/app.manifest b/shmupgame2022/app.manifest new file mode 100644 index 0000000000000000000000000000000000000000..657d45597984a8b64ab0f21aa0bf852cbe40f2b1 --- /dev/null +++ b/shmupgame2022/app.manifest @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> + <assemblyIdentity version="1.0.0.0" name="shmupgame2022"/> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> + <security> + <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + </requestedPrivileges> + </security> + </trustInfo> + + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!-- A list of the Windows versions that this application has been tested on and is + is designed to work with. Uncomment the appropriate elements and Windows will + automatically selected the most compatible environment. --> + + <!-- Windows Vista --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" /> + + <!-- Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" /> + + <!-- Windows 8 --> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" /> + + <!-- Windows 8.1 --> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /> + + <!-- Windows 10 --> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> + + </application> + </compatibility> + + <application xmlns="urn:schemas-microsoft-com:asm.v3"> + <windowsSettings> + <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware> + <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness> + </windowsSettings> + </application> + +</assembly> diff --git a/shmupgame2022/shmupgame2022.csproj b/shmupgame2022/shmupgame2022.csproj new file mode 100644 index 0000000000000000000000000000000000000000..db416ef1c41cdf5a885978285eee24aa6a25f999 --- /dev/null +++ b/shmupgame2022/shmupgame2022.csproj @@ -0,0 +1,30 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <OutputType>WinExe</OutputType> + <TargetFramework>netcoreapp3.1</TargetFramework> + <PublishReadyToRun>false</PublishReadyToRun> + <TieredCompilation>false</TieredCompilation> + </PropertyGroup> + <PropertyGroup> + <ApplicationManifest>app.manifest</ApplicationManifest> + <ApplicationIcon>Icon.ico</ApplicationIcon> + </PropertyGroup> + <ItemGroup> + <None Remove="Icon.ico" /> + <None Remove="Icon.bmp" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Icon.ico" /> + <EmbeddedResource Include="Icon.bmp" /> + </ItemGroup> + <ItemGroup> + <MonoGameContentReference Include="Content\Content.mgcb" /> + </ItemGroup> + <ItemGroup> + <TrimmerRootAssembly Include="Microsoft.Xna.Framework.Content.ContentTypeReader" Visible="false" /> + </ItemGroup> + <ItemGroup> + <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.0.1641" /> + <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.0.1641" /> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/shmupgame2022Test/UnitTest1.cs b/shmupgame2022Test/UnitTest1.cs new file mode 100644 index 0000000000000000000000000000000000000000..f69d6c6e5ce7edf5ee3a01d7e459c5f47a965b0c --- /dev/null +++ b/shmupgame2022Test/UnitTest1.cs @@ -0,0 +1,13 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace shmupgame2022Test +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + } + } +} diff --git a/shmupgame2022Test/shmupgame2022Test.csproj b/shmupgame2022Test/shmupgame2022Test.csproj new file mode 100644 index 0000000000000000000000000000000000000000..1c3ed2603a549acac16c848f99ac39a04de8c773 --- /dev/null +++ b/shmupgame2022Test/shmupgame2022Test.csproj @@ -0,0 +1,16 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netcoreapp3.1</TargetFramework> + + <IsPackable>false</IsPackable> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> + <PackageReference Include="MSTest.TestAdapter" Version="2.2.3" /> + <PackageReference Include="MSTest.TestFramework" Version="2.2.3" /> + <PackageReference Include="coverlet.collector" Version="3.0.2" /> + </ItemGroup> + +</Project> diff --git a/shmupgame2022Tests/PlayerShipTests.cs b/shmupgame2022Tests/PlayerShipTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..5aaba2e52a8eebc911a452b1a6d1e4a698a83dd2 --- /dev/null +++ b/shmupgame2022Tests/PlayerShipTests.cs @@ -0,0 +1,50 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.Xna.Framework; +using shmupgame2022; +using System; +using System.Collections.Generic; +using System.Text; + +namespace shmupgame2022.Tests +{ + [TestClass()] + public class PlayerShipTests + { + [TestMethod()] + public void DieTest() + { + PlayerShip testShip = new PlayerShip(new TextureManager()); + testShip.Die(); + Assert.IsTrue(testShip.IsDead); + } + + [TestMethod()] + public void UpdateTest() + { + PlayerShip testShip = new PlayerShip(new TextureManager()); + Vector2 initpos = testShip.Position; + testShip.Update(new GameTime(new TimeSpan(0, 1, 0), new TimeSpan(0, 0, 2), false), testShip); + if (initpos + testShip.Speed*2 != testShip.Position) + { + Assert.Fail(); + } + } + + [TestMethod()] + public void DrawTest() + { + PlayerShip testShip = new PlayerShip(new TextureManager()); + Assert.IsTrue(true); + // we don't unit test graphical methods, not sure how that'd be even possible + } + + [TestMethod()] + public void CollideTest() + { + PlayerShip testShip = new PlayerShip(new TextureManager()); + EnemyShip testEnemyShip = new EnemyShip(new TextureManager(), new Microsoft.Xna.Framework.Vector2(0,0)); + testShip.Collide(testEnemyShip); + Assert.IsTrue(testShip.IsDead); + } + } +} \ No newline at end of file diff --git a/shmupgame2022Tests/shmupgame2022Tests.csproj b/shmupgame2022Tests/shmupgame2022Tests.csproj new file mode 100644 index 0000000000000000000000000000000000000000..e6e6829cc1956f992cb5582419fc365c3278929a --- /dev/null +++ b/shmupgame2022Tests/shmupgame2022Tests.csproj @@ -0,0 +1,20 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>.NETCoreApp,Version=v3.1</TargetFramework> + + <IsPackable>false</IsPackable> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> + <PackageReference Include="MSTest.TestAdapter" Version="2.2.3" /> + <PackageReference Include="MSTest.TestFramework" Version="2.2.3" /> + <PackageReference Include="coverlet.collector" Version="3.0.2" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\shmupgame2022\shmupgame2022.csproj" /> + </ItemGroup> + +</Project>