Browse Source

AsteroidBeltAssault update to SDK project and pointing 3.8.* on all 4 platforms.

CartBlanche 4 weeks ago
parent
commit
7b6f34163a
41 changed files with 2393 additions and 0 deletions
  1. 47 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/.vscode/launch.json
  2. 67 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/.vscode/tasks.json
  3. 113 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/AsteroidBeltAssault.sln
  4. 13 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/AsteroidBeltAssault.Core.csproj
  5. 210 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/AsteroidManager.cs
  6. 144 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/CollisionManager.cs
  7. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Fonts/Pericles14.xnb
  8. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Game.ico
  9. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/GameThumbnail.png
  10. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion1.xnb
  11. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion2.xnb
  12. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion3.xnb
  13. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion4.xnb
  14. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Shot1.xnb
  15. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Shot2.xnb
  16. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Textures/SpriteSheet.xnb
  17. BIN
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Textures/TitleScreen.xnb
  18. 123 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Enemy.cs
  19. 195 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/EnemyManager.cs
  20. 132 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/ExplosionManager.cs
  21. 317 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Game1.cs
  22. 92 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Particle.cs
  23. 174 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/PlayerManager.cs
  24. 95 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/ShotManager.cs
  25. 81 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/SoundManager.cs
  26. 173 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Sprite.cs
  27. 65 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/StarField.cs
  28. 18 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/AndroidManifest.xml
  29. 36 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/AsteroidBeltAssault.Android.csproj
  30. 30 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/MainActivity.cs
  31. 4 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/Resources/values/strings.xml
  32. 5 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/Resources/values/styles.xml
  33. 29 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/DesktopGL/AsteroidBeltAssault.DesktopGL.csproj
  34. 14 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/DesktopGL/Program.cs
  35. 30 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Windows/AsteroidBeltAssault.Windows.csproj
  36. 14 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Windows/Program.cs
  37. 44 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/AppDelegate.cs
  38. 33 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/AsteroidBeltAssault.iOS.csproj
  39. 16 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/Info.plist
  40. 12 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/Program.cs
  41. 67 0
      XNAGameDevelopmentbyExample/AsteroidBeltAssault/README.md

+ 47 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/.vscode/launch.json

@@ -0,0 +1,47 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Run Windows",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-windows",
+            "program": "${workspaceFolder}/Platforms/Windows/bin/Debug/net8.0-windows/AsteroidBeltAssault.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "console": "externalTerminal",
+            "stopAtEntry": false
+        },
+        {
+            "name": "Run Desktop",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl",
+            "program": "${workspaceFolder}/Platforms/DesktopGL/bin/Debug/net8.0/AsteroidBeltAssault",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "console": "externalTerminal",
+            "stopAtEntry": false
+        }
+        ,
+        {
+            "name": "Debug Android",
+            "type": "mono",
+            "request": "attach",
+            "address": "localhost",
+            "port": 10000,
+			"preLaunchTask": "build-deploy-android"
+        },
+        {
+            "name": "Run iOS",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-ios",
+            "program": "${workspaceFolder}/Platforms/iOS//bin/Debug/net8.0-ios/AsteroidBeltAssault",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "console": "externalTerminal",
+            "stopAtEntry": false
+        }
+    ]
+}

+ 67 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/.vscode/tasks.json

@@ -0,0 +1,67 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build-windows",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "${workspaceFolder}/Platforms/Windows/AsteroidBeltAssault.Windows.csproj"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "silent",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-desktopgl",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "${workspaceFolder}/Platforms/DesktopGL/AsteroidBeltAssault.DesktopGL.csproj"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "silent",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+			"label": "build-deploy-android",
+			"type": "shell",
+			"command": "dotnet build -p:Configuration=Debug ${workspaceFolder}/Platforms/Android/AsteroidBeltAssault.Android.csproj \"/t:Install\" /p:AndroidAttachDebugger=true /p:AndroidSdbHostPort=10000"
+		},
+        {
+            "label": "build-ios",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "${workspaceFolder}/Platforms/iOS/AsteroidBeltAssault.iOS.csproj"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "silent",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            },
+            "problemMatcher": "$msCompile"
+        }
+    ]
+}

+ 113 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/AsteroidBeltAssault.sln

