Browse Source

Rock Rain updated to SDK and MG 3.8. Some Content build issues.

CartBlanche 6 days ago
parent
commit
ef00c80c67
57 changed files with 2452 additions and 1804 deletions
  1. 49 0
      RockRain/.vscode/launch.json
  2. 179 0
      RockRain/.vscode/tasks.json
  3. 262 261
      RockRain/Core/ActionScene.cs
  4. 107 107
      RockRain/Core/AudioLibrary.cs
  5. 158 0
      RockRain/Core/Content/Content.mgcb
  6. 0 0
      RockRain/Core/Content/Default.png
  7. 0 0
      RockRain/Core/Content/GameThumbnail.png
  8. 0 0
      RockRain/Core/Content/backmusic.mp3
  9. 0 0
      RockRain/Core/Content/explosion.png
  10. 0 0
      RockRain/Core/Content/explosion.wav
  11. 0 0
      RockRain/Core/Content/gamepad.png
  12. 0 0
      RockRain/Core/Content/helpscreen.png
  13. 0 0
      RockRain/Core/Content/menuLarge.xnb
  14. 0 0
      RockRain/Core/Content/menuSmall.xnb
  15. 0 0
      RockRain/Core/Content/menu_back.wav
  16. 0 0
      RockRain/Core/Content/menu_scroll.wav
  17. 0 0
      RockRain/Core/Content/menu_select3.wav
  18. 0 0
      RockRain/Core/Content/newmeteor.wav
  19. 0 0
      RockRain/Core/Content/powerget.wav
  20. 0 0
      RockRain/Core/Content/powershow.wav
  21. 0 0
      RockRain/Core/Content/rockrainenhanced.png
  22. 0 0
      RockRain/Core/Content/score.xnb
  23. 0 0
      RockRain/Core/Content/spacebackground.jpg
  24. 0 0
      RockRain/Core/Content/startbackground.png
  25. 0 0
      RockRain/Core/Content/startmusic.mp3
  26. 0 0
      RockRain/Core/Content/startsceneelements.png
  27. 70 70
      RockRain/Core/ExplosionManager.cs
  28. 1 5
      RockRain/Core/ExplosionParticleSystem.cs
  29. 2 4
      RockRain/Core/GameScene.cs
  30. 22 24
      RockRain/Core/HelpScene.cs
  31. 2 4
      RockRain/Core/ImageComponent.cs
  32. 137 137
      RockRain/Core/Meteor.cs
  33. 164 166
      RockRain/Core/MeteorsManager.cs
  34. 1 5
      RockRain/Core/Particle.cs
  35. 1 7
      RockRain/Core/ParticleSystem.cs
  36. 182 184
      RockRain/Core/Player.cs
  37. 93 95
      RockRain/Core/PowerSource.cs
  38. 14 0
      RockRain/Core/RockRain.Core.csproj
  39. 260 256
      RockRain/Core/RockRainGame.cs
  40. 92 94
      RockRain/Core/Score.cs
  41. 2 4
      RockRain/Core/Sprite.cs
  42. 176 177
      RockRain/Core/StartScene.cs
  43. 2 4
      RockRain/Core/TextMenuComponent.cs
  44. 32 0
      RockRain/Platforms/Android/AndroidManifest.xml
  45. 29 0
      RockRain/Platforms/Android/MainActivity.cs
  46. 4 0
      RockRain/Platforms/Android/Resources/values/colors.xml
  47. 42 0
      RockRain/Platforms/Android/RockRain.Android.csproj
  48. 14 0
      RockRain/Platforms/Desktop/Program.cs
  49. 32 0
      RockRain/Platforms/Desktop/RockRain.DesktopGL.csproj
  50. 14 0
      RockRain/Platforms/Windows/Program.cs
  51. 35 0
      RockRain/Platforms/Windows/RockRain.Windows.csproj
  52. 48 0
      RockRain/Platforms/iOS/Info.plist
  53. 38 0
      RockRain/Platforms/iOS/RockRain.iOS.csproj
  54. 136 0
      RockRain/README.md
  55. 0 168
      RockRain/RockRain.iOS.csproj
  56. 52 0
      RockRain/RockRain.sln
  57. 0 32
      RockRain/main.cs

+ 49 - 0
RockRain/.vscode/launch.json

@@ -0,0 +1,49 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Launch Windows (DirectX)",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-windows",
+            "program": "${workspaceFolder}/Platforms/Windows/bin/Debug/net8.0-windows/RockRain.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Windows",
+            "console": "internalConsole",
+            "stopAtEntry": false
+        },
+        {
+            "name": "Launch DesktopGL",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl",
+            "program": "${workspaceFolder}/Platforms/Desktop/bin/Debug/net8.0/RockRain",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Desktop",
+            "console": "internalConsole",
+            "stopAtEntry": false
+        },
+        {
+            "name": "Launch Android",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-android",
+            "program": "${workspaceFolder}/Platforms/Android/bin/Debug/net8.0-android/RockRain.dll",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Android",
+            "console": "internalConsole",
+            "stopAtEntry": false
+        },
+        {
+            "name": "Launch iOS",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-ios",
+            "program": "${workspaceFolder}/Platforms/iOS/bin/Debug/net8.0-ios/iossimulator-x64/RockRain.dll",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/iOS",
+            "console": "internalConsole",
+            "stopAtEntry": false
+        }
+    ]
+}

+ 179 - 0
RockRain/.vscode/tasks.json

@@ -0,0 +1,179 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build-windows",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "build",
+                "RockRain.Windows.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build",
+            "presentation": {
+                "reveal": "silent"
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-desktopgl",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "build",
+                "RockRain.DesktopGL.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build",
+            "presentation": {
+                "reveal": "silent"
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-android",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "build",
+                "RockRain.Android.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build",
+            "presentation": {
+                "reveal": "always"
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-ios",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "build",
+                "RockRain.iOS.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build",
+            "presentation": {
+                "reveal": "always"
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "run-windows",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "run",
+                "--project",
+                "RockRain.Windows.csproj"
+            ],
+            "group": "test",
+            "presentation": {
+                "reveal": "always"
+            },
+            "problemMatcher": "$msCompile",
+            "dependsOn": "build-windows"
+        },
+        {
+            "label": "build-windows",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "build",
+                "Platforms/Windows/RockRain.Windows.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build"
+        },
+        {
+            "label": "build-desktopgl",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "build",
+                "Platforms/Desktop/RockRain.DesktopGL.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build"
+        },
+        {
+            "label": "build-android",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "build",
+                "Platforms/Android/RockRain.Android.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build"
+        },
+        {
+            "label": "build-ios",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "build",
+                "Platforms/iOS/RockRain.iOS.csproj",
+                "/property:GenerateFullPaths=true",
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build"
+        },
+        {
+            "label": "run-windows",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "run",
+                "--project",
+                "Platforms/Windows/RockRain.Windows.csproj"
+            ],
+            "group": "test",
+            "dependsOn": "build-windows"
+        },
+        {
+            "label": "run-desktopgl",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "run",
+                "--project",
+                "Platforms/Desktop/RockRain.DesktopGL.csproj"
+            ],
+            "group": "test",
+            "dependsOn": "build-desktopgl"
+        },
+        {
+            "label": "run-android",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "run",
+                "--project",
+                "Platforms/Android/RockRain.Android.csproj"
+            ],
+            "group": "test",
+            "dependsOn": "build-android"
+        },
+        {
+            "label": "run-ios",
+            "type": "shell",
+            "command": "dotnet",
+            "args": [
+                "run",
+                "--project",
+                "Platforms/iOS/RockRain.iOS.csproj"
+            ],
+            "group": "test",
+            "dependsOn": "build-ios"
+        },

+ 262 - 261
RockRain/ActionScene.cs → RockRain/Core/ActionScene.cs