@@ -0,0 +1,113 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{324791A1-5798-203D-0CA6-A8E0DAEC81C8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windows", "Windows", "{E4D925BB-EB21-135E-07FA-7558DA769730}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsteroidBeltAssault.Windows", "Platforms\Windows\AsteroidBeltAssault.Windows.csproj", "{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesktopGL", "DesktopGL", "{91D1BC8C-EC53-FBF8-D730-71448E1710A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsteroidBeltAssault.DesktopGL", "Platforms\DesktopGL\AsteroidBeltAssault.DesktopGL.csproj", "{192C529B-5DEC-43B6-B88E-B35106B7D8E1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Android", "Android", "{C12F4581-1215-E9D3-7920-679DE6ABBC05}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsteroidBeltAssault.Android", "Platforms\Android\AsteroidBeltAssault.Android.csproj", "{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "iOS", "iOS", "{3260BC3A-D039-20BF-4861-22673C64F5D4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsteroidBeltAssault.iOS", "Platforms\iOS\AsteroidBeltAssault.iOS.csproj", "{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsteroidBeltAssault.Core", "Core\AsteroidBeltAssault.Core.csproj", "{5AF4E344-0595-44F7-BDD5-C34646CA68D0}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Debug|x64.Build.0 = Debug|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Debug|x86.Build.0 = Debug|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Release|x64.ActiveCfg = Release|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Release|x64.Build.0 = Release|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Release|x86.ActiveCfg = Release|Any CPU
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D}.Release|x86.Build.0 = Release|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Debug|x64.Build.0 = Debug|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Debug|x86.Build.0 = Debug|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Release|x64.ActiveCfg = Release|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Release|x64.Build.0 = Release|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Release|x86.ActiveCfg = Release|Any CPU
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1}.Release|x86.Build.0 = Release|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Debug|x64.Build.0 = Debug|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Debug|x86.Build.0 = Debug|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Release|Any CPU.Build.0 = Release|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Release|x64.ActiveCfg = Release|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Release|x64.Build.0 = Release|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Release|x86.ActiveCfg = Release|Any CPU
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19}.Release|x86.Build.0 = Release|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Debug|x64.Build.0 = Debug|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Debug|x86.Build.0 = Debug|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Release|x64.ActiveCfg = Release|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Release|x64.Build.0 = Release|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Release|x86.ActiveCfg = Release|Any CPU
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11}.Release|x86.Build.0 = Release|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Debug|x64.Build.0 = Debug|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Debug|x86.Build.0 = Debug|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Release|x64.ActiveCfg = Release|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Release|x64.Build.0 = Release|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Release|x86.ActiveCfg = Release|Any CPU
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{E4D925BB-EB21-135E-07FA-7558DA769730} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{6AC9E90A-DCB4-42AB-B865-A0D8CBB3C50D} = {E4D925BB-EB21-135E-07FA-7558DA769730}
+		{91D1BC8C-EC53-FBF8-D730-71448E1710A6} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{192C529B-5DEC-43B6-B88E-B35106B7D8E1} = {91D1BC8C-EC53-FBF8-D730-71448E1710A6}
+		{C12F4581-1215-E9D3-7920-679DE6ABBC05} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{8BE0DBF9-B420-48FE-A1F5-2C253E9EDA19} = {C12F4581-1215-E9D3-7920-679DE6ABBC05}
+		{3260BC3A-D039-20BF-4861-22673C64F5D4} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{CE4F2062-B39E-49F4-91DF-A6AB3BD95F11} = {3260BC3A-D039-20BF-4861-22673C64F5D4}
+		{5AF4E344-0595-44F7-BDD5-C34646CA68D0} = {FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6}
+	EndGlobalSection
+EndGlobal

+ 13 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/AsteroidBeltAssault.Core.csproj

@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+
+</Project>

+ 210 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/AsteroidManager.cs

@@ -0,0 +1,210 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class AsteroidManager
+    {
+        private int screenWidth = 800;
+        private int screenHeight = 600;
+        private int screenPadding = 10;
+
+        private Rectangle initialFrame;
+        private int asteroidFrames;
+        private Texture2D texture;
+
+        public List<Sprite> Asteroids = new List<Sprite>();
+        private int minSpeed = 60;
+        private int maxSpeed = 120;
+
+        private Random rand = new Random();
+
+        public void AddAsteroid()
+        {
+            Sprite newAsteroid = new Sprite(
+                new Vector2(-500, -500),
+                texture,
+                initialFrame,
+                Vector2.Zero);
+            for (int x = 1; x < asteroidFrames; x++)
+            {
+                newAsteroid.AddFrame(new Rectangle(
+                    initialFrame.X + (initialFrame.Width * x),
+                    initialFrame.Y,
+                    initialFrame.Width,
+                    initialFrame.Height));
+            }
+            newAsteroid.Rotation =
+                MathHelper.ToRadians((float)rand.Next(0, 360));
+            newAsteroid.CollisionRadius = 15;
+            Asteroids.Add(newAsteroid);
+        }
+
+        public void Clear()
+        {
+            Asteroids.Clear();
+        }
+
+        public AsteroidManager(
+            int asteroidCount,
+            Texture2D texture,
+            Rectangle initialFrame,
+            int asteroidFrames,    
+            int screenWidth,
+            int screenHeight)
+        {
+            this.texture = texture;
+            this.initialFrame = initialFrame;
+            this.asteroidFrames = asteroidFrames;
+            this.screenWidth = screenWidth;
+            this.screenHeight = screenHeight;
+            for (int x = 0; x < asteroidCount; x++)
+            {
+                AddAsteroid();
+            }
+        }
+
+        private Vector2 randomLocation()
+        {
+            Vector2 location = Vector2.Zero;
+            bool locationOK = true;
+            int tryCount = 0;
+
+            do
+            {
+                locationOK = true;
+                switch (rand.Next(0, 3))
+                {
+                    case 0:
+                        location.X = -initialFrame.Width;
+                        location.Y = rand.Next(0, screenHeight);
+                        break;
+
+                    case 1:
+                        location.X = screenWidth;
+                        location.Y = rand.Next(0, screenHeight);
+                        break;
+
+                    case 2:
+                        location.X = rand.Next(0, screenWidth);
+                        location.Y = -initialFrame.Height;
+                        break;
+
+                }
+                foreach (Sprite asteroid in Asteroids)
+                {
+                    if (asteroid.IsBoxColliding(
+                        new Rectangle(
+                            (int)location.X,
+                            (int)location.Y,
+                            initialFrame.Width,
+                            initialFrame.Height)))
+                    {
+                        locationOK = false;
+                    }
+                }
+                tryCount++;
+                if ((tryCount > 5) && locationOK == false)
+                {
+                    location = new Vector2(-500, -500);
+                    locationOK = true;
+                }
+            } while (locationOK == false);
+
+            return location;
+        }
+
+        private Vector2 randomVelocity()
+        {
+            Vector2 velocity = new Vector2(
+                rand.Next(0, 101) - 50,
+                rand.Next(0, 101) - 50);
+            velocity.Normalize();
+            velocity *= rand.Next(minSpeed, maxSpeed);
+            return velocity;
+        }
+
+        private bool isOnScreen(Sprite asteroid)
+        {
+            if (asteroid.Destination.Intersects(
+                new Rectangle(
+                    -screenPadding,
+                    -screenPadding,
+                    screenWidth + screenPadding,
+                    screenHeight + screenPadding)
+                    )
+                )
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        private void BounceAsteroids(Sprite asteroid1, Sprite asteroid2)
+        {
+            {
+                Vector2 cOfMass = (asteroid1.Velocity +
+                    asteroid2.Velocity) / 2;
+
+                Vector2 normal1 = asteroid2.Center - asteroid1.Center;
+                normal1.Normalize();
+                Vector2 normal2 = asteroid1.Center - asteroid2.Center;
+                normal2.Normalize();
+
+                asteroid1.Velocity -= cOfMass;
+                asteroid1.Velocity =
+                    Vector2.Reflect(asteroid1.Velocity, normal1);
+                asteroid1.Velocity += cOfMass;
+
+                asteroid2.Velocity -= cOfMass;
+                asteroid2.Velocity =
+                    Vector2.Reflect(asteroid2.Velocity, normal2);
+
+                asteroid2.Velocity += cOfMass;
+            }
+        }
+
+        public void Update(GameTime gameTime)
+        {
+            foreach (Sprite asteroid in Asteroids)
+            {
+                asteroid.Update(gameTime);
+                if (!isOnScreen(asteroid))
+                {
+                    asteroid.Location = randomLocation();
+                    asteroid.Velocity = randomVelocity();
+                }
+            }
+
+            for (int x = 0; x < Asteroids.Count; x++)
+            {
+                for (int y = x + 1; y < Asteroids.Count; y++)
+                {
+                    if (Asteroids[x].IsCircleColliding(
+                        Asteroids[y].Center, Asteroids[y].CollisionRadius))
+                    {
+                        BounceAsteroids(Asteroids[x], Asteroids[y]);
+                    }
+                }
+            }
+        }
+
+
+        public void Draw(SpriteBatch spriteBatch)
+        {
+            foreach (Sprite asteroid in Asteroids)
+            {
+                asteroid.Draw(spriteBatch);
+            }
+        }
+
+
+    }
+}

+ 144 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/CollisionManager.cs

@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+
+namespace Asteroid_Belt_Assault
+{
+    class CollisionManager
+    {
+        private AsteroidManager asteroidManager;
+        private PlayerManager playerManager;
+        private EnemyManager enemyManager;
+        private ExplosionManager explosionManager;
+        private Vector2 offScreen = new Vector2(-500, -500);
+        private Vector2 shotToAsteroidImpact = new Vector2(0, -20);
+        private int enemyPointValue = 100;
+
+        public CollisionManager(
+            AsteroidManager asteroidManager,
+            PlayerManager playerManager,
+            EnemyManager enemyManager,
+            ExplosionManager explosionManager)
+        {
+            this.asteroidManager = asteroidManager;
+            this.playerManager = playerManager;
+            this.enemyManager = enemyManager;
+            this.explosionManager = explosionManager;
+        }
+
+        private void checkShotToEnemyCollisions()
+        {
+            foreach (Sprite shot in playerManager.PlayerShotManager.Shots)
+            {
+                foreach (Enemy enemy in enemyManager.Enemies)
+                {
+                    if (shot.IsCircleColliding(
+                        enemy.EnemySprite.Center,
+                        enemy.EnemySprite.CollisionRadius))
+                    {
+                        shot.Location = offScreen;
+                        enemy.Destroyed = true;
+                        playerManager.PlayerScore += enemyPointValue;
+                        explosionManager.AddExplosion(
+                            enemy.EnemySprite.Center,
+                            enemy.EnemySprite.Velocity / 10);
+                    }
+
+                }
+            }
+        }
+
+        private void checkShotToAsteroidCollisions()
+        {
+            foreach (Sprite shot in playerManager.PlayerShotManager.Shots)
+            {
+                foreach (Sprite asteroid in asteroidManager.Asteroids)
+                {
+                    if (shot.IsCircleColliding(
+                        asteroid.Center,
+                        asteroid.CollisionRadius))
+                    {
+                        shot.Location = offScreen;
+                        asteroid.Velocity += shotToAsteroidImpact;
+                    }
+                }
+            }
+        }
+
+        private void checkShotToPlayerCollisions()
+        {
+            foreach (Sprite shot in enemyManager.EnemyShotManager.Shots)
+            {
+                if (shot.IsCircleColliding(
+                    playerManager.playerSprite.Center,
+                    playerManager.playerSprite.CollisionRadius))
+                {
+                    shot.Location = offScreen;
+                    playerManager.Destroyed = true;
+                    explosionManager.AddExplosion(
+                        playerManager.playerSprite.Center,
+                        Vector2.Zero);
+                }
+            }
+        }
+
+        private void checkEnemyToPlayerCollisions()
+        {
+            foreach (Enemy enemy in enemyManager.Enemies)
+            {
+                if (enemy.EnemySprite.IsCircleColliding(
+                    playerManager.playerSprite.Center,
+                    playerManager.playerSprite.CollisionRadius))
+                {
+                    enemy.Destroyed = true;
+                    explosionManager.AddExplosion(
+                        enemy.EnemySprite.Center,
+                        enemy.EnemySprite.Velocity / 10);
+
+                    playerManager.Destroyed = true;
+
+                    explosionManager.AddExplosion(
+                        playerManager.playerSprite.Center,
+                        Vector2.Zero);
+                }
+            }
+        }
+
+        private void checkAsteroidToPlayerCollisions()
+        {
+            foreach (Sprite asteroid in asteroidManager.Asteroids)
+            {
+                if (asteroid.IsCircleColliding(
+                    playerManager.playerSprite.Center,
+                    playerManager.playerSprite.CollisionRadius))
+                {
+                    explosionManager.AddExplosion(
+                        asteroid.Center,
+                        asteroid.Velocity / 10);
+
+                    asteroid.Location = offScreen;
+
+                    playerManager.Destroyed = true;
+                    explosionManager.AddExplosion(
+                        playerManager.playerSprite.Center,
+                        Vector2.Zero);
+                }
+            }
+        }
+
+        public void CheckCollisions()
+        {
+            checkShotToEnemyCollisions();
+            checkShotToAsteroidCollisions();
+            if (!playerManager.Destroyed)
+            {
+                checkShotToPlayerCollisions();
+                checkEnemyToPlayerCollisions();
+                checkAsteroidToPlayerCollisions();
+            }
+        }
+
+    }
+}

BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Fonts/Pericles14.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Game.ico


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/GameThumbnail.png


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion1.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion2.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion3.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Explosion4.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Shot1.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Sounds/Shot2.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Textures/SpriteSheet.xnb


BIN
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Content/Textures/TitleScreen.xnb


+ 123 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Enemy.cs

@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class Enemy
+    {
+        public Sprite EnemySprite;
+        public Vector2 gunOffset = new Vector2(25, 25);
+        private Queue<Vector2> waypoints = new Queue<Vector2>();
+        private Vector2 currentWaypoint = Vector2.Zero;
+        private float speed = 120f;
+        public bool Destroyed = false;
+        private int enemyRadius = 15;
+        private Vector2 previousLocation = Vector2.Zero;
+
+        public Enemy(
+            Texture2D texture,
+            Vector2 location,
+            Rectangle initialFrame,
+            int frameCount)
+        {
+            EnemySprite = new Sprite(
+                location,
+                texture,
+                initialFrame,
+                Vector2.Zero);
+
+            for (int x = 1; x < frameCount; x++)
+            {
+                EnemySprite.AddFrame(
+                    new Rectangle(
+                    initialFrame.X = (initialFrame.Width * x),
+                    initialFrame.Y,
+                    initialFrame.Width,
+                    initialFrame.Height));
+            }
+            previousLocation = location;
+            currentWaypoint = location;
+            EnemySprite.CollisionRadius = enemyRadius;
+        }
+
+        public void AddWaypoint(Vector2 waypoint)
+        {
+            waypoints.Enqueue(waypoint);
+        }
+
+        public bool WaypointReached()
+        {
+            if (Vector2.Distance(EnemySprite.Location, currentWaypoint) <
+                (float)EnemySprite.Source.Width / 2)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        public bool IsActive()
+        {
+            if (Destroyed)
+            {
+                return false;
+            }
+
+            if (waypoints.Count > 0)
+            {
+                return true;
+            }
+
+            if (WaypointReached())
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        public void Update(GameTime gameTime)
+        {
+            if (IsActive())
+            {
+                Vector2 heading = currentWaypoint - EnemySprite.Location;
+                if (heading != Vector2.Zero)
+                {
+                    heading.Normalize();
+                }
+                heading *= speed;
+                EnemySprite.Velocity = heading;
+                previousLocation = EnemySprite.Location;
+                EnemySprite.Update(gameTime);
+                EnemySprite.Rotation =
+                    (float)Math.Atan2(
+                    EnemySprite.Location.Y - previousLocation.Y,
+                    EnemySprite.Location.X - previousLocation.X);
+
+                if (WaypointReached())
+                {
+                    if (waypoints.Count > 0)
+                    {
+                        currentWaypoint = waypoints.Dequeue();
+                    }
+                }
+            }
+        }
+
+        public void Draw(SpriteBatch spriteBatch)
+        {
+            if (IsActive())
+            {
+                EnemySprite.Draw(spriteBatch);
+            }
+        }
+
+
+    }
+}

+ 195 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/EnemyManager.cs

@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class EnemyManager
+    {
+        private Texture2D texture;
+        private Rectangle initialFrame;
+        private int frameCount;
+
+        public List<Enemy> Enemies = new List<Enemy>();
+
+        public ShotManager EnemyShotManager;
+        private PlayerManager playerManager;
+
+        public int MinShipsPerWave = 5;
+        public int MaxShipsPerWave = 8;
+        private float nextWaveTimer = 0.0f;
+        private float nextWaveMinTimer = 8.0f;
+        private float shipSpawnTimer = 0.0f;
+        private float shipSpawnWaitTime = 0.5f;
+
+        private float shipShotChance = 0.2f;
+
+        private List<List<Vector2>> pathWaypoints =
+            new List<List<Vector2>>();
+
+        private Dictionary<int, int> waveSpawns = new Dictionary<int, int>();
+
+        public bool Active = false;
+
+        private Random rand = new Random();
+
+        private void setUpWaypoints()
+        {
+            List<Vector2> path0 = new List<Vector2>();
+            path0.Add(new Vector2(850, 300));
+            path0.Add(new Vector2(-100, 300));
+            pathWaypoints.Add(path0);
+            waveSpawns[0] = 0;
+
+            List<Vector2> path1 = new List<Vector2>();
+            path1.Add(new Vector2(-50, 225));
+            path1.Add(new Vector2(850, 225));
+            pathWaypoints.Add(path1);
+            waveSpawns[1] = 0;
+
+            List<Vector2> path2 = new List<Vector2>();
+            path2.Add(new Vector2(-100, 50));
+            path2.Add(new Vector2(150, 50));
+            path2.Add(new Vector2(200, 75));
+            path2.Add(new Vector2(200, 125));
+            path2.Add(new Vector2(150, 150));
+            path2.Add(new Vector2(150, 175));
+            path2.Add(new Vector2(200, 200));
+            path2.Add(new Vector2(600, 200));
+            path2.Add(new Vector2(850, 600));
+            pathWaypoints.Add(path2);
+            waveSpawns[2] = 0;
+
+            List<Vector2> path3 = new List<Vector2>();
+            path3.Add(new Vector2(600, -100));
+            path3.Add(new Vector2(600, 250));
+            path3.Add(new Vector2(580, 275));
+            path3.Add(new Vector2(500, 250));
+            path3.Add(new Vector2(500, 200));
+            path3.Add(new Vector2(450, 175));
+            path3.Add(new Vector2(400, 150));
+            path3.Add(new Vector2(-100, 150));
+            pathWaypoints.Add(path3);
+            waveSpawns[3] = 0;
+        }
+
+        public EnemyManager(
+            Texture2D texture,
+            Rectangle initialFrame,
+            int frameCount,
+            PlayerManager playerManager,
+            Rectangle screenBounds)
+        {
+            this.texture = texture;
+            this.initialFrame = initialFrame;
+            this.frameCount = frameCount;
+            this.playerManager = playerManager;
+
+            EnemyShotManager = new ShotManager(
+                texture,
+                new Rectangle(0, 300, 5, 5),
+                    4,
+                    2,
+                    150f,
+                    screenBounds);
+
+            setUpWaypoints();
+        }
+
+        public void SpawnEnemy(int path)
+        {
+            Enemy thisEnemy = new Enemy(
+                texture,
+                pathWaypoints[path][0],
+                initialFrame,
+                frameCount);
+            for (int x = 0; x < pathWaypoints[path].Count(); x++)
+            {
+                thisEnemy.AddWaypoint(pathWaypoints[path][x]);
+            }
+            Enemies.Add(thisEnemy);
+        }
+
+        public void SpawnWave(int waveType)
+        {
+            waveSpawns[waveType] +=
+                rand.Next(MinShipsPerWave, MaxShipsPerWave + 1);
+        }
+
+        private void updateWaveSpawns(GameTime gameTime)
+        {
+            shipSpawnTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
+            if (shipSpawnTimer > shipSpawnWaitTime)
+            {
+                for (int x = waveSpawns.Count - 1; x >= 0; x--)
+                {
+                    if (waveSpawns[x] > 0)
+                    {
+                        waveSpawns[x]--;
+                        SpawnEnemy(x);
+                    }
+                }
+                shipSpawnTimer = 0f;
+            }
+
+            nextWaveTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
+            if (nextWaveTimer > nextWaveMinTimer)
+            {
+                SpawnWave(rand.Next(0, pathWaypoints.Count));
+                nextWaveTimer = 0f;
+            }
+        }
+
+        public void Update(GameTime gameTime)
+        {
+            EnemyShotManager.Update(gameTime);
+
+            for (int x = Enemies.Count - 1; x >= 0; x--)
+            {
+                Enemies[x].Update(gameTime);
+                if (Enemies[x].IsActive() == false)
+                {
+                    Enemies.RemoveAt(x);
+                }
+                else
+                {
+                    if ((float)rand.Next(0, 1000) / 10 <= shipShotChance)
+                    {
+                        Vector2 fireLoc = Enemies[x].EnemySprite.Location;
+                        fireLoc += Enemies[x].gunOffset;
+
+                        Vector2 shotDirection =
+                            playerManager.playerSprite.Center -
+                            fireLoc;
+
+                        shotDirection.Normalize();
+
+                        EnemyShotManager.FireShot(
+                            fireLoc,
+                            shotDirection,
+                            false);
+                    }
+                }
+            }
+
+            if (Active)
+            {
+                updateWaveSpawns(gameTime);
+            }
+        }
+
+        public void Draw(SpriteBatch spriteBatch)
+        {
+            EnemyShotManager.Draw(spriteBatch);
+
+            foreach (Enemy enemy in Enemies)
+            {
+                enemy.Draw(spriteBatch);
+            }
+        }
+
+    }
+}

+ 132 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/ExplosionManager.cs

@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class ExplosionManager
+    {
+        private Texture2D texture;
+        private List<Rectangle> pieceRectangles = new List<Rectangle>();
+        private Rectangle pointRectangle;
+
+        private int minPieceCount = 3;
+        private int maxPieceCount = 6;
+        private int minPointCount = 20;
+        private int maxPointCount = 30;
+
+        private int durationCount = 90;
+        private float explosionMaxSpeed = 30f;
+
+        private float pieceSpeedScale = 6f;
+        private int pointSpeedMin = 15;
+        private int pointSpeedMax = 30;
+
+        private Color initialColor = new Color(1.0f, 0.3f, 0f) * 0.5f;
+        private Color finalColor = new Color(0f, 0f, 0f, 0f);
+
+        Random rand = new Random();
+
+        private List<Particle> ExplosionParticles = new List<Particle>();
+
+        public ExplosionManager(
+            Texture2D texture,
+            Rectangle initialFrame,
+            int pieceCount,
+            Rectangle pointRectangle)
+        {
+            this.texture = texture;
+            for (int x = 0; x < pieceCount; x++)
+            {
+                pieceRectangles.Add(new Rectangle(
+                    initialFrame.X + (initialFrame.Width * x),
+                    initialFrame.Y,
+                    initialFrame.Width,
+                    initialFrame.Height));
+            }
+            this.pointRectangle = pointRectangle;
+        }
+
+        public Vector2 randomDirection(float scale)
+        {
+            Vector2 direction;
+            do
+            {
+                direction = new Vector2(
+                rand.Next(0, 101) - 50,
+                rand.Next(0, 101) - 50);
+            } while (direction.Length() == 0);
+            direction.Normalize();
+            direction *= scale;
+
+            return direction;
+        }
+
+        public void AddExplosion(Vector2 location, Vector2 momentum)
+        {
+            Vector2 pieceLocation = location -
+                new Vector2(pieceRectangles[0].Width / 2,
+                    pieceRectangles[0].Height / 2);
+
+            int pieces = rand.Next(minPieceCount, maxPieceCount + 1);
+            for (int x = 0; x < pieces; x++)
+            {
+                ExplosionParticles.Add(new Particle(
+                    pieceLocation,
+                    texture,
+                    pieceRectangles[rand.Next(0, pieceRectangles.Count)],
+                    randomDirection(pieceSpeedScale) + momentum,
+                    Vector2.Zero,
+                    explosionMaxSpeed,
+                    durationCount,
+                    initialColor,
+                    finalColor));
+            }
+
+            int points = rand.Next(minPointCount, maxPointCount + 1);
+            for (int x = 0; x < points; x++)
+            {
+                ExplosionParticles.Add(new Particle(
+                    location,
+                    texture,
+                    pointRectangle,
+                    randomDirection((float)rand.Next(
+                        pointSpeedMin, pointSpeedMax)) + momentum,
+                    Vector2.Zero,
+                    explosionMaxSpeed,
+                    durationCount,
+                    initialColor,
+                    finalColor));
+
+            }
+            SoundManager.PlayExplosion();
+        }
+
+        public void Update(GameTime gameTime)
+        {
+            for (int x = ExplosionParticles.Count - 1; x >= 0; x--)
+            {
+                if (ExplosionParticles[x].IsActive)
+                {
+                    ExplosionParticles[x].Update(gameTime);
+                }
+                else
+                {
+                    ExplosionParticles.RemoveAt(x);
+                }
+            }
+        }
+
+        public void Draw(SpriteBatch spriteBatch)
+        {
+            foreach (Particle particle in ExplosionParticles)
+            {
+                particle.Draw(spriteBatch);
+            }
+        }
+
+    }
+}

+ 317 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Game1.cs

@@ -0,0 +1,317 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Media;
+
+namespace Asteroid_Belt_Assault
+{
+    /// <summary>
+    /// This is the main type for your game
+    /// </summary>
+    public class Game1 : Microsoft.Xna.Framework.Game
+    {
+        GraphicsDeviceManager graphics;
+        SpriteBatch spriteBatch;
+
+        enum GameStates { TitleScreen, Playing, PlayerDead, GameOver };
+        GameStates gameState = GameStates.TitleScreen;
+        Texture2D titleScreen;
+        Texture2D spriteSheet;
+
+        StarField starField;
+        AsteroidManager asteroidManager;
+        PlayerManager playerManager;
+        EnemyManager enemyManager;
+        ExplosionManager explosionManager;
+
+        CollisionManager collisionManager;
+
+        SpriteFont pericles14;
+
+        private float playerDeathDelayTime = 10f;
+        private float playerDeathTimer = 0f;
+        private float titleScreenTimer = 0f;
+        private float titleScreenDelayTime = 1f;
+
+        private int playerStartingLives = 3;
+        private Vector2 playerStartLocation = new Vector2(390, 550);
+        private Vector2 scoreLocation = new Vector2(20, 10);
+        private Vector2 livesLocation = new Vector2(20, 25);
+
+
+        public Game1()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+        }
+
+        /// <summary>
+        /// Allows the game to perform any initialization it needs to before starting to run.
+        /// This is where it can query for any required services and load any non-graphic
+        /// related content.  Calling base.Initialize will enumerate through any components
+        /// and initialize them as well.
+        /// </summary>
+        protected override void Initialize()
+        {
+            // TODO: Add your initialization logic here
+
+            base.Initialize();
+        }
+
+        /// <summary>
+        /// LoadContent will be called once per game and is the place to load
+        /// all of your content.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            // Create a new SpriteBatch, which can be used to draw textures.
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+
+            titleScreen = Content.Load<Texture2D>(@"Textures\TitleScreen");
+            spriteSheet = Content.Load<Texture2D>(@"Textures\spriteSheet");
+
+            starField = new StarField(
+                this.Window.ClientBounds.Width,
+                this.Window.ClientBounds.Height,
+                200,
+                new Vector2(0, 30f),
+                spriteSheet,
+                new Rectangle(0, 450, 2, 2));
+
+            asteroidManager = new AsteroidManager(
+                10,
+                spriteSheet,
+                new Rectangle(0, 0, 50, 50),
+                20,
+                this.Window.ClientBounds.Width,
+                this.Window.ClientBounds.Height);
+
+            playerManager = new PlayerManager(
+                spriteSheet,    
+                new Rectangle(0, 150, 50, 50),    
+                3,
+                new Rectangle(
+                    0,
+                    0,
+                    this.Window.ClientBounds.Width,
+                    this.Window.ClientBounds.Height));
+
+            enemyManager = new EnemyManager(
+                spriteSheet,
+                new Rectangle(0, 200, 50, 50),
+                6,
+                playerManager,
+                new Rectangle(
+                    0,
+                    0,
+                    this.Window.ClientBounds.Width,
+                    this.Window.ClientBounds.Height));
+
+            explosionManager = new ExplosionManager(
+                spriteSheet,
+                new Rectangle(0, 100, 50, 50),
+                3,
+                new Rectangle(0, 450, 2, 2));
+
+            collisionManager = new CollisionManager(
+                asteroidManager,
+                playerManager,
+                enemyManager,
+                explosionManager);
+
+            SoundManager.Initialize(Content);
+
+            pericles14 = Content.Load<SpriteFont>(@"Fonts\Pericles14");
+
+
+            // TODO: use this.Content to load your game content here
+        }
+
+        /// <summary>
+        /// UnloadContent will be called once per game and is the place to unload
+        /// all content.
+        /// </summary>
+        protected override void UnloadContent()
+        {
+            // TODO: Unload any non ContentManager content here
+        }
+
+        private void resetGame()
+        {
+            playerManager.playerSprite.Location = playerStartLocation;
+            foreach (Sprite asteroid in asteroidManager.Asteroids)
+            {
+                asteroid.Location = new Vector2(-500, -500);
+            }
+            enemyManager.Enemies.Clear();
+            enemyManager.Active = true;
+            playerManager.PlayerShotManager.Shots.Clear();
+            enemyManager.EnemyShotManager.Shots.Clear();
+            playerManager.Destroyed = false;
+        }
+        
+        /// <summary>
+        /// Allows the game to run logic such as updating the world,
+        /// checking for collisions, gathering input, and playing audio.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Update(GameTime gameTime)
+        {
+            // Allows the game to exit
+            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
+                this.Exit();
+
+            // TODO: Add your update logic here
+
+            switch (gameState)
+            {
+                case GameStates.TitleScreen:
+                    titleScreenTimer +=
+                        (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+                    if (titleScreenTimer >= titleScreenDelayTime)
+                    {
+                        if ((Keyboard.GetState().IsKeyDown(Keys.Space)) ||
+                            (GamePad.GetState(PlayerIndex.One).Buttons.A ==
+                            ButtonState.Pressed))
+                        {
+                            playerManager.LivesRemaining = playerStartingLives;
+                            playerManager.PlayerScore = 0;
+                            resetGame();
+                            gameState = GameStates.Playing;
+                        }
+                    }
+                    break;
+
+                case GameStates.Playing:
+
+                    starField.Update(gameTime);
+                    asteroidManager.Update(gameTime);
+                    playerManager.Update(gameTime);
+                    enemyManager.Update(gameTime);
+                    explosionManager.Update(gameTime);
+                    collisionManager.CheckCollisions();
+
+                    if (playerManager.Destroyed)
+                    {
+                        playerDeathTimer = 0f;
+                        enemyManager.Active = false;
+                        playerManager.LivesRemaining--;
+                        if (playerManager.LivesRemaining < 0)
+                        {
+                            gameState = GameStates.GameOver;
+                        }
+                        else
+                        {
+                            gameState = GameStates.PlayerDead;
+                        }
+                    }
+
+                    break;
+
+                case GameStates.PlayerDead:
+                    playerDeathTimer +=
+                        (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+                    starField.Update(gameTime);
+                    asteroidManager.Update(gameTime);
+                    enemyManager.Update(gameTime);
+                    playerManager.PlayerShotManager.Update(gameTime);
+                    explosionManager.Update(gameTime);
+
+                    if (playerDeathTimer >= playerDeathDelayTime)
+                    {
+                        resetGame();
+                        gameState = GameStates.Playing;
+                    }
+                    break;
+
+                case GameStates.GameOver:
+                    playerDeathTimer +=
+                        (float)gameTime.ElapsedGameTime.TotalSeconds;
+                    starField.Update(gameTime);
+                    asteroidManager.Update(gameTime);
+                    enemyManager.Update(gameTime);
+                    playerManager.PlayerShotManager.Update(gameTime);
+                    explosionManager.Update(gameTime);
+                    if (playerDeathTimer >= playerDeathDelayTime)
+                    {
+                        gameState = GameStates.TitleScreen;
+                    }
+                    break;
+
+            }
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// This is called when the game should draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.Clear(Color.Black);
+
+            spriteBatch.Begin();
+
+            if (gameState == GameStates.TitleScreen)
+            {
+                spriteBatch.Draw(titleScreen,
+                    new Rectangle(0, 0, this.Window.ClientBounds.Width,
+                        this.Window.ClientBounds.Height),
+                        Color.White);
+            }
+
+            if ((gameState == GameStates.Playing) ||
+                (gameState == GameStates.PlayerDead) ||
+                (gameState == GameStates.GameOver))
+            {
+                starField.Draw(spriteBatch);
+                asteroidManager.Draw(spriteBatch);
+                playerManager.Draw(spriteBatch);
+                enemyManager.Draw(spriteBatch);
+                explosionManager.Draw(spriteBatch);
+
+                spriteBatch.DrawString(
+                    pericles14,
+                    "Score: " + playerManager.PlayerScore.ToString(),
+                    scoreLocation,
+                    Color.White);
+
+                if (playerManager.LivesRemaining >= 0)
+                {
+                    spriteBatch.DrawString(
+                        pericles14,
+                        "Ships Remaining: " +
+                            playerManager.LivesRemaining.ToString(),
+                        livesLocation,
+                        Color.White);
+                }
+            }
+
+            if ((gameState == GameStates.GameOver))
+            {
+                spriteBatch.DrawString(
+                    pericles14,
+                    "G A M E  O V E R !",
+                    new Vector2(
+                        this.Window.ClientBounds.Width / 2 -
+                          pericles14.MeasureString("G A M E  O V E R !").X / 2,
+                        50),
+                    Color.White);
+            }
+
+
+            spriteBatch.End();
+
+            base.Draw(gameTime);
+        }
+
+    }
+}