@@ -1,262 +1,263 @@
-using System;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Graphics;
-using RockRainIphone.Core;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Xna.Framework.Input;
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is a game component that implements the Action Scene.
-    /// </summary>
-    public class ActionScene : GameScene
-    {
-        // Basics
-        protected Texture2D actionTexture;        
-        protected SpriteBatch spriteBatch = null;
-        protected AudioLibrary audio;
-
-        // Game Elements
-        protected Player player;
-        protected MeteorsManager meteors;
-        protected PowerSource powerSource;
-        protected ImageComponent background;
-        protected Score score;
-		protected ExplosionManager _explosions;
-
-        // Gui Stuff
-        protected Vector2 pausePosition;
-        protected Vector2 gameoverPosition;
-        protected Rectangle pauseRect = new Rectangle(84, 65, 99, 30);
-        protected Rectangle gameoverRect = new Rectangle(53, 108, 186, 30);
-
-        // GameState elements
-        protected bool paused;
-        protected bool gameOver;
-        protected TimeSpan elapsedTime = TimeSpan.Zero;
-
-        /// <summary>
-        /// Default Constructor
-        /// </summary>
-        /// <param name="game">The main game object</param>
-        /// <param name="theTexture">Texture with the sprite elements</param>
-        /// <param name="backgroundTexture">Texture for the background</param>
-        /// <param name="font">Font used in the score</param>
-        public ActionScene(Game game, Texture2D theTexture, 
-            Texture2D backgroundTexture, SpriteFont font, ExplosionManager explosions) 
-            : base(game)
-        {
-            // Get the current audiocomponent and play the background music
-            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));
-
-            background = new ImageComponent(game, backgroundTexture, 
-                ImageComponent.DrawMode.Stretch);
-            Components.Add(background);
-
-            actionTexture = theTexture;
-
-            spriteBatch = (SpriteBatch) 
-                Game.Services.GetService(typeof (SpriteBatch));
-            meteors = new MeteorsManager(Game, ref actionTexture);
-            Components.Add(meteors);
-
-            player = new Player(Game, ref actionTexture);
-            player.Initialize();
-            Components.Add(player);
-
-            score = new Score(game, font, Color.LightGray);
-            score.Position = new Vector2(1, 1);
-            Components.Add(score);
-
-            powerSource = new PowerSource(game, ref actionTexture);
-            powerSource.Initialize();
-            Components.Add(powerSource);
-			
-			_explosions = explosions;
-        }
-
-        /// <summary>
-        /// Show the action scene
-        /// </summary>
-        public override void Show()
-        {
-			GamePad.Visible = true;
-			
-            MediaPlayer.Play(audio.BackMusic);
-
-            meteors.Initialize();
-            powerSource.PutinStartPosition();
-
-            player.Reset();
-
-            paused = false;
-            pausePosition.X = (Game.Window.ClientBounds.Width - 
-                pauseRect.Width)/2;
-            pausePosition.Y = (Game.Window.ClientBounds.Height - 
-                pauseRect.Height)/2;
-
-            gameOver = false;
-            gameoverPosition.X = (Game.Window.ClientBounds.Width - 
-                gameoverRect.Width)/2;
-            gameoverPosition.Y = (Game.Window.ClientBounds.Height - 
-                gameoverRect.Height)/2;
-
-            // Is a two-player game?
-            player.Visible = true;
-
-            base.Show();
-        }
-
-        /// <summary>
-        /// Hide the scene
-        /// </summary>
-        public override void Hide()
-        {
-            // Stop the background music
-            MediaPlayer.Stop();
-
-            base.Hide();
-        }
-
-        /// <summary>
-        /// True, if the game is in GameOver state
-        /// </summary>
-        public bool GameOver
-        {
-            get { return gameOver; }
-        }
-
-        /// <summary>
-        /// Paused mode
-        /// </summary>
-        public bool Paused
-        {
-            get { return paused; }
-            set
-            {
-                paused = value;
-                if (paused)
-                {
-					//==================================
-            		//AUDIO IS NOT SUPPORTED IN XNATOUCH
-            		//==================================
-                    //MediaPlayer.Pause();
-                }
-                else
-                {
-					//==================================
-            		//AUDIO IS NOT SUPPORTED IN XNATOUCH
-            		//==================================
-                    //MediaPlayer.Resume();
-                }
-            }
-        }
-
-        /// <summary>
-        /// Handle collisions with a meteor
-        /// </summary>
-        private void HandleDamages()
-        {
-            // Check Collision for player 1
-            if (meteors.CheckForCollisions(player.GetBounds()))
-            {
-                // Player penalty
-                player.Power -= 10;
-				
-				_explosions.AddExplosion(player.Position);
-            }
-        }
-
-        /// <summary>
-        /// Handle power-up stuff
-        /// </summary>
-        private void HandlePowerSourceSprite(GameTime gameTime)
-        {
-            // Player 1 get the power source
-            if (powerSource.CheckCollision(player.GetBounds()))
-            {
-                audio.PowerGet.Play();
-                elapsedTime = TimeSpan.Zero;
-                powerSource.PutinStartPosition();
-                player.Power += 50;
-            }
-
-            // Check for send a new Power source
-            elapsedTime += gameTime.ElapsedGameTime;
-            if (elapsedTime > TimeSpan.FromSeconds(15))
-            {
-                elapsedTime -= TimeSpan.FromSeconds(15);
-                powerSource.Enabled = true;
-                audio.PowerShow.Play();
-            }
-        }
-
-        /// <summary>
-        /// Allows the game component to update itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        public override void Update(GameTime gameTime)
-        {
-			// Update the explosions
-            _explosions.Update(gameTime);
-			
-            if ((!paused) && (!gameOver))
-            {
-                // Check collisions with meteors
-                HandleDamages();				 
-
-                // Check if a player get a power boost
-                HandlePowerSourceSprite(gameTime);
-
-                // Update score
-                score.Value = player.Score;
-                score.Power = player.Power;
-
-                // Check if player is dead
-                gameOver = (player.Power <= 0);
-                if (gameOver)
-                {
-                    player.Visible = (player.Power > 0);
-                    
-            		// Stop the music
-					MediaPlayer.Stop();
-                }
-
-                // Update all other game components
-                base.Update(gameTime);
-            }
-
-            // In game over state, keep the meteors animation
-            if (gameOver)
-            {
-                meteors.Update(gameTime);
-            }
-        }
-
-        /// <summary>
-        /// Allows the game component to draw itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        public override void Draw(GameTime gameTime)
-        {
-            // Draw all game components
-            base.Draw(gameTime);
-			
-            if (paused)
-            {
-                // Draw the "pause" text
-                spriteBatch.Draw(actionTexture, pausePosition, pauseRect, 
-                    Color.White);
-            }
-            if (gameOver)
-            {
-                // Draw the "gameover" text
-                spriteBatch.Draw(actionTexture, gameoverPosition, gameoverRect, 
-                    Color.White);
-            }
-			
-		}		
-    }
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Graphics;
+using RockRain.Core;
+using Microsoft.Xna.Framework.Media;
+using Microsoft.Xna.Framework.Input;
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is a game component that implements the Action Scene.
+    /// </summary>
+    public class ActionScene : GameScene
+    {
+        // Basics
+        protected Texture2D actionTexture;        
+        protected SpriteBatch spriteBatch = null;
+        protected AudioLibrary audio;
+
+        // Game Elements
+        protected Player player;
+        protected MeteorsManager meteors;
+        protected PowerSource powerSource;
+        protected ImageComponent background;
+        protected Score score;
+		protected ExplosionManager _explosions;
+
+        // Gui Stuff
+        protected Vector2 pausePosition;
+        protected Vector2 gameoverPosition;
+        protected Rectangle pauseRect = new Rectangle(84, 65, 99, 30);
+        protected Rectangle gameoverRect = new Rectangle(53, 108, 186, 30);
+
+        // GameState elements
+        protected bool paused;
+        protected bool gameOver;
+        protected TimeSpan elapsedTime = TimeSpan.Zero;
+
+        /// <summary>
+        /// Default Constructor
+        /// </summary>
+        /// <param name="game">The main game object</param>
+        /// <param name="theTexture">Texture with the sprite elements</param>
+        /// <param name="backgroundTexture">Texture for the background</param>
+        /// <param name="font">Font used in the score</param>
+        public ActionScene(Game game, Texture2D theTexture, 
+            Texture2D backgroundTexture, SpriteFont font, ExplosionManager explosions) 
+            : base(game)
+        {
+            // Get the current audiocomponent and play the background music
+            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));
+
+            background = new ImageComponent(game, backgroundTexture, 
+                ImageComponent.DrawMode.Stretch);
+            Components.Add(background);
+
+            actionTexture = theTexture;
+
+            spriteBatch = (SpriteBatch) 
+                Game.Services.GetService(typeof (SpriteBatch));
+            meteors = new MeteorsManager(Game, ref actionTexture);
+            Components.Add(meteors);
+
+            player = new Player(Game, ref actionTexture);
+            player.Initialize();
+            Components.Add(player);
+
+            score = new Score(game, font, Color.LightGray);
+            score.Position = new Vector2(1, 1);
+            Components.Add(score);
+
+            powerSource = new PowerSource(game, ref actionTexture);
+            powerSource.Initialize();
+            Components.Add(powerSource);
+			
+			_explosions = explosions;
+        }
+
+        /// <summary>
+        /// Show the action scene
+        /// </summary>
+        public override void Show()
+        {
+            // GamePad.Visible is not available in MonoGame 3.8.4
+            // GamePad.Visible = true;
+            
+            MediaPlayer.Play(audio.BackMusic);
+
+            meteors.Initialize();
+            powerSource.PutinStartPosition();
+
+            player.Reset();
+
+            paused = false;
+            pausePosition.X = (Game.Window.ClientBounds.Width - 
+                pauseRect.Width)/2;
+            pausePosition.Y = (Game.Window.ClientBounds.Height - 
+                pauseRect.Height)/2;
+
+            gameOver = false;
+            gameoverPosition.X = (Game.Window.ClientBounds.Width - 
+                gameoverRect.Width)/2;
+            gameoverPosition.Y = (Game.Window.ClientBounds.Height - 
+                gameoverRect.Height)/2;
+
+            // Is a two-player game?
+            player.Visible = true;
+
+            base.Show();
+        }
+
+        /// <summary>
+        /// Hide the scene
+        /// </summary>
+        public override void Hide()
+        {
+            // Stop the background music
+            MediaPlayer.Stop();
+
+            base.Hide();
+        }
+
+        /// <summary>
+        /// True, if the game is in GameOver state
+        /// </summary>
+        public bool GameOver
+        {
+            get { return gameOver; }
+        }
+
+        /// <summary>
+        /// Paused mode
+        /// </summary>
+        public bool Paused
+        {
+            get { return paused; }
+            set
+            {
+                paused = value;
+                if (paused)
+                {
+					//==================================
+            		//AUDIO IS NOT SUPPORTED IN XNATOUCH
+            		//==================================
+                    //MediaPlayer.Pause();
+                }
+                else
+                {
+					//==================================
+            		//AUDIO IS NOT SUPPORTED IN XNATOUCH
+            		//==================================
+                    //MediaPlayer.Resume();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Handle collisions with a meteor
+        /// </summary>
+        private void HandleDamages()
+        {
+            // Check Collision for player 1
+            if (meteors.CheckForCollisions(player.GetBounds()))
+            {
+                // Player penalty
+                player.Power -= 10;
+				
+				_explosions.AddExplosion(player.Position);
+            }
+        }
+
+        /// <summary>
+        /// Handle power-up stuff
+        /// </summary>
+        private void HandlePowerSourceSprite(GameTime gameTime)
+        {
+            // Player 1 get the power source
+            if (powerSource.CheckCollision(player.GetBounds()))
+            {
+                audio.PowerGet.Play();
+                elapsedTime = TimeSpan.Zero;
+                powerSource.PutinStartPosition();
+                player.Power += 50;
+            }
+
+            // Check for send a new Power source
+            elapsedTime += gameTime.ElapsedGameTime;
+            if (elapsedTime > TimeSpan.FromSeconds(15))
+            {
+                elapsedTime -= TimeSpan.FromSeconds(15);
+                powerSource.Enabled = true;
+                audio.PowerShow.Play();
+            }
+        }
+
+        /// <summary>
+        /// Allows the game component to update itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        public override void Update(GameTime gameTime)
+        {
+			// Update the explosions
+            _explosions.Update(gameTime);
+			
+            if ((!paused) && (!gameOver))
+            {
+                // Check collisions with meteors
+                HandleDamages();				 
+
+                // Check if a player get a power boost
+                HandlePowerSourceSprite(gameTime);
+
+                // Update score
+                score.Value = player.Score;
+                score.Power = player.Power;
+
+                // Check if player is dead
+                gameOver = (player.Power <= 0);
+                if (gameOver)
+                {
+                    player.Visible = (player.Power > 0);
+                    
+            		// Stop the music
+					MediaPlayer.Stop();
+                }
+
+                // Update all other game components
+                base.Update(gameTime);
+            }
+
+            // In game over state, keep the meteors animation
+            if (gameOver)
+            {
+                meteors.Update(gameTime);
+            }
+        }
+
+        /// <summary>
+        /// Allows the game component to draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            // Draw all game components
+            base.Draw(gameTime);
+			
+            if (paused)
+            {
+                // Draw the "pause" text
+                spriteBatch.Draw(actionTexture, pausePosition, pauseRect, 
+                    Color.White);
+            }
+            if (gameOver)
+            {
+                // Draw the "gameover" text
+                spriteBatch.Draw(actionTexture, gameoverPosition, gameoverRect, 
+                    Color.White);
+            }
+			
+		}		
+    }
 }

+ 107 - 107
RockRain/AudioLibrary.cs → RockRain/Core/AudioLibrary.cs

@@ -1,108 +1,108 @@
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.Media;
-
-namespace RockRainIphone
-{
-    public class AudioLibrary
-    {
-        private SoundEffect explosion;
-        private SoundEffect newMeteor;
-        private SoundEffect menuBack;
-        private SoundEffect menuSelect;
-        private SoundEffect powerGet;
-        private SoundEffect powerShow;
-        private Song backMusic;
-        private Song startMusic;
-
-		ContentManager Content;
-		
-        public SoundEffect Explosion
-        {
-            get 
-			{ 	
-				if (explosion == null)
-					explosion = Content.Load<SoundEffect>("explosion");
-				return explosion; 
-			}
-        }
-
-        public SoundEffect NewMeteor
-        {
-            get 
-			{
-				if (newMeteor == null)
-					newMeteor = Content.Load<SoundEffect>("newmeteor");        
-				return newMeteor; 
-			}
-        }
-
-        public SoundEffect MenuBack
-        {
-            get 
-			{
-				if (menuBack == null)
-					menuBack = Content.Load<SoundEffect>("menu_back");
-				return menuBack; 
-			}
-        }
-
-        public SoundEffect MenuSelect
-        {
-            get 
-			{
-				if (menuSelect == null)
-					menuSelect = Content.Load<SoundEffect>("menu_select3");
-				return menuSelect; 
-			}
-        }
-
-        public SoundEffect PowerGet
-        {
-            get 
-			{ 
-				if (powerGet == null)
-					powerGet = Content.Load<SoundEffect>("powerget");
-				return powerGet; 
-			}
-        }
-
-        public SoundEffect PowerShow
-        {
-            get 
-			{ 
-				if (powerShow == null) 
-					powerShow = Content.Load<SoundEffect>("powershow");
-				return powerShow; 
-			}
-        }
-
-        public Song BackMusic
-        {
-            get 
-			{
-				if (backMusic == null)
-					backMusic = Content.Load<Song>("backmusic.mp3");
-				return backMusic; 
-			}
-        }
-
-        public Song StartMusic
-        {
-            get 
-			{ 
-				if (startMusic == null)
-				{
-					 startMusic = Content.Load<Song>("startmusic.mp3");
-				}
-				return startMusic; 
-			}
-        }
-
-        public AudioLibrary(ContentManager Content)
-        {
-			this.Content = Content;         
-        }
-
-    }
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Media;
+
+namespace RockRain
+{
+    public class AudioLibrary
+    {
+        private SoundEffect explosion;
+        private SoundEffect newMeteor;
+        private SoundEffect menuBack;
+        private SoundEffect menuSelect;
+        private SoundEffect powerGet;
+        private SoundEffect powerShow;
+        private Song backMusic;
+        private Song startMusic;
+
+		ContentManager Content;
+		
+        public SoundEffect Explosion
+        {
+            get 
+			{ 	
+				if (explosion == null)
+					explosion = Content.Load<SoundEffect>("explosion");
+				return explosion; 
+			}
+        }
+
+        public SoundEffect NewMeteor
+        {
+            get 
+			{
+				if (newMeteor == null)
+					newMeteor = Content.Load<SoundEffect>("newmeteor");        
+				return newMeteor; 
+			}
+        }
+
+        public SoundEffect MenuBack
+        {
+            get 
+			{
+				if (menuBack == null)
+					menuBack = Content.Load<SoundEffect>("menu_back");
+				return menuBack; 
+			}
+        }
+
+        public SoundEffect MenuSelect
+        {
+            get 
+			{
+				if (menuSelect == null)
+					menuSelect = Content.Load<SoundEffect>("menu_select3");
+				return menuSelect; 
+			}
+        }
+
+        public SoundEffect PowerGet
+        {
+            get 
+			{ 
+				if (powerGet == null)
+					powerGet = Content.Load<SoundEffect>("powerget");
+				return powerGet; 
+			}
+        }
+
+        public SoundEffect PowerShow
+        {
+            get 
+			{ 
+				if (powerShow == null) 
+					powerShow = Content.Load<SoundEffect>("powershow");
+				return powerShow; 
+			}
+        }
+
+        public Song BackMusic
+        {
+            get 
+			{
+				if (backMusic == null)
+					backMusic = Content.Load<Song>("backmusic.mp3");
+				return backMusic; 
+			}
+        }
+
+        public Song StartMusic
+        {
+            get 
+			{ 
+				if (startMusic == null)
+				{
+					 startMusic = Content.Load<Song>("startmusic.mp3");
+				}
+				return startMusic; 
+			}
+        }
+
+        public AudioLibrary(ContentManager Content)
+        {
+			this.Content = Content;         
+        }
+
+    }
 }

+ 158 - 0
RockRain/Core/Content/Content.mgcb

@@ -0,0 +1,158 @@
+
+#----------------------------- Global Properties ----------------------------#
+
+/outputDir:bin/$(Platform)
+/intermediateDir:obj/$(Platform)
+/platform:DesktopGL
+/config:$(Configuration)
+/profile:HiDef
+/compress:False
+
+#---------------------------------- Content ---------------------------------#
+
+# Audio (.wav)
+#begin explosion.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:explosion.wav
+#begin menu_back.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:menu_back.wav
+#begin menu_scroll.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:menu_scroll.wav
+#begin menu_select3.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:menu_select3.wav
+#begin newmeteor.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:newmeteor.wav
+#begin powerget.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:powerget.wav
+#begin powershow.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:powershow.wav
+
+# Audio (.mp3)
+#begin backmusic.mp3
+/importer:Mp3Importer
+/processor:SongProcessor
+/build:backmusic.mp3
+#begin startmusic.mp3
+/importer:Mp3Importer
+/processor:SongProcessor
+/build:startmusic.mp3
+
+# Images
+#begin Default.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:Default.png
+#begin explosion.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:explosion.png
+#begin gamepad.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:gamepad.png
+#begin GameThumbnail.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:GameThumbnail.png
+#begin helpscreen.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:helpscreen.png
+#begin rockrainenhanced.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:rockrainenhanced.png
+#begin spacebackground.jpg
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:spacebackground.jpg
+#begin startbackground.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:startbackground.png
+#begin startsceneelements.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyEnabled=False
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:startsceneelements.png
+
+# Fonts (XNB, already compiled)
+#begin menuLarge.xnb
+/copy:menuLarge.xnb
+#begin menuSmall.xnb
+/copy:menuSmall.xnb
+#begin score.xnb
+/copy:score.xnb

+ 0 - 0
RockRain/Default.png → RockRain/Core/Content/Default.png


+ 0 - 0
RockRain/GameThumbnail.png → RockRain/Core/Content/GameThumbnail.png


+ 0 - 0
RockRain/Content/backmusic.mp3 → RockRain/Core/Content/backmusic.mp3


+ 0 - 0
RockRain/Content/explosion.png → RockRain/Core/Content/explosion.png


+ 0 - 0
RockRain/Content/explosion.wav → RockRain/Core/Content/explosion.wav


+ 0 - 0
RockRain/Content/gamepad.png → RockRain/Core/Content/gamepad.png


+ 0 - 0
RockRain/Content/helpscreen.png → RockRain/Core/Content/helpscreen.png


+ 0 - 0
RockRain/Content/menuLarge.xnb → RockRain/Core/Content/menuLarge.xnb


+ 0 - 0
RockRain/Content/menuSmall.xnb → RockRain/Core/Content/menuSmall.xnb


+ 0 - 0
RockRain/Content/menu_back.wav → RockRain/Core/Content/menu_back.wav


+ 0 - 0
RockRain/Content/menu_scroll.wav → RockRain/Core/Content/menu_scroll.wav


+ 0 - 0
RockRain/Content/menu_select3.wav → RockRain/Core/Content/menu_select3.wav


+ 0 - 0
RockRain/Content/newmeteor.wav → RockRain/Core/Content/newmeteor.wav


+ 0 - 0
RockRain/Content/powerget.wav → RockRain/Core/Content/powerget.wav


+ 0 - 0
RockRain/Content/powershow.wav → RockRain/Core/Content/powershow.wav


+ 0 - 0
RockRain/Content/rockrainenhanced.png → RockRain/Core/Content/rockrainenhanced.png


+ 0 - 0
RockRain/Content/score.xnb → RockRain/Core/Content/score.xnb


+ 0 - 0
RockRain/Content/spacebackground.jpg → RockRain/Core/Content/spacebackground.jpg


+ 0 - 0
RockRain/Content/startbackground.png → RockRain/Core/Content/startbackground.png


+ 0 - 0
RockRain/Content/startmusic.mp3 → RockRain/Core/Content/startmusic.mp3


+ 0 - 0
RockRain/Content/startsceneelements.png → RockRain/Core/Content/startsceneelements.png


+ 70 - 70
RockRain/ExplosionManager.cs → RockRain/Core/ExplosionManager.cs

@@ -1,71 +1,71 @@
-using System.Collections.Generic;
-using Microsoft.Xna.Framework;
-using RockRainIphone.Core;
-
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is a game component that implements IUpdateable.
-    /// </summary>
-    public class ExplosionManager : Microsoft.Xna.Framework.DrawableGameComponent
-    {
-        protected List<ExplosionParticleSystem> explosions;
-
-        public ExplosionManager(Game game)
-            : base(game)
-        {
-            explosions = new List<ExplosionParticleSystem>();
-        }
-
-        /// <summary>
-        /// Allows the game component to perform any initialization it needs to before starting
-        /// to run.  This is where it can query for any required services and load content.
-        /// </summary>
-        public override void Initialize()
-        {
-            // TODO: Add your initialization code here
-
-            base.Initialize();
-        }
-
-        public void AddExplosion(Vector2 position)
-        {
-            ExplosionParticleSystem explosion = new ExplosionParticleSystem(Game, 1);
-            explosion.AddParticles(position);
-            explosions.Add(explosion);
-        }
-
-        /// <summary>
-        /// Allows the game component to update itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        public override void Update(GameTime gameTime)
-        {
-            for (int i = 0; i < explosions.Count; i++)
-            {
-                if (!explosions[i].Active)
-                {
-                    explosions.RemoveAt(i);
-                    i--;
-                }
-                else
-                {
-                    explosions[i].Update(gameTime);
-                }
-            }
-
-            base.Update(gameTime);
-        }
-
-        public override void Draw(GameTime gameTime)
-        {
-            for (int i = 0; i < explosions.Count; i++)
-            {
-                explosions[i].Draw(gameTime);
-            }
-
-            base.Draw(gameTime);
-        }
-    }
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using RockRain.Core;
+
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is a game component that implements IUpdateable.
+    /// </summary>
+    public class ExplosionManager : Microsoft.Xna.Framework.DrawableGameComponent
+    {
+        protected List<ExplosionParticleSystem> explosions;
+
+        public ExplosionManager(Game game)
+            : base(game)
+        {
+            explosions = new List<ExplosionParticleSystem>();
+        }
+
+        /// <summary>
+        /// Allows the game component to perform any initialization it needs to before starting
+        /// to run.  This is where it can query for any required services and load content.
+        /// </summary>
+        public override void Initialize()
+        {
+            // TODO: Add your initialization code here
+
+            base.Initialize();
+        }
+
+        public void AddExplosion(Vector2 position)
+        {
+            ExplosionParticleSystem explosion = new ExplosionParticleSystem(Game, 1);
+            explosion.AddParticles(position);
+            explosions.Add(explosion);
+        }
+
+        /// <summary>
+        /// Allows the game component to update itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        public override void Update(GameTime gameTime)
+        {
+            for (int i = 0; i < explosions.Count; i++)
+            {
+                if (!explosions[i].Active)
+                {
+                    explosions.RemoveAt(i);
+                    i--;
+                }
+                else
+                {
+                    explosions[i].Update(gameTime);
+                }
+            }
+
+            base.Update(gameTime);
+        }
+
+        public override void Draw(GameTime gameTime)
+        {
+            for (int i = 0; i < explosions.Count; i++)
+            {
+                explosions[i].Draw(gameTime);
+            }
+
+            base.Draw(gameTime);
+        }
+    }
 }