+ 92 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Particle.cs

@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class Particle : Sprite
+    {
+        private Vector2 acceleration;
+        private float maxSpeed;
+        private int initialDuration;
+        private int remainingDuration;
+        private Color initialColor;
+        private Color finalColor;
+
+        public int ElapsedDuration
+        {
+            get
+            {
+                return initialDuration - remainingDuration;
+            }
+        }
+
+        public float DurationProgress
+        {
+            get
+            {
+                return (float)ElapsedDuration /
+                    (float)initialDuration;
+            }
+        }
+
+        public bool IsActive
+        {
+            get
+            {
+                return (remainingDuration > 0);
+            }
+        }
+
+        public Particle(
+            Vector2 location,
+            Texture2D texture,
+            Rectangle initialFrame,
+            Vector2 velocity,
+            Vector2 acceleration,
+            float maxSpeed,
+            int duration,
+            Color initialColor,
+            Color finalColor)
+            : base(location, texture, initialFrame, velocity)
+        {
+            initialDuration = duration;
+            remainingDuration = duration;
+            this.acceleration = acceleration;
+            this.initialColor = initialColor;
+            this.maxSpeed = maxSpeed;
+            this.finalColor = finalColor;
+        }
+
+        public override void Update(GameTime gameTime)
+        {
+            if (IsActive)
+            {
+                velocity += acceleration;
+                if (velocity.Length() > maxSpeed)
+                {
+                    velocity.Normalize();
+                    velocity *= maxSpeed;
+                }
+                TintColor = Color.Lerp(
+                    initialColor,
+                    finalColor,
+                    DurationProgress);
+                remainingDuration--;
+                base.Update(gameTime);
+            }
+        }
+
+        public override void Draw(SpriteBatch spriteBatch)
+        {
+            if (IsActive)
+            {
+                base.Draw(spriteBatch);
+            }
+        }
+
+    }
+}

+ 174 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/PlayerManager.cs

@@ -0,0 +1,174 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class PlayerManager
+    {
+        public Sprite playerSprite;
+        private float playerSpeed = 160.0f;
+        private Rectangle playerAreaLimit;
+
+        public long PlayerScore = 0;
+        public int LivesRemaining = 3;
+        public bool Destroyed = false;
+
+        private Vector2 gunOffset = new Vector2(25, 10);
+        private float shotTimer = 0.0f;
+        private float minShotTimer = 0.2f;
+        private int playerRadius = 15;
+        public ShotManager PlayerShotManager;
+
+        public PlayerManager(
+            Texture2D texture,  
+            Rectangle initialFrame,
+            int frameCount,
+            Rectangle screenBounds)
+        {
+            playerSprite = new Sprite(
+                new Vector2(500, 500),
+                texture,
+                initialFrame,
+                Vector2.Zero);
+
+            PlayerShotManager = new ShotManager(
+                texture,
+                new Rectangle(0, 300, 5, 5),
+                4,
+                2,
+                250f,
+                screenBounds);
+
+            playerAreaLimit =
+                new Rectangle(
+                    0,
+                    screenBounds.Height / 2,
+                    screenBounds.Width,
+                    screenBounds.Height / 2);
+
+            for (int x = 1; x < frameCount; x++)
+            {
+                playerSprite.AddFrame(
+                    new Rectangle(
+                        initialFrame.X + (initialFrame.Width * x),
+                        initialFrame.Y,
+                        initialFrame.Width,
+                        initialFrame.Height));
+            }
+            playerSprite.CollisionRadius = playerRadius;
+        }
+
+        private void FireShot()
+        {
+            if (shotTimer >= minShotTimer)
+            {
+                PlayerShotManager.FireShot(
+                    playerSprite.Location + gunOffset,
+                    new Vector2(0, -1),
+                    true);
+                shotTimer = 0.0f;
+            }
+        }
+
+        private void HandleKeyboardInput(KeyboardState keyState)
+        {
+            if (keyState.IsKeyDown(Keys.Up))
+            {
+                playerSprite.Velocity += new Vector2(0, -1);
+            }
+
+            if (keyState.IsKeyDown(Keys.Down))
+            {
+                playerSprite.Velocity += new Vector2(0, 1);
+            }
+
+            if (keyState.IsKeyDown(Keys.Left))
+            {
+                playerSprite.Velocity += new Vector2(-1, 0);
+            }
+
+            if (keyState.IsKeyDown(Keys.Right))
+            {
+                playerSprite.Velocity += new Vector2(1, 0);
+            }
+
+            if (keyState.IsKeyDown(Keys.Space))
+            {
+                FireShot();
+            }
+        }
+
+        private void HandleGamepadInput(GamePadState gamePadState)
+        {
+            playerSprite.Velocity +=
+                new Vector2(
+                    gamePadState.ThumbSticks.Left.X,
+                    -gamePadState.ThumbSticks.Left.Y);
+
+            if (gamePadState.Buttons.A == ButtonState.Pressed)
+            {
+                FireShot();
+            }
+        }
+
+        private void imposeMovementLimits()
+        {
+            Vector2 location = playerSprite.Location;
+
+            if (location.X < playerAreaLimit.X)
+                location.X = playerAreaLimit.X;
+
+            if (location.X >
+                (playerAreaLimit.Right - playerSprite.Source.Width))
+                location.X =
+                    (playerAreaLimit.Right - playerSprite.Source.Width);
+
+            if (location.Y < playerAreaLimit.Y)
+                location.Y = playerAreaLimit.Y;
+
+            if (location.Y >
+                (playerAreaLimit.Bottom - playerSprite.Source.Height))
+                location.Y =
+                    (playerAreaLimit.Bottom - playerSprite.Source.Height);
+
+            playerSprite.Location = location;
+        }
+
+        public void Update(GameTime gameTime)
+        {
+            PlayerShotManager.Update(gameTime);
+
+            if (!Destroyed)
+            {
+                playerSprite.Velocity = Vector2.Zero;
+
+                shotTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+                HandleKeyboardInput(Keyboard.GetState());
+                HandleGamepadInput(GamePad.GetState(PlayerIndex.One));
+
+                playerSprite.Velocity.Normalize();
+                playerSprite.Velocity *= playerSpeed;
+
+                playerSprite.Update(gameTime);
+                imposeMovementLimits();
+            }
+        }
+
+        public void Draw(SpriteBatch spriteBatch)
+        {
+            PlayerShotManager.Draw(spriteBatch);
+
+            if (!Destroyed)
+            {
+                playerSprite.Draw(spriteBatch);
+            }
+        }
+
+    }
+}