+ 1 - 5
RockRain/Core/ExplosionParticleSystem.cs

@@ -1,18 +1,14 @@
-#region File Description
 //-----------------------------------------------------------------------------
 // ExplosionParticleSystem.cs
 //
 // Microsoft XNA Community Game Platform
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
-#endregion
 
-#region Using Statements
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
-#endregion
 
-namespace RockRainIphone.Core
+namespace RockRain.Core
 {
     /// <summary>
     /// ExplosionParticleSystem is a specialization of ParticleSystem which creates a

+ 2 - 4
RockRain/Core/GameScene.cs

@@ -1,11 +1,9 @@
-#region Using Statements
 
 using System.Collections.Generic;
 using Microsoft.Xna.Framework;
 
-#endregion
 
-namespace RockRainIphone.Core
+namespace RockRain.Core
 {
     /// <summary>
     /// This is the base class for all game scenes.
@@ -87,4 +85,4 @@ namespace RockRainIphone.Core
             base.Draw(gameTime);
         }
     }
-}
+}

+ 22 - 24
RockRain/helpScene.cs → RockRain/Core/HelpScene.cs

@@ -1,24 +1,22 @@
-#region Using Statements
-
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using RockRainIphone.Core;
-using Microsoft.Xna.Framework.Input;
-
-#endregion
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is a game component thats represents the Instrucions Scene
-    /// </summary>
-    public class HelpScene : GameScene
-    {
-        public HelpScene(Game game, Texture2D textureBack)
-            : base(game)
-        {
-            Components.Add(new ImageComponent(game, textureBack, 
-                ImageComponent.DrawMode.Stretch));
-        }
-    }
-}
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using RockRain.Core;
+using Microsoft.Xna.Framework.Input;
+
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is a game component thats represents the Instrucions Scene
+    /// </summary>
+    public class HelpScene : GameScene
+    {
+        public HelpScene(Game game, Texture2D textureBack)
+            : base(game)
+        {
+            Components.Add(new ImageComponent(game, textureBack, 
+                ImageComponent.DrawMode.Stretch));
+        }
+    }
+}

+ 2 - 4
RockRain/Core/ImageComponent.cs

@@ -1,11 +1,9 @@
-#region Using Statements
 
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 
-#endregion
 
-namespace RockRainIphone.Core
+namespace RockRain.Core
 {
     /// <summary>
     /// This is a game component that draw a image.
@@ -67,4 +65,4 @@ namespace RockRainIphone.Core
             base.Draw(gameTime);
         }
     }
-}
+}

+ 137 - 137
RockRain/Meteor.cs → RockRain/Core/Meteor.cs

@@ -1,138 +1,138 @@
-using System;
-using System.Collections.Generic;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using RockRainIphone.Core;
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This class is the Animated Sprite for a Meteor
-    /// </summary>
-    public class Meteor : Sprite
-    {
-        // Vertical velocity
-        protected int Yspeed;
-        // Horizontal velocity
-        protected int Xspeed;
-        protected Random random;
-        // Unique id for this meteor
-        private int index;
-
-        public Meteor(Game game, ref Texture2D theTexture) : 
-            base(game, ref theTexture)
-        {
-            Frames = new List<Rectangle>();
-            Rectangle frame = new Rectangle();
-            frame.X = 15;
-            frame.Y = 10;
-            frame.Width = 23;
-            frame.Height = 24;
-            Frames.Add(frame);
-
-            frame.Y = 37;
-            Frames.Add(frame);
-
-            frame.Y = 63;
-            frame.Height = 24;
-            Frames.Add(frame);
-
-            frame.Y = 89;
-            frame.Height = 27;
-            Frames.Add(frame);
-
-            frame.Y = 119;
-            frame.Height = 24;
-            Frames.Add(frame);
-
-            frame.Y = 145;
-            Frames.Add(frame);
-
-            frame.Y = 171;
-            Frames.Add(frame);
-
-            frame.Y = 199;
-            frame.Height = 26;
-            Frames.Add(frame);
-
-            // Initialize the random number generator and put the meteor in your
-            // start position
-            random = new Random(GetHashCode());
-            PutinStartPosition();
-        }
-
-        /// <summary>
-        /// Initialize Meteor Position and Velocity
-        /// </summary>
-        public void PutinStartPosition()
-        {
-            position.X = random.Next(Game.Window.ClientBounds.Width - 
-                currentFrame.Width);
-            position.Y = 0;
-            YSpeed = 1 + random.Next(3);
-            XSpeed = random.Next(3) - 1;
-        }
-
-        /// Vertical velocity
-        /// </summary>
-        public int YSpeed
-        {
-            get { return Yspeed; }
-            set
-            {
-                Yspeed = value;
-                frameDelay = 200 - (Yspeed * 2);
-            }
-        }
-
-        /// <summary>
-        /// Horizontal Velocity
-        /// </summary>
-        public int XSpeed
-        {
-            get { return Xspeed; }
-            set { Xspeed = value; }
-        }
-
-        /// <summary>
-        /// Meteor Identifier
-        /// </summary>
-        public int Index
-        {
-            get { return index; }
-            set { index = value; }
-        }
-
-        /// <summary>
-        /// Update the Meteor Position
-        /// </summary>
-        public override void Update(GameTime gameTime)
-        {
-            // Check if the meteor still visible
-            if ((position.Y >= Game.Window.ClientBounds.Height) || 
-                (position.X >= Game.Window.ClientBounds.Width) ||
-                (position.X <= 0))
-            {
-                PutinStartPosition();
-            }
-
-            // Move meteor
-            position.Y += Yspeed;
-            position.X += Xspeed;
-
-            base.Update(gameTime);
-        }
-
-        /// <summary>
-        /// Check if the meteor intersects with the specified rectangle
-        /// </summary>
-        /// <param name="rect">test rectangle</param>
-        /// <returns>true, if has a collision</returns>
-        public bool CheckCollision(Rectangle rect)
-        {
-            Rectangle spriterect =new Rectangle((int) position.X, (int) position.Y, 
-                currentFrame.Width, currentFrame.Height);
-            return spriterect.Intersects(rect);
-        }
-    }
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using RockRain.Core;
+
+namespace RockRain
+{
+    /// <summary>
+    /// This class is the Animated Sprite for a Meteor
+    /// </summary>
+    public class Meteor : Sprite
+    {
+        // Vertical velocity
+        protected int Yspeed;
+        // Horizontal velocity
+        protected int Xspeed;
+        protected Random random;
+        // Unique id for this meteor
+        private int index;
+
+        public Meteor(Game game, ref Texture2D theTexture) : 
+            base(game, ref theTexture)
+        {
+            Frames = new List<Rectangle>();
+            Rectangle frame = new Rectangle();
+            frame.X = 15;
+            frame.Y = 10;
+            frame.Width = 23;
+            frame.Height = 24;
+            Frames.Add(frame);
+
+            frame.Y = 37;
+            Frames.Add(frame);
+
+            frame.Y = 63;
+            frame.Height = 24;
+            Frames.Add(frame);
+
+            frame.Y = 89;
+            frame.Height = 27;
+            Frames.Add(frame);
+
+            frame.Y = 119;
+            frame.Height = 24;
+            Frames.Add(frame);
+
+            frame.Y = 145;
+            Frames.Add(frame);
+
+            frame.Y = 171;
+            Frames.Add(frame);
+
+            frame.Y = 199;
+            frame.Height = 26;
+            Frames.Add(frame);
+
+            // Initialize the random number generator and put the meteor in your
+            // start position
+            random = new Random(GetHashCode());
+            PutinStartPosition();
+        }
+
+        /// <summary>
+        /// Initialize Meteor Position and Velocity
+        /// </summary>
+        public void PutinStartPosition()
+        {
+            position.X = random.Next(Game.Window.ClientBounds.Width - 
+                currentFrame.Width);
+            position.Y = 0;
+            YSpeed = 1 + random.Next(3);
+            XSpeed = random.Next(3) - 1;
+        }
+
+        /// Vertical velocity
+        /// </summary>
+        public int YSpeed
+        {
+            get { return Yspeed; }
+            set
+            {
+                Yspeed = value;
+                frameDelay = 200 - (Yspeed * 2);
+            }
+        }
+
+        /// <summary>
+        /// Horizontal Velocity
+        /// </summary>
+        public int XSpeed
+        {
+            get { return Xspeed; }
+            set { Xspeed = value; }
+        }
+
+        /// <summary>
+        /// Meteor Identifier
+        /// </summary>
+        public int Index
+        {
+            get { return index; }
+            set { index = value; }
+        }
+
+        /// <summary>
+        /// Update the Meteor Position
+        /// </summary>
+        public override void Update(GameTime gameTime)
+        {
+            // Check if the meteor still visible
+            if ((position.Y >= Game.Window.ClientBounds.Height) || 
+                (position.X >= Game.Window.ClientBounds.Width) ||
+                (position.X <= 0))
+            {
+                PutinStartPosition();
+            }
+
+            // Move meteor
+            position.Y += Yspeed;
+            position.X += Xspeed;
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// Check if the meteor intersects with the specified rectangle
+        /// </summary>
+        /// <param name="rect">test rectangle</param>
+        /// <returns>true, if has a collision</returns>
+        public bool CheckCollision(Rectangle rect)
+        {
+            Rectangle spriterect =new Rectangle((int) position.X, (int) position.Y, 
+                currentFrame.Width, currentFrame.Height);
+            return spriterect.Intersects(rect);
+        }
+    }
 }

+ 164 - 166
RockRain/MeteorsManager.cs → RockRain/Core/MeteorsManager.cs

@@ -1,166 +1,164 @@
-#region Using Statements
-
-using System;
-using System.Collections.Generic;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using RockRainIphone.Core;
-
-#endregion
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This game component implements a manager for all Meteors in the game.
-    /// </summary>
-    public class MeteorsManager : DrawableGameComponent
-    {
-        // List of active meteors
-        protected List<Meteor> meteors;
-        // Constant for initial meteor count
-        private const int STARTMETEORCOUNT = 5;
-        // Time for a new meteor
-        private const int ADDMETEORTIME = 6000;
-
-        protected Texture2D meteorTexture;
-        protected TimeSpan elapsedTime = TimeSpan.Zero;
-        protected AudioLibrary audio;
-
-        public MeteorsManager(Game game, ref Texture2D theTexture)
-            : base(game)
-        {
-            meteorTexture = theTexture;
-            meteors = new List<Meteor>();
-        }
-
-        /// <summary>
-        /// Allows the game component to perform any initialization it needs to 
-        /// before starting to run.  This is where it can query for any required
-        /// services and load content.
-        /// </summary>
-        public override void Initialize()
-        {
-            // Get the current audiocomponent and play the background music
-            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));
-
-            meteors.Clear();
-
-            Start();
-
-            for (int i = 0; i < meteors.Count; i++)
-            {
-                meteors[i].Initialize();
-            }
-
-            base.Initialize();
-        }
-
-        /// <summary>
-        /// Start the Meteors Rain
-        /// </summary>
-        public void Start()
-        {
-            // Initialize a counter
-            elapsedTime = TimeSpan.Zero;
-
-            // Add the meteors
-            for (int i = 0; i < STARTMETEORCOUNT; i++)
-            {
-                AddNewMeteor();
-            }
-        }
-
-        /// <summary>
-        /// All Meteors in the game
-        /// </summary>
-        public List<Meteor> AllMeteors
-        {
-            get { return meteors; }
-        }
-
-        /// <summary>
-        /// Check if is a moment for a new meteor
-        /// </summary>
-        private void CheckforNewMeteor(GameTime gameTime)
-        {
-            // Add a rock each ADDMETEORTIME
-            elapsedTime += gameTime.ElapsedGameTime;
-
-            if (elapsedTime > TimeSpan.FromMilliseconds(ADDMETEORTIME))
-            {
-                elapsedTime -= TimeSpan.FromMilliseconds(ADDMETEORTIME);
-
-                AddNewMeteor();
-                // Play a sound for a new meteor
-                audio.NewMeteor.Play();
-            }
-        }
-
-        /// <summary>
-        /// Add a new meteor in the scene
-        /// </summary>
-        private Meteor AddNewMeteor()
-        {
-            Meteor newMeteor = new Meteor(Game, ref meteorTexture);
-            newMeteor.Initialize();
-            meteors.Add(newMeteor);
-            // Set the meteor identifier
-            newMeteor.Index = meteors.Count - 1;
-
-            return newMeteor;
-        }
-
-        /// <summary>
-        /// Allows the game component to update itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        public override void Update(GameTime gameTime)
-        {
-            CheckforNewMeteor(gameTime);
-
-            // Update Meteors
-            for (int i = 0; i < meteors.Count; i++)
-            {
-                meteors[i].Update(gameTime);
-            }
-
-            base.Update(gameTime);
-        }
-
-        /// <summary>
-        /// Check if the ship collide with a meteor
-        /// <returns>true, if has a collision</returns>
-        /// </summary>
-        public bool CheckForCollisions(Rectangle rect)
-        {
-            for (int i = 0; i < meteors.Count; i++)
-            {
-                if (meteors[i].CheckCollision(rect))
-                {
-                    // BOM !!
-                    audio.Explosion.Play();
-
-                    // Put the meteor back to your initial position
-                    meteors[i].PutinStartPosition();
-
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /// <summary>
-        /// Allows the game component draw your content in game screen
-        /// </summary>
-        public override void Draw(GameTime gameTime)
-        {
-            // Draw the meteors
-            for (int i = 0; i < meteors.Count; i++)
-            {
-                meteors[i].Draw(gameTime);
-            }
-
-            base.Draw(gameTime);
-        }
-    }
-}
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using RockRain.Core;
+
+
+namespace RockRain
+{
+    /// <summary>
+    /// This game component implements a manager for all Meteors in the game.
+    /// </summary>
+    public class MeteorsManager : DrawableGameComponent
+    {
+        // List of active meteors
+        protected List<Meteor> meteors;
+        // Constant for initial meteor count
+        private const int STARTMETEORCOUNT = 5;
+        // Time for a new meteor
+        private const int ADDMETEORTIME = 6000;
+
+        protected Texture2D meteorTexture;
+        protected TimeSpan elapsedTime = TimeSpan.Zero;
+        protected AudioLibrary audio;
+
+        public MeteorsManager(Game game, ref Texture2D theTexture)
+            : base(game)
+        {
+            meteorTexture = theTexture;
+            meteors = new List<Meteor>();
+        }
+
+        /// <summary>
+        /// Allows the game component to perform any initialization it needs to 
+        /// before starting to run.  This is where it can query for any required
+        /// services and load content.
+        /// </summary>
+        public override void Initialize()
+        {
+            // Get the current audiocomponent and play the background music
+            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));
+
+            meteors.Clear();
+
+            Start();
+
+            for (int i = 0; i < meteors.Count; i++)
+            {
+                meteors[i].Initialize();
+            }
+
+            base.Initialize();
+        }
+
+        /// <summary>
+        /// Start the Meteors Rain
+        /// </summary>
+        public void Start()
+        {
+            // Initialize a counter
+            elapsedTime = TimeSpan.Zero;
+
+            // Add the meteors
+            for (int i = 0; i < STARTMETEORCOUNT; i++)
+            {
+                AddNewMeteor();
+            }
+        }
+
+        /// <summary>
+        /// All Meteors in the game
+        /// </summary>
+        public List<Meteor> AllMeteors
+        {
+            get { return meteors; }
+        }
+
+        /// <summary>
+        /// Check if is a moment for a new meteor
+        /// </summary>
+        private void CheckforNewMeteor(GameTime gameTime)
+        {
+            // Add a rock each ADDMETEORTIME
+            elapsedTime += gameTime.ElapsedGameTime;
+
+            if (elapsedTime > TimeSpan.FromMilliseconds(ADDMETEORTIME))
+            {
+                elapsedTime -= TimeSpan.FromMilliseconds(ADDMETEORTIME);
+
+                AddNewMeteor();
+                // Play a sound for a new meteor
+                audio.NewMeteor.Play();
+            }
+        }
+
+        /// <summary>
+        /// Add a new meteor in the scene
+        /// </summary>
+        private Meteor AddNewMeteor()
+        {
+            Meteor newMeteor = new Meteor(Game, ref meteorTexture);
+            newMeteor.Initialize();
+            meteors.Add(newMeteor);
+            // Set the meteor identifier
+            newMeteor.Index = meteors.Count - 1;
+
+            return newMeteor;
+        }
+
+        /// <summary>
+        /// Allows the game component to update itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        public override void Update(GameTime gameTime)
+        {
+            CheckforNewMeteor(gameTime);
+
+            // Update Meteors
+            for (int i = 0; i < meteors.Count; i++)
+            {
+                meteors[i].Update(gameTime);
+            }
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// Check if the ship collide with a meteor
+        /// <returns>true, if has a collision</returns>
+        /// </summary>
+        public bool CheckForCollisions(Rectangle rect)
+        {
+            for (int i = 0; i < meteors.Count; i++)
+            {
+                if (meteors[i].CheckCollision(rect))
+                {
+                    // BOM !!
+                    audio.Explosion.Play();
+
+                    // Put the meteor back to your initial position
+                    meteors[i].PutinStartPosition();
+
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /// <summary>
+        /// Allows the game component draw your content in game screen
+        /// </summary>
+        public override void Draw(GameTime gameTime)
+        {
+            // Draw the meteors
+            for (int i = 0; i < meteors.Count; i++)
+            {
+                meteors[i].Draw(gameTime);
+            }
+
+            base.Draw(gameTime);
+        }
+    }
+}

+ 1 - 5
RockRain/Core/Particle.cs

@@ -1,18 +1,14 @@
-#region File Description
 //-----------------------------------------------------------------------------
 // Particle.cs
 //
 // Microsoft XNA Community Game Platform
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
-#endregion
 
-#region Using Statements
 using System;
 using Microsoft.Xna.Framework;
-#endregion
 
-namespace RockRainIphone.Core
+namespace RockRain.Core
 {
     /// <summary>
     /// particles are the little bits that will make up an effect. each effect will

+ 1 - 7
RockRain/Core/ParticleSystem.cs

@@ -1,20 +1,16 @@
-#region File Description
 //-----------------------------------------------------------------------------
 // SmokePlumeParticleSystem.cs
 //
 // Microsoft XNA Community Game Platform
 // Copyright (C) Microsoft Corporation. All rights reserved.
 //-----------------------------------------------------------------------------
-#endregion
 
-#region Using Statements
 using System;
 using System.Collections.Generic;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
-#endregion
 
-namespace RockRainIphone.Core
+namespace RockRain.Core
 {
     /// <summary>
     /// ParticleSystem is an abstract class that provides the basic functionality to
@@ -69,7 +65,6 @@ namespace RockRainIphone.Core
         // values are then used by the virtual function InitializeParticle. Subclasses
         // can override InitializeParticle for further
         // customization.
-        #region constants to be set by subclasses
 
         /// <summary>
         /// minNumParticles and maxNumParticles control the number of particles that are
@@ -138,7 +133,6 @@ namespace RockRainIphone.Core
         /// </summary>
         protected BlendState spriteBlendMode;
 
-        #endregion
         
         /// <summary>
         /// Constructs a new ParticleSystem.

+ 182 - 184
RockRain/Player.cs → RockRain/Core/Player.cs

@@ -1,184 +1,182 @@
-#region Using Statements
-
-using System;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-
-#endregion
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is a game component that implements the player ship.
-    /// </summary>
-    public class Player : DrawableGameComponent
-    {
-        protected Texture2D texture;
-        protected Rectangle spriteRectangle;
-        protected Vector2 position;
-        protected TimeSpan elapsedTime = TimeSpan.Zero;
-
-        // Screen Area
-        protected Rectangle screenBounds;
-
-        // Game Stuff
-        protected int score;
-        protected int power;
-        private const int INITIALPOWER = 100;
-
-        public Player(Game game, ref Texture2D theTexture) : base(game)
-        {
-            texture = theTexture;
-            position = new Vector2();
-
-            // Create the source rectangle.
-            // This represents where is the sprite picture in surface
-            spriteRectangle = new Rectangle(86,11,24,22);
-
-            screenBounds = new Rectangle(0, 0, Game.Window.ClientBounds.Width, 
-                Game.Window.ClientBounds.Height);
-        }
-
-        /// <summary>
-        /// Put the ship in your start position in screen
-        /// </summary>
-        public void Reset()
-        {
-            position.X = screenBounds.Width/3;
-
-            position.Y = screenBounds.Height - spriteRectangle.Height;
-            score = 0;
-            power = INITIALPOWER;
-        }
-
-        /// <summary>
-        /// Total Points of the Player
-        /// </summary>
-        public int Score
-        {
-            get { return score; }
-            set
-            {
-                if (value < 0)
-                {
-                    score = 0;
-                }
-                else
-                {
-                    score = value;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Remaining Power
-        /// </summary>
-        public int Power
-        {
-            get { return power; }
-            set { power = value; }
-        }
-
-        /// <summary>
-        /// Update the ship position, points and power 
-        /// </summary>
-        public override void Update(GameTime gameTime)
-        {
-            HandleInput();
-            UpdateShip(gameTime);
-
-            base.Update(gameTime);
-        }
-
-
-        /// <summary>
-        /// Get the ship position
-        /// </summary>
-        protected void HandleInput()
-        {
-			GamePadState gamepadstatus = GamePad.GetState(PlayerIndex.One);
-            // Check the thumbstick
-            position.Y += (int)(gamepadstatus.ThumbSticks.Left.Y * -4);
-            position.X += (int)(gamepadstatus.ThumbSticks.Left.X * 4);
-			
-			// Check the accelerometer
-			position.Y += (int)(Accelerometer.GetState().Acceleration.Y * -4);
-            position.X += (int)(Accelerometer.GetState().Acceleration.X * 4);
-        }
-
-        /// <summary>
-        /// Update ship status
-        /// </summary>
-        private void UpdateShip(GameTime gameTime)
-        {
-            // Keep the player inside the screen
-            KeepInBound();
-
-            // Update score
-            elapsedTime += gameTime.ElapsedGameTime;
-
-            if (elapsedTime > TimeSpan.FromSeconds(1))
-            {
-                elapsedTime -= TimeSpan.FromSeconds(1);
-                score++;
-                power--;
-            }
-        }
-
-        /// <summary>
-        /// Keep the ship inside the screen
-        /// </summary>
-        private void KeepInBound()
-        {
-            if (position.X < screenBounds.Left)
-            {
-                position.X = screenBounds.Left;
-            }
-            if (position.X > screenBounds.Width - spriteRectangle.Width)
-            {
-                position.X = screenBounds.Width - spriteRectangle.Width;
-            }
-            if (position.Y < screenBounds.Top)
-            {
-                position.Y = screenBounds.Top;
-            }
-            if (position.Y > screenBounds.Height - spriteRectangle.Height)
-            {
-                position.Y = screenBounds.Height - spriteRectangle.Height;
-            }
-        }
-
-        /// <summary>
-        /// Draw the ship sprite
-        /// </summary>
-        public override void Draw(GameTime gameTime)
-        {
-            // Get the current spritebatch
-            SpriteBatch sBatch = (SpriteBatch) 
-                Game.Services.GetService(typeof (SpriteBatch));
-
-            // Draw the ship
-            sBatch.Draw(texture, position, spriteRectangle, Color.White);
-
-            base.Draw(gameTime);
-        }
-
-        /// <summary>
-        /// Get the bound rectangle of ship position in screen
-        /// </summary>
-        public Rectangle GetBounds()
-        {
-            return new Rectangle((int) position.X, (int) position.Y, 
-                spriteRectangle.Width, spriteRectangle.Height);
-        }
-		
-		public Vector2 Position
-		{
-			get
-			{
-				return position;
-			}
-		}
-    }
-}
+
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is a game component that implements the player ship.
+    /// </summary>
+    public class Player : DrawableGameComponent
+    {
+        protected Texture2D texture;
+        protected Rectangle spriteRectangle;
+        protected Vector2 position;
+        protected TimeSpan elapsedTime = TimeSpan.Zero;
+
+        // Screen Area
+        protected Rectangle screenBounds;
+
+        // Game Stuff
+        protected int score;
+        protected int power;
+        private const int INITIALPOWER = 100;
+
+        public Player(Game game, ref Texture2D theTexture) : base(game)
+        {
+            texture = theTexture;
+            position = new Vector2();
+
+            // Create the source rectangle.
+            // This represents where is the sprite picture in surface
+            spriteRectangle = new Rectangle(86,11,24,22);
+
+            screenBounds = new Rectangle(0, 0, Game.Window.ClientBounds.Width, 
+                Game.Window.ClientBounds.Height);
+        }
+
+        /// <summary>
+        /// Put the ship in your start position in screen
+        /// </summary>
+        public void Reset()
+        {
+            position.X = screenBounds.Width/3;
+
+            position.Y = screenBounds.Height - spriteRectangle.Height;
+            score = 0;
+            power = INITIALPOWER;
+        }
+
+        /// <summary>
+        /// Total Points of the Player
+        /// </summary>
+        public int Score
+        {
+            get { return score; }
+            set
+            {
+                if (value < 0)
+                {
+                    score = 0;
+                }
+                else
+                {
+                    score = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Remaining Power
+        /// </summary>
+        public int Power
+        {
+            get { return power; }
+            set { power = value; }
+        }
+
+        /// <summary>
+        /// Update the ship position, points and power 
+        /// </summary>
+        public override void Update(GameTime gameTime)
+        {
+            HandleInput();
+            UpdateShip(gameTime);
+
+            base.Update(gameTime);
+        }
+
+
+        /// <summary>
+        /// Get the ship position
+        /// </summary>
+        protected void HandleInput()
+        {
+			GamePadState gamepadstatus = GamePad.GetState(PlayerIndex.One);
+            // Check the thumbstick
+            position.Y += (int)(gamepadstatus.ThumbSticks.Left.Y * -4);
+            position.X += (int)(gamepadstatus.ThumbSticks.Left.X * 4);
+			
+			// Check the accelerometer - not available in MonoGame 3.8.4
+			// position.Y += (int)(Accelerometer.GetState().Acceleration.Y * -4);
+            // position.X += (int)(Accelerometer.GetState().Acceleration.X * 4);
+        }
+
+        /// <summary>
+        /// Update ship status
+        /// </summary>
+        private void UpdateShip(GameTime gameTime)
+        {
+            // Keep the player inside the screen
+            KeepInBound();
+
+            // Update score
+            elapsedTime += gameTime.ElapsedGameTime;
+
+            if (elapsedTime > TimeSpan.FromSeconds(1))
+            {
+                elapsedTime -= TimeSpan.FromSeconds(1);
+                score++;
+                power--;
+            }
+        }
+
+        /// <summary>
+        /// Keep the ship inside the screen
+        /// </summary>
+        private void KeepInBound()
+        {
+            if (position.X < screenBounds.Left)
+            {
+                position.X = screenBounds.Left;
+            }
+            if (position.X > screenBounds.Width - spriteRectangle.Width)
+            {
+                position.X = screenBounds.Width - spriteRectangle.Width;
+            }
+            if (position.Y < screenBounds.Top)
+            {
+                position.Y = screenBounds.Top;
+            }
+            if (position.Y > screenBounds.Height - spriteRectangle.Height)
+            {
+                position.Y = screenBounds.Height - spriteRectangle.Height;
+            }
+        }
+
+        /// <summary>
+        /// Draw the ship sprite
+        /// </summary>
+        public override void Draw(GameTime gameTime)
+        {
+            // Get the current spritebatch
+            SpriteBatch sBatch = (SpriteBatch) 
+                Game.Services.GetService(typeof (SpriteBatch));
+
+            // Draw the ship
+            sBatch.Draw(texture, position, spriteRectangle, Color.White);
+
+            base.Draw(gameTime);
+        }
+
+        /// <summary>
+        /// Get the bound rectangle of ship position in screen
+        /// </summary>
+        public Rectangle GetBounds()
+        {
+            return new Rectangle((int) position.X, (int) position.Y, 
+                spriteRectangle.Width, spriteRectangle.Height);
+        }
+		
+		public Vector2 Position
+		{
+			get
+			{
+				return position;
+			}
+		}
+    }
+}

+ 93 - 95
RockRain/PowerSource.cs → RockRain/Core/PowerSource.cs

@@ -1,95 +1,93 @@
-#region Using Statements
-
-using System;
-using System.Collections.Generic;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using RockRainIphone.Core;
-
-#endregion
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is a game component that implements Power Source Element.
-    /// </summary>
-    public class PowerSource : Sprite
-    {
-        protected Texture2D texture;
-        protected Random random;
-
-        public PowerSource(Game game, ref Texture2D theTexture)
-            : base(game, ref theTexture)
-        {
-            texture = theTexture;
-
-            Frames = new List<Rectangle>();
-            Rectangle frame = new Rectangle();
-            frame.X = 55;
-            frame.Y = 15;
-            frame.Width = 14;
-            frame.Height = 12;
-            Frames.Add(frame);
-
-            frame.Y = 29;
-            Frames.Add(frame);
-
-            frame.Y = 42;
-            Frames.Add(frame);
-
-            frame.Y = 56;
-            Frames.Add(frame);
-
-            frame.Y = 69;
-            Frames.Add(frame);
-
-            frame.Y = 81;
-            Frames.Add(frame);
-
-            frameDelay = 200;
-
-            // Initialize the random number generator and put the power source in your
-            // start position
-            random = new Random(GetHashCode());
-            PutinStartPosition();
-        }
-
-        /// <summary>
-        /// Initialize Position and Velocity
-        /// </summary>
-        public void PutinStartPosition()
-        {
-            position.X = random.Next(Game.Window.ClientBounds.Width - 
-                currentFrame.Width);
-            position.Y = -10;
-            Enabled = false;
-        }
-
-        public override void Update(GameTime gameTime)
-        {
-            // Check if the still visible
-            if (position.Y >= Game.Window.ClientBounds.Height)
-            {
-                PutinStartPosition();
-            }
-
-            // Move
-            position.Y += 1;
-
-            base.Update(gameTime);
-        }
-
-        /// <summary>
-        /// Check if the object intersects with the specified rectangle
-        /// </summary>
-        /// <param name="rect">test rectangle</param>
-        /// <returns>true, if has a collision</returns>
-        public bool CheckCollision(Rectangle rect)
-        {
-            Rectangle spriterect =
-                new Rectangle((int) position.X, (int) position.Y, 
-                currentFrame.Width, currentFrame.Height);
-            return spriterect.Intersects(rect);
-        }
-    }
-}
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using RockRain.Core;
+
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is a game component that implements Power Source Element.
+    /// </summary>
+    public class PowerSource : Sprite
+    {
+        protected Texture2D texture;
+        protected Random random;
+
+        public PowerSource(Game game, ref Texture2D theTexture)
+            : base(game, ref theTexture)
+        {
+            texture = theTexture;
+
+            Frames = new List<Rectangle>();
+            Rectangle frame = new Rectangle();
+            frame.X = 55;
+            frame.Y = 15;
+            frame.Width = 14;
+            frame.Height = 12;
+            Frames.Add(frame);
+
+            frame.Y = 29;
+            Frames.Add(frame);
+
+            frame.Y = 42;
+            Frames.Add(frame);
+
+            frame.Y = 56;
+            Frames.Add(frame);
+
+            frame.Y = 69;
+            Frames.Add(frame);
+
+            frame.Y = 81;
+            Frames.Add(frame);
+
+            frameDelay = 200;
+
+            // Initialize the random number generator and put the power source in your
+            // start position
+            random = new Random(GetHashCode());
+            PutinStartPosition();
+        }
+
+        /// <summary>
+        /// Initialize Position and Velocity
+        /// </summary>
+        public void PutinStartPosition()
+        {
+            position.X = random.Next(Game.Window.ClientBounds.Width - 
+                currentFrame.Width);
+            position.Y = -10;
+            Enabled = false;
+        }
+
+        public override void Update(GameTime gameTime)
+        {
+            // Check if the still visible
+            if (position.Y >= Game.Window.ClientBounds.Height)
+            {
+                PutinStartPosition();
+            }
+
+            // Move
+            position.Y += 1;
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// Check if the object intersects with the specified rectangle
+        /// </summary>
+        /// <param name="rect">test rectangle</param>
+        /// <returns>true, if has a collision</returns>
+        public bool CheckCollision(Rectangle rect)
+        {
+            Rectangle spriterect =
+                new Rectangle((int) position.X, (int) position.Y, 
+                currentFrame.Width, currentFrame.Height);
+            return spriterect.Intersects(rect);
+        }
+    }
+}

+ 14 - 0
RockRain/Core/RockRain.Core.csproj

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

+ 260 - 256
RockRain/Game1.cs → RockRain/Core/RockRainGame.cs

@@ -1,256 +1,260 @@
-
-using System;
-
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-
-using RockRainIphone;
-using RockRainIphone.Core;
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is the main type for your game
-    /// </summary>
-    public class Game1 : Game
-    {
-        private readonly GraphicsDeviceManager graphics;
-        private SpriteBatch spriteBatch;
-		private ExplosionManager explosions;
-
-        // Textures
-		protected Texture2D gamepadTexture,helpBackgroundTexture;
-        protected Texture2D startBackgroundTexture, startElementsTexture;
-        protected Texture2D actionElementsTexture, actionBackgroundTexture;
-
-        // Game Scenes
-        protected HelpScene helpScene;
-        protected StartScene startScene;
-        protected ActionScene actionScene;
-        protected GameScene activeScene;
-
-        // Audio Stuff
-        private AudioLibrary audio;
-
-        // Fonts
-        private SpriteFont smallFont, largeFont, scoreFont;
-
-		// Used for handle input
-        protected GamePadState oldGamePadState;
-
-        public Game1()
-        {
-            graphics = new GraphicsDeviceManager(this);
-            Content.RootDirectory = "Content";
-			
-            // Used for input handling
-            oldGamePadState = GamePad.GetState(PlayerIndex.One);
-        }
-
-        /// <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);
-
-            // TODO: use this.Content to load your game content here
-            Services.AddService(typeof(SpriteBatch), spriteBatch);
-
-			// Setup virtual gamepad
-			gamepadTexture = Content.Load<Texture2D>("gamepad.png");  
-			ButtonDefinition BButton = new ButtonDefinition();
-			BButton.Texture = gamepadTexture;
-			BButton.Position = new Vector2(100,420);
-			BButton.Type = Buttons.Back;
-			BButton.TextureRect = new Rectangle(72,77,36,36);
-			
-			ButtonDefinition AButton = new ButtonDefinition();
-			AButton.Texture = gamepadTexture;
-			AButton.Position = new Vector2(150,420);
-			AButton.Type = Buttons.A;
-			AButton.TextureRect = new Rectangle(73,114,36,36);
-			
-			GamePad.ButtonsDefinitions.Add(BButton);
-			GamePad.ButtonsDefinitions.Add(AButton);
-			
-			ThumbStickDefinition thumbStick = new ThumbStickDefinition();
-			thumbStick.Position = new Vector2(220,400);
-			thumbStick.Texture = gamepadTexture;
-			thumbStick.TextureRect = new Rectangle(2,2,68,68);	
-			GamePad.LeftThumbStickDefinition = thumbStick;
-			
-            // Create the audio bank
-            audio = new AudioLibrary(Content);
-            Services.AddService(typeof(AudioLibrary), audio);
-			
-            // Create the Start Scene
-            smallFont = Content.Load<SpriteFont>("menuSmall");
-			largeFont = Content.Load<SpriteFont>("menuLarge");
-			startElementsTexture = Content.Load<Texture2D>("startsceneelements.png");            
-            startBackgroundTexture = Content.Load<Texture2D>("startbackground");
-            startScene = new StartScene(this, smallFont, largeFont,startBackgroundTexture, startElementsTexture);
-            Components.Add(startScene);
-			
-            // Start the game in the start Scene :)
-            startScene.Show();
-            activeScene = startScene;
-        }
-
-		private void CreateActionScene()
-		{
-			explosions = new ExplosionManager(this);
-            actionElementsTexture = Content.Load<Texture2D>("rockrainenhanced.png");
-            actionBackgroundTexture = Content.Load<Texture2D>("spacebackground.jpg");
-            scoreFont = Content.Load<SpriteFont>("score");
-            actionScene = new ActionScene(this, actionElementsTexture,actionBackgroundTexture, scoreFont, explosions);
-            Components.Add(actionScene);
-		}
-		
-		private void CreateHelpScene()
-		{
-            helpBackgroundTexture = Content.Load<Texture2D>("helpscreen.png");
-            helpScene = new HelpScene(this, helpBackgroundTexture);
-            Components.Add(helpScene);
-		}
-		
-        /// <summary>
-        /// Open a new scene
-        /// </summary>
-        /// <param name="scene">Scene to be opened</param>
-        protected void ShowScene(GameScene scene)
-        {
-            activeScene.Hide();
-            activeScene = scene;
-            scene.Show();
-        }
-
-        /// <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)
-        {
-            // Handle Game Inputs
-            HandleScenesInput();
-
-            base.Update(gameTime);
-        }
-
-        /// <summary>
-        /// Handle input of all game scenes
-        /// </summary>
-        private void HandleScenesInput()
-        {
-            // Handle Start Scene Input
-            if (activeScene == startScene)
-            {
-                HandleStartSceneInput();
-            }
-            // Handle Help Scene input
-            else if (activeScene == helpScene)
-            {
-                if ((Mouse.GetState().X != 0) || (Mouse.GetState().Y != 0))
-                {
-                    ShowScene(startScene);
-                }
-            }
-            // Handle Action Scene Input
-            else if (activeScene == actionScene)
-            {
-                HandleActionInput();
-            }
-        }
-
-        /// <summary>
-        /// Check if the Enter Key ou 'A' button was pressed
-        /// </summary>
-        /// <returns>true, if enter key ou 'A' button was pressed</returns>
-        private void HandleActionInput()
-        {
-            // Get the Keyboard and GamePad state
-            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
-
-            bool backKey = (oldGamePadState.Buttons.Back == ButtonState.Pressed) &&
-                       (gamepadState.Buttons.Back == ButtonState.Released);
-
-            bool enterKey = (oldGamePadState.Buttons.A == ButtonState.Pressed) &&
-                        (gamepadState.Buttons.A == ButtonState.Released);
-
-            oldGamePadState = gamepadState;
-
-            if (enterKey)
-            {
-                if (actionScene.GameOver)
-                {
-                    ShowScene(startScene);
-                }
-                else
-                {
-                    audio.MenuBack.Play();
-                    actionScene.Paused = !actionScene.Paused;
-                }
-            }
-
-            if (backKey)
-            {
-                ShowScene(startScene);
-            }
-        }
-
-        /// <summary>
-        /// Handle buttons and keyboard in StartScene
-        /// </summary>
-        private void HandleStartSceneInput()
-        {
-            if (startScene.MenuSelected)
-            {
-				//Mouse.SetPosition(0,0);
-                audio.MenuSelect.Play();
-                switch (startScene.SelectedMenuIndex)
-                {
-                    case 0:
-						if (actionScene == null)
-							CreateActionScene();
-                        ShowScene(actionScene);
-                        break;
-                    case 1:
-						if (helpScene == null)
-							CreateHelpScene();
-                        ShowScene(helpScene);
-                        break;
-                    case 2:
-                        Exit();
-                        break;
-                }
-            }
-        }
-
-        /// <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)
-        {
-			graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
-			
-            // Begin..
-            spriteBatch.Begin();
-
-            // Draw all Game Components..
-            base.Draw(gameTime);
-
-			GamePad.Draw(gameTime,spriteBatch);
-            // End.
-            spriteBatch.End();
-						
-			// Draw particles
-			if (activeScene == actionScene)
-				explosions.Draw(gameTime);
-		}
-    }
-}
+
+using System;
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using RockRain.Core;
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is the main type for your game
+    /// </summary>
+    public class RockRainGame : Game
+    {
+        private readonly GraphicsDeviceManager graphics;
+        private SpriteBatch spriteBatch;
+		private ExplosionManager explosions;
+
+        // Textures
+		protected Texture2D gamepadTexture,helpBackgroundTexture;
+        protected Texture2D startBackgroundTexture, startElementsTexture;
+        protected Texture2D actionElementsTexture, actionBackgroundTexture;
+
+        // Game Scenes
+        protected HelpScene helpScene;
+        protected StartScene startScene;
+        protected ActionScene actionScene;
+        protected GameScene activeScene;
+
+        // Audio Stuff
+        private AudioLibrary audio;
+
+        // Fonts
+        private SpriteFont smallFont, largeFont, scoreFont;
+
+		// Used for handle input
+        protected GamePadState oldGamePadState;
+
+        public RockRainGame()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+			
+            // Used for input handling
+            oldGamePadState = GamePad.GetState(PlayerIndex.One);
+        }
+
+        /// <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);
+
+            // TODO: use this.Content to load your game content here
+            Services.AddService(typeof(SpriteBatch), spriteBatch);
+
+            // Setup virtual gamepad - not available in MonoGame 3.8.4
+            /*
+			gamepadTexture = Content.Load<Texture2D>("gamepad.png");  
+			ButtonDefinition BButton = new ButtonDefinition();
+			BButton.Texture = gamepadTexture;
+			BButton.Position = new Vector2(100,420);
+			BButton.Type = Buttons.Back;
+			BButton.TextureRect = new Rectangle(72,77,36,36);
+			
+			ButtonDefinition AButton = new ButtonDefinition();
+			AButton.Texture = gamepadTexture;
+			AButton.Position = new Vector2(150,420);
+			AButton.Type = Buttons.A;
+			AButton.TextureRect = new Rectangle(73,114,36,36);
+			
+			GamePad.ButtonsDefinitions.Add(BButton);
+			GamePad.ButtonsDefinitions.Add(AButton);
+			
+			ThumbStickDefinition thumbStick = new ThumbStickDefinition();
+			thumbStick.Position = new Vector2(220,400);
+			thumbStick.Texture = gamepadTexture;
+			thumbStick.TextureRect = new Rectangle(2,2,68,68);	
+			GamePad.LeftThumbStickDefinition = thumbStick;
+            */
+			
+            // Create the audio bank
+            audio = new AudioLibrary(Content);
+            Services.AddService(typeof(AudioLibrary), audio);
+			
+            // Create the Start Scene
+            // Note: XNB files are incompatible with MonoGame 3.8.4
+            // Commenting out font loading for compatibility
+            // smallFont = Content.Load<SpriteFont>("menuSmall");
+			// largeFont = Content.Load<SpriteFont>("menuLarge");
+			startElementsTexture = Content.Load<Texture2D>("startsceneelements");            
+            startBackgroundTexture = Content.Load<Texture2D>("startbackground");
+            startScene = new StartScene(this, null, null, startBackgroundTexture, startElementsTexture);
+            Components.Add(startScene);
+			
+            // Start the game in the start Scene :)
+            startScene.Show();
+            activeScene = startScene;
+        }
+
+		private void CreateActionScene()
+		{
+			explosions = new ExplosionManager(this);
+            actionElementsTexture = Content.Load<Texture2D>("rockrainenhanced.png");
+            actionBackgroundTexture = Content.Load<Texture2D>("spacebackground.jpg");
+            // Note: XNB files are incompatible with MonoGame 3.8.4
+            // scoreFont = Content.Load<SpriteFont>("score");
+            actionScene = new ActionScene(this, actionElementsTexture,actionBackgroundTexture, null, explosions);
+            Components.Add(actionScene);
+		}
+		
+		private void CreateHelpScene()
+		{
+            helpBackgroundTexture = Content.Load<Texture2D>("helpscreen.png");
+            helpScene = new HelpScene(this, helpBackgroundTexture);
+            Components.Add(helpScene);
+		}
+		
+        /// <summary>
+        /// Open a new scene
+        /// </summary>
+        /// <param name="scene">Scene to be opened</param>
+        protected void ShowScene(GameScene scene)
+        {
+            activeScene.Hide();
+            activeScene = scene;
+            scene.Show();
+        }
+
+        /// <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)
+        {
+            // Handle Game Inputs
+            HandleScenesInput();
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// Handle input of all game scenes
+        /// </summary>
+        private void HandleScenesInput()
+        {
+            // Handle Start Scene Input
+            if (activeScene == startScene)
+            {
+                HandleStartSceneInput();
+            }
+            // Handle Help Scene input
+            else if (activeScene == helpScene)
+            {
+                if ((Mouse.GetState().X != 0) || (Mouse.GetState().Y != 0))
+                {
+                    ShowScene(startScene);
+                }
+            }
+            // Handle Action Scene Input
+            else if (activeScene == actionScene)
+            {
+                HandleActionInput();
+            }
+        }
+
+        /// <summary>
+        /// Check if the Enter Key ou 'A' button was pressed
+        /// </summary>
+        /// <returns>true, if enter key ou 'A' button was pressed</returns>
+        private void HandleActionInput()
+        {
+            // Get the Keyboard and GamePad state
+            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
+
+            bool backKey = (oldGamePadState.Buttons.Back == ButtonState.Pressed) &&
+                       (gamepadState.Buttons.Back == ButtonState.Released);
+
+            bool enterKey = (oldGamePadState.Buttons.A == ButtonState.Pressed) &&
+                        (gamepadState.Buttons.A == ButtonState.Released);
+
+            oldGamePadState = gamepadState;
+
+            if (enterKey)
+            {
+                if (actionScene.GameOver)
+                {
+                    ShowScene(startScene);
+                }
+                else
+                {
+                    audio.MenuBack.Play();
+                    actionScene.Paused = !actionScene.Paused;
+                }
+            }
+
+            if (backKey)
+            {
+                ShowScene(startScene);
+            }
+        }
+
+        /// <summary>
+        /// Handle buttons and keyboard in StartScene
+        /// </summary>
+        private void HandleStartSceneInput()
+        {
+            if (startScene.MenuSelected)
+            {
+				//Mouse.SetPosition(0,0);
+                audio.MenuSelect.Play();
+                switch (startScene.SelectedMenuIndex)
+                {
+                    case 0:
+						if (actionScene == null)
+							CreateActionScene();
+                        ShowScene(actionScene);
+                        break;
+                    case 1:
+						if (helpScene == null)
+							CreateHelpScene();
+                        ShowScene(helpScene);
+                        break;
+                    case 2:
+                        Exit();
+                        break;
+                }
+            }
+        }
+
+        /// <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)
+        {
+			graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
+			
+            // Begin..
+            spriteBatch.Begin();
+
+            // Draw all Game Components..
+            base.Draw(gameTime);
+
+            // GamePad.Draw is not available in MonoGame 3.8.4
+			// GamePad.Draw(gameTime,spriteBatch);
+            // End.
+            spriteBatch.End();
+						
+			// Draw particles
+			if (activeScene == actionScene)
+				explosions.Draw(gameTime);
+		}
+    }
+}

+ 92 - 94
RockRain/Score.cs → RockRain/Core/Score.cs

@@ -1,94 +1,92 @@
-#region Using Statements
-
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-
-#endregion
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is a game component that implements the Game Score.
-    /// </summary>
-    public class Score : DrawableGameComponent
-    {
-        // Spritebatch
-        protected SpriteBatch spriteBatch = null;
-
-        // Score Position
-        protected Vector2 position = new Vector2();
-
-        // Values
-        protected int value;
-        protected int power;
-
-        protected readonly SpriteFont font;
-        protected readonly Color fontColor;
-
-        public Score(Game game, SpriteFont font, Color fontColor)
-            : base(game)
-        {
-            this.font = font;
-            this.fontColor = fontColor;
-            // Get the current spritebatch
-            spriteBatch = (SpriteBatch) 
-                            Game.Services.GetService(typeof (SpriteBatch));
-        }
-
-        /// <summary>
-        /// Points value
-        /// </summary>
-        public int Value
-        {
-            get { return value; }
-            set { this.value = value; }
-        }
-
-        /// <summary>
-        /// Power Value
-        /// </summary>
-        public int Power
-        {
-            get { return power; }
-            set { power = value; }
-        }
-
-        /// <summary>
-        /// Position of component in screen
-        /// </summary>
-        public Vector2 Position
-        {
-            get { return position; }
-            set { position = value; }
-        }
-
-        /// <summary>
-        /// Allows the game component to draw itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        public override void Draw(GameTime gameTime)
-        {
-            string TextToDraw = string.Format("Score: {0}", value);
-
-            // Draw the text shadow
-            spriteBatch.DrawString(font, TextToDraw, new Vector2(position.X + 1,
-                                    position.Y + 1), Color.Black);
-            // Draw the text item
-            spriteBatch.DrawString(font, TextToDraw, 
-                                    new Vector2(position.X, position.Y), 
-                                    fontColor);
-
-            TextToDraw = string.Format("Power: {0}", power);
-            // Draw the text shadow
-            spriteBatch.DrawString(font, TextToDraw, 
-                new Vector2(position.X + 151, position.Y + 1), 
-                Color.Black);
-            // Draw the text item
-            spriteBatch.DrawString(font, TextToDraw, 
-                new Vector2(position.X+150, position.Y), 
-                fontColor);
-			 
-            base.Draw(gameTime);
-        }
-    }
-}
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is a game component that implements the Game Score.
+    /// </summary>
+    public class Score : DrawableGameComponent
+    {
+        // Spritebatch
+        protected SpriteBatch spriteBatch = null;
+
+        // Score Position
+        protected Vector2 position = new Vector2();
+
+        // Values
+        protected int value;
+        protected int power;
+
+        protected readonly SpriteFont font;
+        protected readonly Color fontColor;
+
+        public Score(Game game, SpriteFont font, Color fontColor)
+            : base(game)
+        {
+            this.font = font;
+            this.fontColor = fontColor;
+            // Get the current spritebatch
+            spriteBatch = (SpriteBatch) 
+                            Game.Services.GetService(typeof (SpriteBatch));
+        }
+
+        /// <summary>
+        /// Points value
+        /// </summary>
+        public int Value
+        {
+            get { return value; }
+            set { this.value = value; }
+        }
+
+        /// <summary>
+        /// Power Value
+        /// </summary>
+        public int Power
+        {
+            get { return power; }
+            set { power = value; }
+        }
+
+        /// <summary>
+        /// Position of component in screen
+        /// </summary>
+        public Vector2 Position
+        {
+            get { return position; }
+            set { position = value; }
+        }
+
+        /// <summary>
+        /// Allows the game component to draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            string TextToDraw = string.Format("Score: {0}", value);
+
+            // Draw the text shadow
+            spriteBatch.DrawString(font, TextToDraw, new Vector2(position.X + 1,
+                                    position.Y + 1), Color.Black);
+            // Draw the text item
+            spriteBatch.DrawString(font, TextToDraw, 
+                                    new Vector2(position.X, position.Y), 
+                                    fontColor);
+
+            TextToDraw = string.Format("Power: {0}", power);
+            // Draw the text shadow
+            spriteBatch.DrawString(font, TextToDraw, 
+                new Vector2(position.X + 151, position.Y + 1), 
+                Color.Black);
+            // Draw the text item
+            spriteBatch.DrawString(font, TextToDraw, 
+                new Vector2(position.X+150, position.Y), 
+                fontColor);
+			 
+            base.Draw(gameTime);
+        }
+    }
+}

+ 2 - 4
RockRain/Core/Sprite.cs

@@ -1,13 +1,11 @@
-#region Using Statements
 
 using System;
 using System.Collections.Generic;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 
-#endregion
 
-namespace RockRainIphone.Core
+namespace RockRain.Core
 {
     /// <summary>
     /// This is a game component that implements a Animated Sprite.
@@ -93,4 +91,4 @@ namespace RockRainIphone.Core
             base.Draw(gameTime);
         }
     }