+ 95 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/ShotManager.cs

@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class ShotManager
+    {
+        public List<Sprite> Shots = new List<Sprite>();
+        private Rectangle screenBounds;
+
+        private static Texture2D Texture;
+        private static Rectangle InitialFrame;
+        private static int FrameCount;
+        private float shotSpeed;
+        private static int CollisionRadius;
+
+        public ShotManager(
+            Texture2D texture,
+            Rectangle initialFrame,
+            int frameCount,
+            int collisionRadius,
+            float shotSpeed,
+            Rectangle screenBounds)
+        {
+            Texture = texture;
+            InitialFrame = initialFrame;
+            FrameCount = frameCount;
+            CollisionRadius = collisionRadius;
+            this.shotSpeed = shotSpeed;
+            this.screenBounds = screenBounds;
+        }
+
+        public void FireShot(
+            Vector2 location,
+            Vector2 velocity,
+            bool playerFired)
+        {
+            Sprite thisShot = new Sprite(
+                location,
+                Texture,
+                InitialFrame,
+                velocity);
+
+            thisShot.Velocity *= shotSpeed;
+
+            for (int x = 1; x < FrameCount; x++)
+            {
+                thisShot.AddFrame(new Rectangle(
+                    InitialFrame.X + (InitialFrame.Width * x),
+                    InitialFrame.Y,
+                    InitialFrame.Width,
+                    InitialFrame.Height));
+            }
+            thisShot.CollisionRadius = CollisionRadius;
+            Shots.Add(thisShot);
+
+            if (playerFired)
+            {
+
+                SoundManager.PlayPlayerShot();
+            }
+            else
+            {
+
+                SoundManager.PlayEnemyShot();
+            }
+        }
+
+        public void Update(GameTime gameTime)
+        {
+            for (int x = Shots.Count - 1; x >= 0; x--)
+            {
+                Shots[x].Update(gameTime);
+                if (!screenBounds.Intersects(Shots[x].Destination))
+                {
+                    Shots.RemoveAt(x);
+                }
+            }
+        }
+
+        public void Draw(SpriteBatch spriteBatch)
+        {
+            foreach (Sprite shot in Shots)
+            {
+                shot.Draw(spriteBatch);
+            }
+        }
+
+    
+    }
+}

+ 81 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/SoundManager.cs