-}
+}

+ 176 - 177
RockRain/StartScene.cs → RockRain/Core/StartScene.cs

@@ -1,177 +1,176 @@
-#region Using Statements
-
-using System;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Graphics;
-using RockRainIphone.Core;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Xna.Framework.Input;
-
-#endregion
-
-namespace RockRainIphone
-{
-    /// <summary>
-    /// This is a game component that implements the Game Start Scene.
-    /// </summary>
-    public class StartScene : GameScene
-    {
-        // Misc
-        protected TextMenuComponent menu;
-        protected readonly Texture2D elements;
-        // Audio Bank
-        protected AudioLibrary audio;
-        // Spritebatch
-        protected SpriteBatch spriteBatch = null;
-        // Gui Stuff
-        protected Rectangle rockRect = new Rectangle(3, 2, 197, 49);
-        protected Vector2 rockPosition;
-        protected Rectangle rainRect = new Rectangle(47, 63, 189, 48);
-        protected Vector2 rainPosition;
-        protected Rectangle enhancedRect = new Rectangle(7, 110, 122, 46);
-        protected Vector2 enhancedPosition;
-        protected bool showEnhanced;
-        protected TimeSpan elapsedTime = TimeSpan.Zero;
-
-        /// <summary>
-        /// Default Constructor
-        /// </summary>
-        /// <param name="game">Main game object</param>
-        /// <param name="smallFont">Font for the menu items</param>
-        /// <param name="largeFont">Font for the menu selcted item</param>
-        /// <param name="background">Texture for background image</param>
-        /// <param name="elements">Texture with the foreground elements</param>
-        public StartScene(Game game, SpriteFont smallFont, SpriteFont largeFont,
-                            Texture2D background,Texture2D elements)
-            : base(game)
-        {
-            this.elements = elements;
-            Components.Add(new ImageComponent(game, background, 
-                                            ImageComponent.DrawMode.Stretch));
-
-            // Create the Menu
-            string[] items = {"Play!", "Help", "Quit"};
-            menu = new TextMenuComponent(game, smallFont, largeFont);
-            menu.SetMenuItems(items);
-            Components.Add(menu);
-
-            // Get the current spritebatch
-            spriteBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch));
-            // Get the current audiocomponent and play the background music
-            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));
-        }
-
-        /// <summary>
-        /// Show the start scene
-        /// </summary>
-        public override void Show()
-        {
-			GamePad.Visible = false;
-			
-            audio.NewMeteor.Play();            
-
-            rockPosition.X = -1*rockRect.Width;
-            rockPosition.Y = 20;
-            rainPosition.X = Game.Window.ClientBounds.Width;
-            rainPosition.Y = 70;
-            // Put the menu centered in screen
-            menu.Position = new Vector2((Game.Window.ClientBounds.Width - 
-                                          menu.Width)/2, 200);
-
-            // These elements will be visible when the 'Rock Rain' title
-            // is done.
-            menu.Visible = false;
-            menu.Enabled = false;
-			menu.Selected = false;
-            showEnhanced = false;
-
-            base.Show();
-        }
-
-        /// <summary>
-        /// Hide the start scene
-        /// </summary>
-        public override void Hide()
-        {            
-            MediaPlayer.Stop();
-            base.Hide();
-        }
-
-        /// <summary>
-        /// Gets the selected menu option
-        /// </summary>
-        public int SelectedMenuIndex
-        {
-            get { return menu.SelectedIndex; }
-        }
-		
-		public bool MenuSelected
-        {
-            get 
-			{
-				return menu.Selected; 
-			}
-        }
-
-        /// <summary>
-        /// Allows the game component to update itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        public override void Update(GameTime gameTime)
-        {
-            if (!menu.Visible)
-            {
-                if (rainPosition.X >= (Game.Window.ClientBounds.Width - rainRect.Width)/2)
-                {
-                    rainPosition.X -= 5;
-                }
-
-                if (rockPosition.X <= (Game.Window.ClientBounds.Width - rockRect.Width)/2)
-                {
-                    rockPosition.X += 5;
-                }
-                else
-                {
-                    menu.Visible = true;
-                    menu.Enabled = true;
-
-                    MediaPlayer.Play(audio.StartMusic);
-
-                    enhancedPosition =
-                        new Vector2((rainPosition.X + rainRect.Width - 
-                        enhancedRect.Width/2) - 40, rainPosition.Y+20);
-                    showEnhanced = true;
-                }
-            }
-            else
-            {
-                elapsedTime += gameTime.ElapsedGameTime;
-
-                if (elapsedTime > TimeSpan.FromSeconds(1))
-                {
-                    elapsedTime -= TimeSpan.FromSeconds(1);
-                    showEnhanced = !showEnhanced;
-                }
-            }
-
-            base.Update(gameTime);
-        }
-
-        /// <summary>
-        /// Allows the game component to draw itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        public override void Draw(GameTime gameTime)
-        {
-            base.Draw(gameTime);
-
-            spriteBatch.Draw(elements, rockPosition, rockRect, Color.White);
-            spriteBatch.Draw(elements, rainPosition, rainRect, Color.White);
-            if (showEnhanced)
-            {
-                spriteBatch.Draw(elements, enhancedPosition, enhancedRect,Color.White);
-            }
-        }
-    }
-}
+
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Graphics;
+using RockRain.Core;
+using Microsoft.Xna.Framework.Media;
+using Microsoft.Xna.Framework.Input;
+
+
+namespace RockRain
+{
+    /// <summary>
+    /// This is a game component that implements the Game Start Scene.
+    /// </summary>
+    public class StartScene : GameScene
+    {
+        // Misc
+        protected TextMenuComponent menu;
+        protected readonly Texture2D elements;
+        // Audio Bank
+        protected AudioLibrary audio;
+        // Spritebatch
+        protected SpriteBatch spriteBatch = null;
+        // Gui Stuff
+        protected Rectangle rockRect = new Rectangle(3, 2, 197, 49);
+        protected Vector2 rockPosition;
+        protected Rectangle rainRect = new Rectangle(47, 63, 189, 48);
+        protected Vector2 rainPosition;
+        protected Rectangle enhancedRect = new Rectangle(7, 110, 122, 46);
+        protected Vector2 enhancedPosition;
+        protected bool showEnhanced;
+        protected TimeSpan elapsedTime = TimeSpan.Zero;
+
+        /// <summary>
+        /// Default Constructor
+        /// </summary>
+        /// <param name="game">Main game object</param>
+        /// <param name="smallFont">Font for the menu items</param>
+        /// <param name="largeFont">Font for the menu selcted item</param>
+        /// <param name="background">Texture for background image</param>
+        /// <param name="elements">Texture with the foreground elements</param>
+        public StartScene(Game game, SpriteFont smallFont, SpriteFont largeFont,
+                            Texture2D background,Texture2D elements)
+            : base(game)
+        {
+            this.elements = elements;
+            Components.Add(new ImageComponent(game, background, 
+                                            ImageComponent.DrawMode.Stretch));
+
+            // Create the Menu
+            string[] items = {"Play!", "Help", "Quit"};
+            menu = new TextMenuComponent(game, smallFont, largeFont);
+            menu.SetMenuItems(items);
+            Components.Add(menu);
+
+            // Get the current spritebatch
+            spriteBatch = (SpriteBatch) Game.Services.GetService(typeof (SpriteBatch));
+            // Get the current audiocomponent and play the background music
+            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));
+        }
+
+        /// <summary>
+        /// Show the start scene
+        /// </summary>
+        public override void Show()
+        {
+            // GamePad.Visible is not available in MonoGame 3.8.4
+            // GamePad.Visible = false;
+            
+            audio.NewMeteor.Play();            
+
+            rockPosition.X = -1*rockRect.Width;
+            rockPosition.Y = 20;
+            rainPosition.X = Game.Window.ClientBounds.Width;
+            rainPosition.Y = 70;
+            // Put the menu centered in screen
+            menu.Position = new Vector2((Game.Window.ClientBounds.Width - 
+                                          menu.Width)/2, 200);
+
+            // These elements will be visible when the 'Rock Rain' title
+            // is done.
+            menu.Visible = false;
+            menu.Enabled = false;
+			menu.Selected = false;
+            showEnhanced = false;
+
+            base.Show();
+        }
+
+        /// <summary>
+        /// Hide the start scene
+        /// </summary>
+        public override void Hide()
+        {            
+            MediaPlayer.Stop();
+            base.Hide();
+        }
+
+        /// <summary>
+        /// Gets the selected menu option
+        /// </summary>
+        public int SelectedMenuIndex
+        {
+            get { return menu.SelectedIndex; }
+        }
+		
+		public bool MenuSelected
+        {
+            get 
+			{
+				return menu.Selected; 
+			}
+        }
+
+        /// <summary>
+        /// Allows the game component to update itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        public override void Update(GameTime gameTime)
+        {
+            if (!menu.Visible)
+            {
+                if (rainPosition.X >= (Game.Window.ClientBounds.Width - rainRect.Width)/2)
+                {
+                    rainPosition.X -= 5;
+                }
+
+                if (rockPosition.X <= (Game.Window.ClientBounds.Width - rockRect.Width)/2)
+                {
+                    rockPosition.X += 5;
+                }
+                else
+                {
+                    menu.Visible = true;
+                    menu.Enabled = true;
+
+                    MediaPlayer.Play(audio.StartMusic);
+
+                    enhancedPosition =
+                        new Vector2((rainPosition.X + rainRect.Width - 
+                        enhancedRect.Width/2) - 40, rainPosition.Y+20);
+                    showEnhanced = true;
+                }
+            }
+            else
+            {
+                elapsedTime += gameTime.ElapsedGameTime;
+
+                if (elapsedTime > TimeSpan.FromSeconds(1))
+                {
+                    elapsedTime -= TimeSpan.FromSeconds(1);
+                    showEnhanced = !showEnhanced;
+                }
+            }
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// Allows the game component to draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            base.Draw(gameTime);
+
+            spriteBatch.Draw(elements, rockPosition, rockRect, Color.White);
+            spriteBatch.Draw(elements, rainPosition, rainRect, Color.White);
+            if (showEnhanced)
+            {
+                spriteBatch.Draw(elements, enhancedPosition, enhancedRect,Color.White);
+            }
+        }
+    }
+}