@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+
+
+namespace Asteroid_Belt_Assault
+{
+    public static class SoundManager
+    {
+        private static List<SoundEffect> explosions = new
+            List<SoundEffect>();
+        private static int explosionCount = 4;
+
+        private static SoundEffect playerShot;
+        private static SoundEffect enemyShot;
+
+        private static Random rand = new Random();
+
+        public static void Initialize(ContentManager content)
+        {
+            try
+            {
+                playerShot = content.Load<SoundEffect>(@"Sounds\Shot1");
+                enemyShot = content.Load<SoundEffect>(@"Sounds\Shot2");
+
+                for (int x = 1; x <= explosionCount; x++)
+                {
+                    explosions.Add(
+                        content.Load<SoundEffect>(@"Sounds\Explosion" +
+                            x.ToString()));
+                }
+            }
+            catch
+            {
+                Debug.Write("SoundManager Initialization Failed");
+            }
+        }
+
+        public static void PlayExplosion()
+        {
+            try
+            {
+                explosions[rand.Next(0, explosionCount)].Play();
+            }
+            catch
+            {
+                Debug.Write("PlayExplosion Failed");
+            }
+        }
+
+        public static void PlayPlayerShot()
+        {
+            try
+            {
+                playerShot.Play();
+            }
+            catch
+            {
+                Debug.Write("PlayPlayerShot Failed");
+            }
+        }
+
+        public static void PlayEnemyShot()
+        {
+            try
+            {
+                enemyShot.Play();
+            }
+            catch
+            {
+                Debug.Write("PlayEnemyShot Failed");
+            }
+        }
+
+    }
+}

+ 173 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/Sprite.cs

@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class Sprite
+    {
+        public Texture2D Texture;
+
+        protected List<Rectangle> frames = new List<Rectangle>();
+        private int frameWidth = 0;
+        private int frameHeight = 0;
+        private int currentFrame;
+        private float frameTime = 0.1f;
+        private float timeForCurrentFrame = 0.0f;
+
+        private Color tintColor = Color.White;
+        private float rotation = 0.0f;
+
+        public int CollisionRadius = 0;
+        public int BoundingXPadding = 0;
+        public int BoundingYPadding = 0;
+
+        protected Vector2 location = Vector2.Zero;
+        protected Vector2 velocity = Vector2.Zero;
+
+        public Sprite(
+            Vector2 location,
+            Texture2D texture,
+            Rectangle initialFrame,
+            Vector2 velocity)
+        {
+            this.location = location;
+            Texture = texture;
+            this.velocity = velocity;
+
+            frames.Add(initialFrame);
+            frameWidth = initialFrame.Width;
+            frameHeight = initialFrame.Height;
+        }
+
+        public Vector2 Location
+        {
+            get { return location; }
+            set { location = value; }
+        }
+
+        public Vector2 Velocity
+        {
+            get { return velocity; }
+            set { velocity = value; }
+        }
+
+        public Color TintColor
+        {
+            get { return tintColor; }
+            set { tintColor = value; }
+        }
+
+        public float Rotation
+        {
+            get { return rotation; }
+            set { rotation = value % MathHelper.TwoPi; }
+        }
+
+        public int Frame
+        {
+            get { return currentFrame; }
+            set
+            {
+                currentFrame = (int)MathHelper.Clamp(value, 0,
+                frames.Count - 1);
+            }
+        }
+
+        public float FrameTime
+        {
+            get { return frameTime; }
+            set { frameTime = MathHelper.Max(0, value); }
+        }
+
+        public Rectangle Source
+        {
+            get { return frames[currentFrame]; }
+        }
+
+        public Rectangle Destination
+        {
+            get
+            {
+                return new Rectangle(
+                    (int)location.X,
+                    (int)location.Y,
+                    frameWidth,
+                    frameHeight);
+            }
+        }
+
+        public Vector2 Center
+        {
+            get
+            {
+                return location +
+                    new Vector2(frameWidth / 2, frameHeight / 2);
+            }
+        }
+
+        public Rectangle BoundingBoxRect
+        {
+            get
+            {
+                return new Rectangle(
+                    (int)location.X + BoundingXPadding,
+                    (int)location.Y + BoundingYPadding,
+                    frameWidth - (BoundingXPadding * 2),
+                    frameHeight - (BoundingYPadding * 2));
+            }
+        }
+
+        public bool IsBoxColliding(Rectangle OtherBox)
+        {
+            return BoundingBoxRect.Intersects(OtherBox);
+        }
+
+        public bool IsCircleColliding(Vector2 otherCenter, float otherRadius)
+        {
+            if (Vector2.Distance(Center, otherCenter) <
+                (CollisionRadius + otherRadius))
+                return true;
+            else
+                return false;
+        }
+
+        public void AddFrame(Rectangle frameRectangle)
+        {
+            frames.Add(frameRectangle);
+        }
+
+        public virtual void Update(GameTime gameTime)
+        {
+            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+            timeForCurrentFrame += elapsed;
+
+            if (timeForCurrentFrame >= FrameTime)
+            {
+                currentFrame = (currentFrame + 1) % (frames.Count);
+                timeForCurrentFrame = 0.0f;
+            }
+
+            location += (velocity * elapsed);
+        }
+
+        public virtual void Draw(SpriteBatch spriteBatch)
+        {
+            spriteBatch.Draw(
+                Texture,
+                Center,
+                Source,
+                tintColor,
+                rotation,
+                new Vector2(frameWidth / 2, frameHeight / 2),
+                1.0f,
+                SpriteEffects.None,
+                0.0f);
+        }
+
+    }
+}

+ 65 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Core/StarField.cs

@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Asteroid_Belt_Assault
+{
+    class StarField
+    {
+        private List<Sprite> stars = new List<Sprite>();
+        private int screenWidth = 800;
+        private int screenHeight = 600;
+        private Random rand = new Random();
+        private Color[] colors = { Color.White, Color.Yellow, 
+                           Color.Wheat, Color.WhiteSmoke, 
+                           Color.SlateGray };
+
+        public StarField(
+            int screenWidth,
+            int screenHeight,
+            int starCount,
+            Vector2 starVelocity,
+            Texture2D texture,
+            Rectangle frameRectangle)
+        {
+            this.screenWidth = screenWidth;
+            this.screenHeight = screenHeight;
+            for (int x = 0; x < starCount; x++)
+            {
+                stars.Add(new Sprite(
+                    new Vector2(rand.Next(0, screenWidth),
+                        rand.Next(0, screenHeight)),
+                    texture,
+                    frameRectangle,
+                    starVelocity));
+                Color starColor = colors[rand.Next(0, colors.Count())];
+                starColor *= (float)(rand.Next(30, 80) / 100f); stars[stars.Count() - 1].TintColor = starColor;
+            }
+        }
+
+        public void Update(GameTime gameTime)
+        {
+            foreach (Sprite star in stars)
+            {
+                star.Update(gameTime);
+                if (star.Location.Y > screenHeight)
+                {
+                    star.Location = new Vector2(
+                        rand.Next(0, screenWidth), 0);
+                }
+            }
+        }
+
+        public void Draw(SpriteBatch spriteBatch)
+        {
+            foreach (Sprite star in stars)
+            {
+                star.Draw(spriteBatch);
+            }
+        }
+
+    }
+}

+ 18 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.asteroidbeltassault">
+    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
+    
+    <application android:allowBackup="true" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
+        <activity android:name="microsoft.xna.framework.AndroidGameActivity" 
+                  android:label="@string/app_name" 
+                  android:launchMode="singleInstance" 
+                  android:screenOrientation="sensorLandscape" 
+                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>

+ 36 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/AsteroidBeltAssault.Android.csproj

@@ -0,0 +1,36 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Asteroid_Belt_Assault</RootNamespace>
+    <AssemblyName>AsteroidBeltAssault</AssemblyName>
+    <AndroidApplication>true</AndroidApplication>
+    <AndroidUseAapt2>true</AndroidUseAapt2>
+    <AndroidManifest>AndroidManifest.xml</AndroidManifest>
+    <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
+    <ApplicationId>com.companyname.asteroidbeltassault</ApplicationId>
+    <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
+    <ApplicationVersion>1</ApplicationVersion>
+    <PublishSingleFile>false</PublishSingleFile>
+    <TieredCompilation>false</TieredCompilation>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+   <ItemGroup>
+    <ProjectReference Include="..\..\Core\AsteroidBeltAssault.Core.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+
+</Project>