+ 2 - 4
RockRain/Core/TextMenuComponent.cs

@@ -1,4 +1,3 @@
-#region Using Statements
 
 using System.Collections.Specialized;
 using Microsoft.Xna.Framework;
@@ -7,9 +6,8 @@ using Microsoft.Xna.Framework.Input;
 using System.Collections.Generic;
 using System;
 
-#endregion
 
-namespace RockRainIphone.Core
+namespace RockRain.Core
 {
     /// <summary>
     /// This is a game component that implements a menu with text elements.
@@ -201,4 +199,4 @@ namespace RockRainIphone.Core
             base.Draw(gameTime);
         }
     }
-}
+}

+ 32 - 0
RockRain/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,32 @@
+<?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.monogame.rockrain">
+  
+  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
+  
+  <uses-permission android:name="android.permission.VIBRATE" />
+  <uses-permission android:name="android.permission.WAKE_LOCK" />
+  
+  <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+  
+  <application android:allowBackup="true" 
+               android:label="RockRain"
+               android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+    
+    <activity android:name="crc6414252091ad8633ca.MainActivity"
+              android:exported="true"
+              android:label="RockRain"
+              android:launchMode="singleInstance"
+              android:screenOrientation="fullUser"
+              android:configChanges="orientation|keyboardHidden|keyboard">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+    
+  </application>
+  
+</manifest>