+ 30 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/MainActivity.cs

@@ -0,0 +1,30 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Android.Views;
+using Microsoft.Xna.Framework;
+
+namespace Asteroid_Belt_Assault
+{
+    [Activity(
+        Label = "@string/app_name",
+        MainLauncher = true,
+        AlwaysRetainTaskState = true,
+        LaunchMode = LaunchMode.SingleInstance,
+        ScreenOrientation = ScreenOrientation.SensorLandscape,
+        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize
+    )]
+    public class MainActivity : AndroidGameActivity
+    {
+        private Game1 _game;
+
+        protected override void OnCreate(Bundle bundle)
+        {
+            base.OnCreate(bundle);
+
+            _game = new Game1();
+            SetContentView((View)_game.Services.GetService(typeof(View)));
+            _game.Run();
+        }
+    }
+}

+ 4 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/Resources/values/strings.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Asteroid Belt Assault</string>
+</resources>

+ 5 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Android/Resources/values/styles.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="AppTheme" parent="@android:style/Theme.Holo.Light">
+    </style>
+</resources>

+ 29 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/DesktopGL/AsteroidBeltAssault.DesktopGL.csproj

@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Asteroid_Belt_Assault</RootNamespace>
+    <AssemblyName>AsteroidBeltAssault</AssemblyName>
+    <ApplicationIcon>..\..\Core\Content\Game.ico</ApplicationIcon>
+    <PublishSingleFile>false</PublishSingleFile>
+    <TieredCompilation>false</TieredCompilation>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\AsteroidBeltAssault.Core.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+
+</Project>

+ 14 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/DesktopGL/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Asteroid_Belt_Assault
+{
+    public static class Program
+    {
+        [STAThread]
+        public static void Main()
+        {
+            using (var game = new Game1())
+                game.Run();
+        }
+    }
+}

+ 30 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Windows/AsteroidBeltAssault.Windows.csproj

@@ -0,0 +1,30 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Asteroid_Belt_Assault</RootNamespace>
+    <AssemblyName>AsteroidBeltAssault</AssemblyName>
+    <UseWindowsForms>true</UseWindowsForms>
+    <ApplicationIcon>..\..\Core\Content\Game.ico</ApplicationIcon>
+    <PublishSingleFile>false</PublishSingleFile>
+    <TieredCompilation>false</TieredCompilation>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\AsteroidBeltAssault.Core.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+
+</Project>

+ 14 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/Windows/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Asteroid_Belt_Assault
+{
+    public static class Program
+    {
+        [STAThread]
+        public static void Main()
+        {
+            using (var game = new Game1())
+                game.Run();
+        }
+    }
+}

+ 44 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/AppDelegate.cs

@@ -0,0 +1,44 @@
+using Foundation;
+using UIKit;
+
+namespace Asteroid_Belt_Assault
+{
+    [Register("AppDelegate")]
+    public partial class AppDelegate : UIApplicationDelegate
+    {
+        private Game1 game;
+
+        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
+        {
+            game = new Game1();
+            game.Run();
+
+            return true;
+        }
+
+        public override void OnActivated(UIApplication application)
+        {
+            // Handle when your app becomes active
+        }
+
+        public override void OnResignActivation(UIApplication application)
+        {
+            // Handle when your app moves from active to inactive state
+        }
+
+        public override void DidEnterBackground(UIApplication application)
+        {
+            // Handle when your app moves to background
+        }
+
+        public override void WillEnterForeground(UIApplication application)
+        {
+            // Handle when your app transitions from background to foreground
+        }
+
+        public override void WillTerminate(UIApplication application)
+        {
+            // Handle when your app is about to terminate
+        }
+    }
+}

+ 33 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/AsteroidBeltAssault.iOS.csproj

@@ -0,0 +1,33 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Asteroid_Belt_Assault</RootNamespace>
+    <AssemblyName>AsteroidBeltAssault</AssemblyName>
+    <SupportedOSPlatformVersion>11.0</SupportedOSPlatformVersion>
+    <ApplicationId>com.companyname.asteroidbeltassault</ApplicationId>
+    <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
+    <ApplicationVersion>1</ApplicationVersion>
+    <PublishSingleFile>false</PublishSingleFile>
+    <TieredCompilation>false</TieredCompilation>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\AsteroidBeltAssault.Core.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+
+</Project>

+ 16 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/Info.plist

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleIdentifier</key>
+	<string>com.yourcompany.AsteroidBeltAssault</string>
+	<key>CFBundleName</key>
+	<string>AsteroidBeltAssault</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.6</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

+ 12 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/Platforms/iOS/Program.cs

@@ -0,0 +1,12 @@
+using UIKit;
+
+namespace Asteroid_Belt_Assault
+{
+    public class Program
+    {
+        static void Main(string[] args)
+        {
+            UIApplication.Main(args, null, typeof(AppDelegate));
+        }
+    }
+}

+ 67 - 0
XNAGameDevelopmentbyExample/AsteroidBeltAssault/README.md

@@ -0,0 +1,67 @@
+Asteroid Belt Assault
+=====================
+
+This project contains the Asteroid Belt Assault game as it is at the end of Chapter 5. 
+
+This was taken from the Book XNA 4.0 Game Development by Example: Beginner's Guide by Kurt Jaegers
+Published by PACKT Publishing which can be found here 
+http://www.packtpub.com/xna-4-0-game-development-by-example-beginners-guide/book
+
+For a complete discussion of the code please buy the book as it is worth the money.
+
+## About
+
+Asteroid Belt Assault is a cross-platform 2D space shooter game originally developed for XNA 4.0, now ported to MonoGame. The project demonstrates game development concepts such as sprite management, collision detection, particle effects, and sound, following the structure from the book "XNA 4.0 Game Development by Example: Beginner's Guide" by Kurt Jaegers.
+
+## Supported Platforms
+- Windows (DirectX)
+- DesktopGL (cross-platform)
+- Android
+- iOS
+
+## Building and Running
+
+### Prerequisites
+- [.NET 8 SDK](https://dotnet.microsoft.com/download)
+- [MonoGame](https://www.monogame.net/) (if not included via NuGet)
+- For Android: Android SDK & emulator
+- For iOS: macOS with Xcode & simulator (or networked Mac for Windows users)
+
+### Windows
+1. Build: Use the VS Code task `build-windows` or run:
+   ```pwsh
+   dotnet build Platforms/Windows/AsteroidBeltAssault.Windows.csproj
+   ```
+2. Run: Use the VS Code launch config `Run Windows` or run the built `.exe` from `Platforms/Windows/bin/Debug/net8.0-windows/`.
+
+### DesktopGL
+1. Build: Use the VS Code task `build-desktopgl` or run:
+   ```pwsh
+   dotnet build Platforms/Desktop/AsteroidBeltAssault.DesktopGL.csproj
+   ```
+2. Run: Use the VS Code launch config `Run Desktop` or run the built binary from `Platforms/Desktop/bin/Debug/net8.0/`.
+
+### Android
+1. Build: Use the VS Code task `build-android` or run:
+   ```pwsh
+   dotnet build Platforms/Android/AsteroidBeltAssault.Android.csproj
+   ```
+2. Deploy & Run: Use the VS Code launch config `Deploy and Launch Android` or run:
+   ```pwsh
+   dotnet android deploy --project Platforms/Android/AsteroidBeltAssault.Android.csproj
+   ```
+   The app will be deployed to the default Android emulator.
+
+### iOS
+1. Build: Use the VS Code task `build-ios` or run:
+   ```pwsh
+   dotnet build Platforms/iOS/AsteroidBeltAssault.iOS.csproj
+   ```
+2. Deploy & Run: Use the VS Code launch config `Deploy and Launch iOS` or run:
+   ```pwsh
+   dotnet ios deploy --project Platforms/iOS/AsteroidBeltAssault.iOS.csproj
+   ```
+   The app will be deployed to the default iOS simulator.
+
+---
+For more details, see the book or the source code in the `Core` and `Platforms` directories.