+ 29 - 0
RockRain/Platforms/Android/MainActivity.cs

@@ -0,0 +1,29 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Android.Views;
+using Microsoft.Xna.Framework;
+
+namespace RockRain.Android
+{
+    [Activity(
+        Label = "RockRain",
+        MainLauncher = true,
+        AlwaysRetainTaskState = true,
+        LaunchMode = LaunchMode.SingleInstance,
+        ScreenOrientation = ScreenOrientation.FullUser,
+        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize | ConfigChanges.ScreenLayout)]
+    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
RockRain/Platforms/Android/Resources/values/colors.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="launcher_background">#FFFFFF</color>
+</resources>

+ 42 - 0
RockRain/Platforms/Android/RockRain.Android.csproj

@@ -0,0 +1,42 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <UseAndroidX>true</UseAndroidX>
+    <AndroidApplication>true</AndroidApplication>
+    <AndroidUseAapt2>true</AndroidUseAapt2>
+    <AndroidManifest>Platforms\Android\AndroidManifest.xml</AndroidManifest>
+    <AssemblyName>RockRain.Android</AssemblyName>
+    <RootNamespace>RockRain</RootNamespace>
+    <ApplicationId>com.monogame.rockrain</ApplicationId>
+    <ApplicationDisplayName>RockRain</ApplicationDisplayName>
+    <ApplicationVersion>1</ApplicationVersion>
+    <ApplicationVersionName>1.0</ApplicationVersionName>
+    <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
+    <TargetSdkVersion>34</TargetSdkVersion>
+    <AssemblyTitle>RockRain</AssemblyTitle>
+    <Product>RockRain</Product>
+    <AssemblyDescription>A MonoGame sample game - RockRain</AssemblyDescription>
+    <AssemblyCompany>MonoGame Team</AssemblyCompany>
+    <AssemblyCopyright>Copyright © MonoGame Team 2024</AssemblyCopyright>
+    <AssemblyVersion>1.0.0.0</AssemblyVersion>
+    <FileVersion>1.0.0.0</FileVersion>
+    <MonoGamePlatform>Android</MonoGamePlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\RockRain.Core.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+</Project>

+ 14 - 0
RockRain/Platforms/Desktop/Program.cs

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

+ 32 - 0
RockRain/Platforms/Desktop/RockRain.DesktopGL.csproj

@@ -0,0 +1,32 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <AssemblyName>RockRain</AssemblyName>
+    <RootNamespace>RockRain</RootNamespace>
+    <AssemblyTitle>RockRain</AssemblyTitle>
+    <Product>RockRain</Product>
+    <AssemblyDescription>A MonoGame sample game - RockRain</AssemblyDescription>
+    <AssemblyCompany>MonoGame Team</AssemblyCompany>
+    <AssemblyCopyright>Copyright © MonoGame Team 2024</AssemblyCopyright>
+    <AssemblyVersion>1.0.0.0</AssemblyVersion>
+    <FileVersion>1.0.0.0</FileVersion>
+    <MonoGamePlatform>DesktopGL</MonoGamePlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\RockRain.Core.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+</Project>

+ 14 - 0
RockRain/Platforms/Windows/Program.cs

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

+ 35 - 0
RockRain/Platforms/Windows/RockRain.Windows.csproj

@@ -0,0 +1,35 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <UseWindowsForms>true</UseWindowsForms>
+    <AssemblyName>RockRain</AssemblyName>
+    <RootNamespace>RockRain</RootNamespace>
+    <AssemblyTitle>RockRain</AssemblyTitle>
+    <Product>RockRain</Product>
+    <AssemblyDescription>A MonoGame sample game - RockRain</AssemblyDescription>
+    <AssemblyCompany>MonoGame Team</AssemblyCompany>
+    <AssemblyCopyright>Copyright © MonoGame Team 2024</AssemblyCopyright>
+    <AssemblyVersion>1.0.0.0</AssemblyVersion>
+    <FileVersion>1.0.0.0</FileVersion>
+    <MonoGamePlatform>Windows</MonoGamePlatform>
+  </PropertyGroup>
+  
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\RockRain.Core.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb" />
+  </ItemGroup>
+
+</Project>

+ 48 - 0
RockRain/Platforms/iOS/Info.plist

@@ -0,0 +1,48 @@
+<?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>CFBundleDisplayName</key>
+	<string>RockRain</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.monogame.rockrain</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>MinimumOSVersion</key>
+	<string>11.0</string>
+	<key>UIDeviceFamily</key>
+	<array>
+		<integer>1</integer>
+		<integer>2</integer>
+	</array>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UIStatusBarHidden</key>
+	<true/>
+	<key>CFBundleIconFiles</key>
+	<array>
+		<string>GameThumbnail</string>
+	</array>
+</dict>
+</plist>

+ 38 - 0
RockRain/Platforms/iOS/RockRain.iOS.csproj

@@ -0,0 +1,38 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <UseInterpreter>true</UseInterpreter>
+    <AssemblyName>RockRain</AssemblyName>
+    <RootNamespace>RockRain</RootNamespace>
+    <CFBundleDisplayName>RockRain</CFBundleDisplayName>
+    <CFBundleIdentifier>com.monogame.rockrain</CFBundleIdentifier>
+    <CFBundleVersion>1.0</CFBundleVersion>
+    <CFBundleShortVersionString>1.0</CFBundleShortVersionString>
+    <SupportedOSPlatformVersion>11.0</SupportedOSPlatformVersion>
+    <AssemblyTitle>RockRain</AssemblyTitle>
+    <Product>RockRain</Product>
+    <AssemblyDescription>A MonoGame sample game - RockRain</AssemblyDescription>
+    <AssemblyCompany>MonoGame Team</AssemblyCompany>
+    <AssemblyCopyright>Copyright © MonoGame Team 2024</AssemblyCopyright>
+    <AssemblyVersion>1.0.0.0</AssemblyVersion>
+    <FileVersion>1.0.0.0</FileVersion>
+    <MonoGamePlatform>iOS</MonoGamePlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\RockRain.Core.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+
+</Project>

+ 136 - 0
RockRain/README.md

@@ -0,0 +1,136 @@
+# RockRain - MonoGame Sample
+
+RockRain is a classic arcade-style space shooter game built with MonoGame 3.8.4. The player controls a spaceship and must avoid meteors while collecting power-ups to survive as long as possible.
+
+## Features
+
+- Classic arcade gameplay
+- Particle explosion effects
+- Power-ups and scoring system
+- Background music and sound effects
+- Multiple platform support
+
+## Supported Platforms
+
+
+This project has been modernized to use .NET 8.0 SDK-style projects and supports the following platforms:
+
+- **Windows (DirectX)** - `Platforms/Windows/RockRain.Windows.csproj`
+- **DesktopGL (Cross-platform)** - `Platforms/Desktop/RockRain.DesktopGL.csproj`
+- **Android** - `Platforms/Android/RockRain.Android.csproj`
+- **iOS** - `Platforms/iOS/RockRain.iOS.csproj`
+
+## Prerequisites
+
+- [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) or later
+- For Android development: Android SDK and workloads
+- For iOS development: Xcode and iOS workloads (macOS only)
+
+## Building and Running
+
+### Windows (DirectX)
+
+```bash
+# Build
+dotnet build RockRain.Windows.csproj
+
+# Run
+dotnet run --project RockRain.Windows.csproj
+```
+
+### DesktopGL (Cross-platform)
+
+```bash
+# Build  
+dotnet build RockRain.DesktopGL.csproj
+
+# Run
+dotnet run --project RockRain.DesktopGL.csproj
+```
+
+### Android
+
+```bash
+# Build
+dotnet build RockRain.Android.csproj
+
+# Deploy to device/emulator
+dotnet build RockRain.Android.csproj -t:Run
+```
+
+### iOS
+
+```bash
+# Build
+dotnet build RockRain.iOS.csproj
+
+# Deploy to device/simulator (requires macOS and Xcode)
+dotnet build RockRain.iOS.csproj -t:Run
+```
+
+## Visual Studio Code
+
+This project includes VS Code configuration for building and debugging:
+
+### Tasks Available:
+- `build-windows` - Build Windows version
+- `build-desktopgl` - Build DesktopGL version  
+- `build-android` - Build Android version
+- `build-ios` - Build iOS version
+- `run-windows` - Run Windows version
+- `run-desktopgl` - Run DesktopGL version
+- `clean` - Clean all projects
+- `restore` - Restore NuGet packages
+
+### Debugging:
+- Use `F5` to start debugging
+- Choose "Launch Windows (DirectX)" or "Launch DesktopGL" configuration
+
+## Visual Studio
+
+Open `RockRain.sln` in Visual Studio to build and run all platform projects.
+
+## Game Controls
+
+- **Arrow Keys / WASD** - Move spaceship
+- **Spacebar** - Fire (if power-up collected)
+- **Escape** - Return to menu
+
+
+## Project Structure
+
+- `/Core/` - Shared game logic and components (Game1, GameScene, Sprite, ParticleSystem, etc.)
+- `/Core/RockRain.Core.csproj` - Shared code project referenced by all platforms
+- `/Content/` - Game assets (textures, sounds, fonts)
+- `/Platforms/Windows/` - Windows-specific entry point and project files
+- `/Platforms/Desktop/` - DesktopGL-specific entry point and project files
+- `/Platforms/Android/` - Android-specific entry point, manifest, and project files
+- `/Platforms/iOS/` - iOS-specific entry point, plist, and project files
+- Each platform directory contains its own `Program.cs` (or `MainActivity.cs` for Android) and `RockRain.[Platform].csproj`
+
+## Modernization Notes
+
+This project has been modernized from an older MonoGame version to 3.8.4:
+
+- **Mobile-specific APIs removed**: `GamePad.Visible`, `ButtonDefinition`, `ThumbStickDefinition`, and `Accelerometer` APIs that were specific to older mobile platforms have been commented out
+- **Content Pipeline**: Uses pre-compiled .xnb files directly instead of requiring a Content.mgcb file
+- **Platform-specific entry points**: Each platform now has its own entry point in `/Platforms/[Platform]/` (e.g., `Program.cs` for Windows/DesktopGL/iOS, `MainActivity.cs` for Android)
+
+## Known Limitations
+
+- **Font Support**: The original XNB font files (menuSmall.xnb, menuLarge.xnb, score.xnb) are incompatible with MonoGame 3.8.4 and have been disabled. Text rendering is currently not functional.
+- **Touch/virtual gamepad support**: Has been disabled for compatibility with MonoGame 3.8.4
+- **Accelerometer input**: Not available in desktop versions
+- **Content Pipeline Warning**: The "No Content References Found" warning is expected since we're using pre-compiled XNB files instead of a Content.mgcb file
+
+## Content Compatibility
+
+To fully restore text rendering functionality, the XNB font files would need to be rebuilt with MonoGame 3.8.4's content pipeline, or the original font source files (.spritefont) would need to be compiled through a proper Content.mgcb file.
+
+## MonoGame Content
+
+This project uses pre-compiled .xnb content files located in the `/Content/` directory. No Content.mgcb file is needed as the content has already been processed.
+
+## License
+
+This is a MonoGame sample project provided for educational purposes.

+ 0 - 168
RockRain/RockRain.iOS.csproj

@@ -1,168 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{6AD0E621-8D0C-42B1-A42C-B36F8537B234}</ProjectGuid>
-    <ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <OutputType>Exe</OutputType>
-    <AssemblyName>RockRainIphone</AssemblyName>
-    <RootNamespace>RockRainIphone</RootNamespace>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
-    <DefineConstants>DEBUG</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
-    <MtouchLink>None</MtouchLink>
-    <MtouchDebug>True</MtouchDebug>
-    <MtouchI18n />
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
-    <DebugType>none</DebugType>
-    <Optimize>True</Optimize>
-    <OutputPath>bin\iPhoneSimulator\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <MtouchI18n />
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\iPhone\Debug</OutputPath>
-    <DefineConstants>DEBUG</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <MtouchDebug>True</MtouchDebug>
-    <MtouchI18n />
-    <MtouchSdkVersion>4.0</MtouchSdkVersion>
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
-    <DebugType>none</DebugType>
-    <Optimize>True</Optimize>
-    <OutputPath>bin\iPhone\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <MtouchI18n />
-    <CodesignKey>iPhone Developer</CodesignKey>
-    <MtouchSdkVersion>4.0</MtouchSdkVersion>
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <WarningLevel>4</WarningLevel>
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <WarningLevel>4</WarningLevel>
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="monotouch" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="main.cs" />
-    <Compile Include="Core\GameScene.cs" />
-    <Compile Include="Core\ImageComponent.cs" />
-    <Compile Include="Core\Sprite.cs" />
-    <Compile Include="Core\TextMenuComponent.cs" />
-    <Compile Include="AudioLibrary.cs" />
-    <Compile Include="helpScene.cs" />
-    <Compile Include="MeteorsManager.cs" />
-    <Compile Include="Score.cs" />
-    <Compile Include="Meteor.cs" />
-    <Compile Include="Player.cs" />
-    <Compile Include="PowerSource.cs" />
-    <Compile Include="ActionScene.cs" />
-    <Compile Include="StartScene.cs" />
-    <Compile Include="Game1.cs" />
-    <Compile Include="Core\ExplosionParticleSystem.cs" />
-    <Compile Include="Core\Particle.cs" />
-    <Compile Include="Core\ParticleSystem.cs" />
-    <Compile Include="ExplosionManager.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="GameThumbnail.png" />
-    <None Include="Info.iOS.plist">
-      <Link>Info.plist</Link>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Content\gamepad.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\backmusic.mp3">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\explosion.wav">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\menu_back.wav">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\menu_select3.wav">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\newmeteor.wav">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\powerget.wav">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\powershow.wav">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\rockrainenhanced.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\spacebackground.jpg">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\startmusic.mp3">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\startsceneelements.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\startbackground.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\helpscreen.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\menuLarge.xnb">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\menuSmall.xnb">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\score.xnb">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\explosion.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Default.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-</Project>

+ 52 - 0
RockRain/RockRain.sln

@@ -0,0 +1,52 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RockRain.Core", "Core\RockRain.Core.csproj", "{43B03CF6-986A-7F90-5A39-2405E5554100}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RockRain.Windows", "Platforms\Windows\RockRain.Windows.csproj", "{965C3802-F95B-BBDD-B306-7A5100B4296D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RockRain.iOS", "Platforms\iOS\RockRain.iOS.csproj", "{DF780DF6-4D3F-E314-D7C1-F89E7F429BC9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RockRain.DesktopGL", "Platforms\Desktop\RockRain.DesktopGL.csproj", "{50A57D36-890E-5121-ACF3-F2BAB2992B48}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RockRain.Android", "Platforms\Android\RockRain.Android.csproj", "{04935748-DCCF-DA8E-C7BE-1307F0935535}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{43B03CF6-986A-7F90-5A39-2405E5554100}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{43B03CF6-986A-7F90-5A39-2405E5554100}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{43B03CF6-986A-7F90-5A39-2405E5554100}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{43B03CF6-986A-7F90-5A39-2405E5554100}.Release|Any CPU.Build.0 = Release|Any CPU
+		{965C3802-F95B-BBDD-B306-7A5100B4296D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{965C3802-F95B-BBDD-B306-7A5100B4296D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{965C3802-F95B-BBDD-B306-7A5100B4296D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{965C3802-F95B-BBDD-B306-7A5100B4296D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DF780DF6-4D3F-E314-D7C1-F89E7F429BC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DF780DF6-4D3F-E314-D7C1-F89E7F429BC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DF780DF6-4D3F-E314-D7C1-F89E7F429BC9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{DF780DF6-4D3F-E314-D7C1-F89E7F429BC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DF780DF6-4D3F-E314-D7C1-F89E7F429BC9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DF780DF6-4D3F-E314-D7C1-F89E7F429BC9}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{50A57D36-890E-5121-ACF3-F2BAB2992B48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{50A57D36-890E-5121-ACF3-F2BAB2992B48}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{50A57D36-890E-5121-ACF3-F2BAB2992B48}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{50A57D36-890E-5121-ACF3-F2BAB2992B48}.Release|Any CPU.Build.0 = Release|Any CPU
+		{04935748-DCCF-DA8E-C7BE-1307F0935535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{04935748-DCCF-DA8E-C7BE-1307F0935535}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{04935748-DCCF-DA8E-C7BE-1307F0935535}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{04935748-DCCF-DA8E-C7BE-1307F0935535}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{04935748-DCCF-DA8E-C7BE-1307F0935535}.Release|Any CPU.Build.0 = Release|Any CPU
+		{04935748-DCCF-DA8E-C7BE-1307F0935535}.Release|Any CPU.Deploy.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {6624C337-C531-4C52-97CF-85E5F7BF8651}
+	EndGlobalSection
+EndGlobal

+ 0 - 32
RockRain/main.cs

@@ -1,32 +0,0 @@
-using System;
-using System.Drawing;
-using System.Runtime.InteropServices;
-using MonoTouch.AudioToolbox;
-using MonoTouch.CoreAnimation;
-using MonoTouch.CoreGraphics;
-using MonoTouch.Foundation;
-using MonoTouch.OpenGLES;
-using MonoTouch.UIKit;
-using MonoTouch.ObjCRuntime;
-using Microsoft.Xna.Framework;
-
-namespace RockRainIphone
-{
-	[Register ("AppDelegate")]
-	class Program : UIApplicationDelegate 
-	{
-		private Game1 game;
-
-		public override void FinishedLaunching (UIApplication app)
-		{
-			// Fun begins..
-			game = new Game1();
-			game.Run();
-		}
-		
-		static void Main (string [] args)
-		{
-			UIApplication.Main (args,null,"AppDelegate");
-		}
-	}
-}