Browse Source

Changes that allows this code to work under Windows XNA, minus shader and audio support.

CartBlanche 13 years ago
parent
commit
e44639851b

+ 2 - 1
StarterKits/MacOS/VectorRumble/AudioManager.cs

@@ -51,8 +51,9 @@ namespace VectorRumble
             string soundBankFile)
             : base(game)
         {
-            engine = new AudioEngine(settingsFile);
+            
 #if AUDIO
+            engine = new AudioEngine(settingsFile);
             waves = new WaveBank(engine, waveBankFile);
             sounds = new SoundBank(engine, soundBankFile);
 #endif

+ 317 - 318
StarterKits/MacOS/VectorRumble/BloomPostprocess/BloomComponent.cs

@@ -1,318 +1,317 @@
-#region File Description
-//-----------------------------------------------------------------------------
-// BloomComponent.cs
-//
-// Microsoft XNA Community Game Platform
-// Copyright (C) Microsoft Corporation. All rights reserved.
-//-----------------------------------------------------------------------------
-#endregion
-
-#region Using Statements
-using System;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.Graphics;
-#endregion
-
-namespace VectorRumble
-{
-    /// <summary>
-    /// A DrawableGameComponent that will add bloom post-processing to what the previous
-    /// components have drawn.
-    /// </summary>
-    /// <remarks>
-    /// This class is similar to one of the same name in the Bloom sample.
-    /// </remarks>
-    public class BloomComponent : DrawableGameComponent
-    {
-        #region Fields
-
-        SpriteBatch spriteBatch;
-
-        Effect bloomExtractEffect;
-        Effect bloomCombineEffect;
-        Effect gaussianBlurEffect;
-
-        ResolveTexture2D resolveTarget;
-        RenderTarget2D renderTarget1;
-        RenderTarget2D renderTarget2;
-
-
-        // Choose what display settings the bloom should use.
-        public BloomSettings Settings
-        {
-            get { return settings; }
-            set { settings = value; }
-        }
-
-        BloomSettings settings = BloomSettings.PresetSettings[0];
-
-
-        // Optionally displays one of the intermediate buffers used
-        // by the bloom postprocess, so you can see exactly what is
-        // being drawn into each rendertarget.
-        public enum IntermediateBuffer
-        {
-            PreBloom,
-            BlurredHorizontally,
-            BlurredBothWays,
-            FinalResult,
-        }
-
-        public IntermediateBuffer ShowBuffer
-        {
-            get { return showBuffer; }
-            set { showBuffer = value; }
-        }
-
-        IntermediateBuffer showBuffer = IntermediateBuffer.FinalResult;
-
-
-        #endregion
-
-        #region Initialization
-
-
-        public BloomComponent(Game game)
-            : base(game)
-        {
-            if (game == null)
-                throw new ArgumentNullException("game");
-        }
-
-
-        /// <summary>
-        /// Load your graphics content.
-        /// </summary>
-        protected override void LoadContent()
-        {
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-
-#if SHADER_EFFECTS
-            bloomExtractEffect = Game.Content.Load<Effect>("Effects/BloomExtract");
-            bloomCombineEffect = Game.Content.Load<Effect>("Effects/BloomCombine");
-            gaussianBlurEffect = Game.Content.Load<Effect>("Effects/GaussianBlur");
-#endif
-
-
-            // Look up the resolution and format of our main backbuffer.
-            PresentationParameters pp = GraphicsDevice.PresentationParameters;
-
-            int width = pp.BackBufferWidth;
-            int height = pp.BackBufferHeight;
-
-            SurfaceFormat format = pp.BackBufferFormat;
-
-            // Create a texture for reading back the backbuffer contents.
-            resolveTarget = new ResolveTexture2D(GraphicsDevice, width, height, 1, 
-                format);
-
-            // Create two rendertargets for the bloom processing. These are half the
-            // size of the backbuffer, in order to minimize fillrate costs. Reducing
-            // the resolution in this way doesn't hurt quality, because we are going
-            // to be blurring the bloom images in any case.
-            width /= 2;
-            height /= 2;
-
-            renderTarget1 = new RenderTarget2D(GraphicsDevice, width, height, true, format, DepthFormat.None);
-            renderTarget2 = new RenderTarget2D(GraphicsDevice, width, height, true, format, DepthFormat.None);
-        }
-
-
-        /// <summary>
-        /// Unload your graphics content.
-        /// </summary>
-        protected override void UnloadContent()
-        {
-            resolveTarget.Dispose();
-            renderTarget1.Dispose();
-            renderTarget2.Dispose();
-        }
-
-
-        #endregion
-
-        #region Draw
-
-
-        /// <summary>
-        /// This is where it all happens. Grabs a scene that has already been rendered,
-        /// and uses postprocess magic to add a glowing bloom effect over the top of it.
-        /// </summary>
-        public override void Draw(GameTime gameTime)
-        {
-#if SHADER_EFFECTS
-            // Resolve the scene into a texture, so we can
-            // use it as input data for the bloom processing.
-            GraphicsDevice.ResolveBackBuffer(resolveTarget);
-
-            // Pass 1: draw the scene into rendertarget 1, using a
-            // shader that extracts only the brightest parts of the image.
-            bloomExtractEffect.Parameters["BloomThreshold"].SetValue(Settings.BloomThreshold);
-
-            DrawFullscreenQuad(resolveTarget, renderTarget1, bloomExtractEffect, IntermediateBuffer.PreBloom);
-
-            // Pass 2: draw from rendertarget 1 into rendertarget 2,
-            // using a shader to apply a horizontal gaussian blur filter.
-            SetBlurEffectParameters(1.0f / (float)renderTarget1.Width, 0);
-
-            DrawFullscreenQuad(renderTarget1, renderTarget2, gaussianBlurEffect, IntermediateBuffer.BlurredHorizontally);
-
-            // Pass 3: draw from rendertarget 2 back into rendertarget 1,
-            // using a shader to apply a vertical gaussian blur filter.
-            SetBlurEffectParameters(0, 1.0f / (float)renderTarget1.Height);
-
-            DrawFullscreenQuad(renderTarget2, renderTarget1, gaussianBlurEffect, IntermediateBuffer.BlurredBothWays);
-
-            // Pass 4: draw both rendertarget 1 and the original scene
-            // image back into the main backbuffer, using a shader that
-            // combines them to produce the final bloomed result.
-            GraphicsDevice.SetRenderTarget(null);
-
-            EffectParameterCollection parameters = bloomCombineEffect.Parameters;
-
-            parameters["BloomIntensity"].SetValue(Settings.BloomIntensity);
-            parameters["BaseIntensity"].SetValue(Settings.BaseIntensity);
-            parameters["BloomSaturation"].SetValue(Settings.BloomSaturation);
-            parameters["BaseSaturation"].SetValue(Settings.BaseSaturation); 
-
-            GraphicsDevice.Textures[1] = resolveTarget;
-
-            Viewport viewport = GraphicsDevice.Viewport;
-
-            DrawFullscreenQuad(renderTarget1, viewport.Width, viewport.Height, bloomCombineEffect, IntermediateBuffer.FinalResult);
-#endif
-        }
-
-
-        /// <summary>
-        /// Helper for drawing a texture into a rendertarget, using
-        /// a custom shader to apply postprocessing effects.
-        /// </summary>
-        void DrawFullscreenQuad(Texture2D texture, RenderTarget2D renderTarget,
-                                Effect effect, IntermediateBuffer currentBuffer)
-        {
-            GraphicsDevice.SetRenderTarget(renderTarget);
-
-            DrawFullscreenQuad(texture,
-                               renderTarget.Width, renderTarget.Height,
-                               effect, currentBuffer);
-
-            GraphicsDevice.SetRenderTarget(null);
-        }
-
-
-        /// <summary>
-        /// Helper for drawing a texture into the current rendertarget,
-        /// using a custom shader to apply postprocessing effects.
-        /// </summary>
-        void DrawFullscreenQuad(Texture2D texture, int width, int height,
-                                Effect effect, IntermediateBuffer currentBuffer)
-        {
-            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
-
-            // Begin the custom effect, if it is currently enabled. If the user
-            // has selected one of the show intermediate buffer options, we still
-            // draw the quad to make sure the image will end up on the screen,
-            // but might need to skip applying the custom pixel shader.
-            if (showBuffer >= currentBuffer)
-            {
-                effect.CurrentTechnique.Passes[0].Apply();
-            }
-
-            // Draw the quad.
-            spriteBatch.Draw(texture, new Rectangle(0, 0, width, height), Color.White);
-            spriteBatch.End();
-
-            // End the custom effect.
-            /* NO LONGER NEEDED if (showBuffer >= currentBuffer)
-            {
-                effect.CurrentTechnique.Passes[0].End();
-                effect.End();
-            } */
-        }
-
-
-        /// <summary>
-        /// Computes sample weightings and texture coordinate offsets
-        /// for one pass of a separable gaussian blur filter.
-        /// </summary>
-        void SetBlurEffectParameters(float dx, float dy)
-        {
-            // Look up the sample weight and offset effect parameters.
-            EffectParameter weightsParameter, offsetsParameter;
-
-            weightsParameter = gaussianBlurEffect.Parameters["SampleWeights"];
-            offsetsParameter = gaussianBlurEffect.Parameters["SampleOffsets"];
-
-            // Look up how many samples our gaussian blur effect supports.
-            int sampleCount = weightsParameter.Elements.Count;
-
-            // Create temporary arrays for computing our filter settings.
-            float[] sampleWeights = new float[sampleCount];
-            Vector2[] sampleOffsets = new Vector2[sampleCount];
-
-            // The first sample always has a zero offset.
-            sampleWeights[0] = ComputeGaussian(0);
-            sampleOffsets[0] = new Vector2(0);
-
-            // Maintain a sum of all the weighting values.
-            float totalWeights = sampleWeights[0];
-
-            // Add pairs of additional sample taps, positioned
-            // along a line in both directions from the center.
-            for (int i = 0; i < sampleCount / 2; i++)
-            {
-                // Store weights for the positive and negative taps.
-                float weight = ComputeGaussian(i + 1);
-
-                sampleWeights[i * 2 + 1] = weight;
-                sampleWeights[i * 2 + 2] = weight;
-
-                totalWeights += weight * 2;
-
-                // To get the maximum amount of blurring from a limited number of
-                // pixel shader samples, we take advantage of the bilinear filtering
-                // hardware inside the texture fetch unit. If we position our texture
-                // coordinates exactly halfway between two texels, the filtering unit
-                // will average them for us, giving two samples for the price of one.
-                // This allows us to step in units of two texels per sample, rather
-                // than just one at a time. The 1.5 offset kicks things off by
-                // positioning us nicely in between two texels.
-                float sampleOffset = i * 2 + 1.5f;
-
-                Vector2 delta = new Vector2(dx, dy) * sampleOffset;
-
-                // Store texture coordinate offsets for the positive and negative taps.
-                sampleOffsets[i * 2 + 1] = delta;
-                sampleOffsets[i * 2 + 2] = -delta;
-            }
-
-            // Normalize the list of sample weightings, so they will always sum to one.
-            for (int i = 0; i < sampleWeights.Length; i++)
-            {
-                sampleWeights[i] /= totalWeights;
-            }
-
-            // Tell the effect about our new filter settings.
-            weightsParameter.SetValue(sampleWeights);
-            offsetsParameter.SetValue(sampleOffsets);
-        }
-
-
-        /// <summary>
-        /// Evaluates a single point on the gaussian falloff curve.
-        /// Used for setting up the blur filter weightings.
-        /// </summary>
-        float ComputeGaussian(float n)
-        {
-            float theta = Settings.BlurAmount;
-
-            return (float)((1.0 / Math.Sqrt(2 * Math.PI * theta)) *
-                           Math.Exp(-(n * n) / (2 * theta * theta)));
-        }
-
-
-        #endregion
-    }
-}
+#region File Description
+//-----------------------------------------------------------------------------
+// BloomComponent.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+#endregion
+
+namespace VectorRumble
+{
+    /// <summary>
+    /// A DrawableGameComponent that will add bloom post-processing to what the previous
+    /// components have drawn.
+    /// </summary>
+    /// <remarks>
+    /// This class is similar to one of the same name in the Bloom sample.
+    /// </remarks>
+    public class BloomComponent : DrawableGameComponent
+    {
+        #region Fields
+
+        SpriteBatch spriteBatch;
+
+        Effect bloomExtractEffect;
+        Effect bloomCombineEffect;
+        Effect gaussianBlurEffect;
+
+        RenderTarget2D resolveTarget;
+        RenderTarget2D renderTarget1;
+        RenderTarget2D renderTarget2;
+
+
+        // Choose what display settings the bloom should use.
+        public BloomSettings Settings
+        {
+            get { return settings; }
+            set { settings = value; }
+        }
+
+        BloomSettings settings = BloomSettings.PresetSettings[0];
+
+
+        // Optionally displays one of the intermediate buffers used
+        // by the bloom postprocess, so you can see exactly what is
+        // being drawn into each rendertarget.
+        public enum IntermediateBuffer
+        {
+            PreBloom,
+            BlurredHorizontally,
+            BlurredBothWays,
+            FinalResult,
+        }
+
+        public IntermediateBuffer ShowBuffer
+        {
+            get { return showBuffer; }
+            set { showBuffer = value; }
+        }
+
+        IntermediateBuffer showBuffer = IntermediateBuffer.FinalResult;
+
+
+        #endregion
+
+        #region Initialization
+
+
+        public BloomComponent(Game game)
+            : base(game)
+        {
+            if (game == null)
+                throw new ArgumentNullException("game");
+        }
+
+
+        /// <summary>
+        /// Load your graphics content.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+
+#if SHADER_EFFECTS
+            bloomExtractEffect = Game.Content.Load<Effect>("Effects/BloomExtract");
+            bloomCombineEffect = Game.Content.Load<Effect>("Effects/BloomCombine");
+            gaussianBlurEffect = Game.Content.Load<Effect>("Effects/GaussianBlur");
+#endif
+
+
+            // Look up the resolution and format of our main backbuffer.
+            PresentationParameters pp = GraphicsDevice.PresentationParameters;
+
+            int width = pp.BackBufferWidth;
+            int height = pp.BackBufferHeight;
+
+            SurfaceFormat format = pp.BackBufferFormat;
+
+            // Create a texture for reading back the backbuffer contents.
+            resolveTarget = new RenderTarget2D(GraphicsDevice, width, height, true, format, DepthFormat.None);
+
+            // Create two rendertargets for the bloom processing. These are half the
+            // size of the backbuffer, in order to minimize fillrate costs. Reducing
+            // the resolution in this way doesn't hurt quality, because we are going
+            // to be blurring the bloom images in any case.
+            width /= 2;
+            height /= 2;
+
+            renderTarget1 = new RenderTarget2D(GraphicsDevice, width, height, true, format, DepthFormat.None);
+            renderTarget2 = new RenderTarget2D(GraphicsDevice, width, height, true, format, DepthFormat.None);
+        }
+
+
+        /// <summary>
+        /// Unload your graphics content.
+        /// </summary>
+        protected override void UnloadContent()
+        {
+            resolveTarget.Dispose();
+            renderTarget1.Dispose();
+            renderTarget2.Dispose();
+        }
+
+
+        #endregion
+
+        #region Draw
+
+
+        /// <summary>
+        /// This is where it all happens. Grabs a scene that has already been rendered,
+        /// and uses postprocess magic to add a glowing bloom effect over the top of it.
+        /// </summary>
+        public override void Draw(GameTime gameTime)
+        {
+#if SHADER_EFFECTS
+            // Resolve the scene into a texture, so we can
+            // use it as input data for the bloom processing.
+            // GraphicsDevice.ResolveBackBuffer(resolveTarget);
+
+            // Pass 1: draw the scene into rendertarget 1, using a
+            // shader that extracts only the brightest parts of the image.
+            bloomExtractEffect.Parameters["BloomThreshold"].SetValue(Settings.BloomThreshold);
+
+            DrawFullscreenQuad(resolveTarget, renderTarget1, bloomExtractEffect, IntermediateBuffer.PreBloom);
+
+            // Pass 2: draw from rendertarget 1 into rendertarget 2,
+            // using a shader to apply a horizontal gaussian blur filter.
+            SetBlurEffectParameters(1.0f / (float)renderTarget1.Width, 0);
+
+            DrawFullscreenQuad(renderTarget1, renderTarget2, gaussianBlurEffect, IntermediateBuffer.BlurredHorizontally);
+
+            // Pass 3: draw from rendertarget 2 back into rendertarget 1,
+            // using a shader to apply a vertical gaussian blur filter.
+            SetBlurEffectParameters(0, 1.0f / (float)renderTarget1.Height);
+
+            DrawFullscreenQuad(renderTarget2, renderTarget1, gaussianBlurEffect, IntermediateBuffer.BlurredBothWays);
+
+            // Pass 4: draw both rendertarget 1 and the original scene
+            // image back into the main backbuffer, using a shader that
+            // combines them to produce the final bloomed result.
+            GraphicsDevice.SetRenderTarget(null);
+
+            EffectParameterCollection parameters = bloomCombineEffect.Parameters;
+
+            parameters["BloomIntensity"].SetValue(Settings.BloomIntensity);
+            parameters["BaseIntensity"].SetValue(Settings.BaseIntensity);
+            parameters["BloomSaturation"].SetValue(Settings.BloomSaturation);
+            parameters["BaseSaturation"].SetValue(Settings.BaseSaturation); 
+
+            GraphicsDevice.Textures[1] = resolveTarget;
+
+            Viewport viewport = GraphicsDevice.Viewport;
+
+            DrawFullscreenQuad(renderTarget1, viewport.Width, viewport.Height, bloomCombineEffect, IntermediateBuffer.FinalResult);
+#endif
+        }
+
+
+        /// <summary>
+        /// Helper for drawing a texture into a rendertarget, using
+        /// a custom shader to apply postprocessing effects.
+        /// </summary>
+        void DrawFullscreenQuad(Texture2D texture, RenderTarget2D renderTarget,
+                                Effect effect, IntermediateBuffer currentBuffer)
+        {
+            GraphicsDevice.SetRenderTarget(renderTarget);
+
+            DrawFullscreenQuad(texture,
+                               renderTarget.Width, renderTarget.Height,
+                               effect, currentBuffer);
+
+            GraphicsDevice.SetRenderTarget(null);
+        }
+
+
+        /// <summary>
+        /// Helper for drawing a texture into the current rendertarget,
+        /// using a custom shader to apply postprocessing effects.
+        /// </summary>
+        void DrawFullscreenQuad(Texture2D texture, int width, int height,
+                                Effect effect, IntermediateBuffer currentBuffer)
+        {
+            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
+
+            // Begin the custom effect, if it is currently enabled. If the user
+            // has selected one of the show intermediate buffer options, we still
+            // draw the quad to make sure the image will end up on the screen,
+            // but might need to skip applying the custom pixel shader.
+            if (showBuffer >= currentBuffer)
+            {
+                effect.CurrentTechnique.Passes[0].Apply();
+            }
+
+            // Draw the quad.
+            spriteBatch.Draw(texture, new Rectangle(0, 0, width, height), Color.White);
+            spriteBatch.End();
+
+            // End the custom effect.
+            /* NO LONGER NEEDED if (showBuffer >= currentBuffer)
+            {
+                effect.CurrentTechnique.Passes[0].End();
+                effect.End();
+            } */
+        }
+
+
+        /// <summary>
+        /// Computes sample weightings and texture coordinate offsets
+        /// for one pass of a separable gaussian blur filter.
+        /// </summary>
+        void SetBlurEffectParameters(float dx, float dy)
+        {
+            // Look up the sample weight and offset effect parameters.
+            EffectParameter weightsParameter, offsetsParameter;
+
+            weightsParameter = gaussianBlurEffect.Parameters["SampleWeights"];
+            offsetsParameter = gaussianBlurEffect.Parameters["SampleOffsets"];
+
+            // Look up how many samples our gaussian blur effect supports.
+            int sampleCount = weightsParameter.Elements.Count;
+
+            // Create temporary arrays for computing our filter settings.
+            float[] sampleWeights = new float[sampleCount];
+            Vector2[] sampleOffsets = new Vector2[sampleCount];
+
+            // The first sample always has a zero offset.
+            sampleWeights[0] = ComputeGaussian(0);
+            sampleOffsets[0] = new Vector2(0);
+
+            // Maintain a sum of all the weighting values.
+            float totalWeights = sampleWeights[0];
+
+            // Add pairs of additional sample taps, positioned
+            // along a line in both directions from the center.
+            for (int i = 0; i < sampleCount / 2; i++)
+            {
+                // Store weights for the positive and negative taps.
+                float weight = ComputeGaussian(i + 1);
+
+                sampleWeights[i * 2 + 1] = weight;
+                sampleWeights[i * 2 + 2] = weight;
+
+                totalWeights += weight * 2;
+
+                // To get the maximum amount of blurring from a limited number of
+                // pixel shader samples, we take advantage of the bilinear filtering
+                // hardware inside the texture fetch unit. If we position our texture
+                // coordinates exactly halfway between two texels, the filtering unit
+                // will average them for us, giving two samples for the price of one.
+                // This allows us to step in units of two texels per sample, rather
+                // than just one at a time. The 1.5 offset kicks things off by
+                // positioning us nicely in between two texels.
+                float sampleOffset = i * 2 + 1.5f;
+
+                Vector2 delta = new Vector2(dx, dy) * sampleOffset;
+
+                // Store texture coordinate offsets for the positive and negative taps.
+                sampleOffsets[i * 2 + 1] = delta;
+                sampleOffsets[i * 2 + 2] = -delta;
+            }
+
+            // Normalize the list of sample weightings, so they will always sum to one.
+            for (int i = 0; i < sampleWeights.Length; i++)
+            {
+                sampleWeights[i] /= totalWeights;
+            }
+
+            // Tell the effect about our new filter settings.
+            weightsParameter.SetValue(sampleWeights);
+            offsetsParameter.SetValue(sampleOffsets);
+        }
+
+
+        /// <summary>
+        /// Evaluates a single point on the gaussian falloff curve.
+        /// Used for setting up the blur filter weightings.
+        /// </summary>
+        float ComputeGaussian(float n)
+        {
+            float theta = Settings.BlurAmount;
+
+            return (float)((1.0 / Math.Sqrt(2 * Math.PI * theta)) *
+                           Math.Exp(-(n * n) / (2 * theta * theta)));
+        }
+
+
+        #endregion
+    }
+}

+ 60 - 2
StarterKits/MacOS/VectorRumble/Gameplay/Ship.cs

@@ -183,6 +183,16 @@ namespace VectorRumble
         /// </summary>
         private GamePadState lastGamePadState;
 
+        /// <summary>
+        /// The current state of the Keyboard that is controlling this ship.
+        /// </summary>
+        private KeyboardState currentKeyboardState;
+
+        /// <summary>
+        /// The previous state of the Keyboard that is controlling this ship.
+        /// </summary>
+        private KeyboardState lastKeyboardState;
+
         /// <summary>
         /// Timer for how long the player has been holding the A button (to join).
         /// </summary>
@@ -612,12 +622,14 @@ namespace VectorRumble
         public virtual void ProcessInput(float elapsedTime, bool overlayPresent)
         {
             currentGamePadState = GamePad.GetState(playerIndex);
+            currentKeyboardState = Keyboard.GetState();
+
             if (overlayPresent == false)
             {
                 if (playing == false)
                 {
                     // trying to join - update the a-button timer
-                    if (currentGamePadState.Buttons.A == ButtonState.Pressed)
+                    if ((currentGamePadState.Buttons.A == ButtonState.Pressed) || (currentKeyboardState.IsKeyDown(Keys.A) && playerIndex == PlayerIndex.Two))                    
                     {
                         aButtonTimer += elapsedTime;
                     }
@@ -635,7 +647,7 @@ namespace VectorRumble
                 else
                 {
                     // check if we're trying to leave
-                    if (currentGamePadState.Buttons.B == ButtonState.Pressed)
+                    if ((currentGamePadState.Buttons.B == ButtonState.Pressed) || (currentKeyboardState.IsKeyDown(Keys.B) && playerIndex == PlayerIndex.Two))
                     {
                         bButtonTimer += elapsedTime;
                     }
@@ -681,6 +693,51 @@ namespace VectorRumble
                             }
 
                         }
+                        else if (currentKeyboardState != null && playerIndex == PlayerIndex.Two)
+                        {
+                            // Rotate Left            
+                            if (currentKeyboardState.IsKeyDown(Keys.Left))
+                            {
+                                Rotation -= elapsedTime * rotationRadiansPerSecond;
+                            }
+
+                            // Rotate Right
+                            if (currentKeyboardState.IsKeyDown(Keys.Right))
+                            {
+                                Rotation += elapsedTime * rotationRadiansPerSecond;
+                            }
+
+                            //create some velocity if the right trigger is down
+                            Vector2 shipVelocityAdd = Vector2.Zero;
+
+                            //now scale our direction by how hard/long the trigger/keyboard is down
+                            if (currentKeyboardState.IsKeyDown(Keys.Up))
+                            {
+                                //find out what direction we should be thrusting, using rotation
+                                shipVelocityAdd.X = (float)Math.Sin(Rotation);
+                                shipVelocityAdd.Y = (float)-Math.Cos(Rotation);
+
+                                shipVelocityAdd = shipVelocityAdd / elapsedTime * MathHelper.ToRadians(9.0f);
+                            }
+
+                            //finally, add this vector to our velocity.
+                            Velocity += shipVelocityAdd;
+
+                            // Lets drop some Mines
+                            if (currentKeyboardState.IsKeyDown(Keys.RightControl))
+                            {
+                                // fire ahead of us
+                                weapon.Fire(Vector2.Normalize(forward));
+                            }
+
+                            // Lets drop some Mines
+                            if (currentKeyboardState.IsKeyDown(Keys.Down))
+                            {
+                                // fire behind the ship
+                                mineWeapon.Fire(-forward);
+                            }
+                        }
+
                         // check for firing with the right stick
                         Vector2 rightStick = currentGamePadState.ThumbSticks.Right;
                         rightStick.Y *= -1f;
@@ -701,6 +758,7 @@ namespace VectorRumble
 
             // update the gamepad state
             lastGamePadState = currentGamePadState;
+            lastKeyboardState = currentKeyboardState;
             return;
         }
         #endregion

+ 38 - 4
StarterKits/MacOS/VectorRumble/Rendering/LineBatch.cs

@@ -80,7 +80,7 @@ namespace VectorRumble
 			
 
             // create and configure the effect
-            this.effect = new BasicEffect(graphicsDevice, null);
+            this.effect = new BasicEffect(graphicsDevice);
             this.effect.VertexColorEnabled = true;
             this.effect.TextureEnabled = false;
             this.effect.LightingEnabled = false;
@@ -219,6 +219,43 @@ namespace VectorRumble
             }
         }
 
+        /// <summary>
+        /// Draws the given polygon, in defined segments.
+        /// </summary>
+        /// <param name="aPolygon">The polygon to render.</param>
+        /// <param name="aColor">The color to use when drawing the polygon.</param>
+        /// <param name="aDashed">If true, the polygon will be "dashed".</param>
+        /// <param name="aStartSeg">Start of segment drawing.</param>
+        /// <param name="aEndSeg">End of segment drawing.</param>
+        public void DrawPolygonSegments(VectorPolygon aPolygon, Color aColor, bool aDashed, int aStartSeg, int aEndSeg)
+        {
+            if (aPolygon == null || aEndSeg > aPolygon.TransformedPoints.Length)
+            {
+                throw new ArgumentNullException("polygon");
+            }
+            int step = (aDashed == true) ? 2 : 1;
+            for (int i = aStartSeg; i < aEndSeg; i += step)
+            {
+                if (currentIndex >= vertices.Length - 2)
+                {
+                    End();
+                    Begin();
+                }
+                vertices[currentIndex].Position.X =
+                    aPolygon.TransformedPoints[i % aPolygon.TransformedPoints.Length].X;
+                vertices[currentIndex].Position.Y =
+                    aPolygon.TransformedPoints[i % aPolygon.TransformedPoints.Length].Y;
+                vertices[currentIndex++].Color = aColor;
+                vertices[currentIndex].Position.X =
+                    aPolygon.TransformedPoints[(i + 1) %
+                        aPolygon.TransformedPoints.Length].X;
+                vertices[currentIndex].Position.Y =
+                    aPolygon.TransformedPoints[(i + 1) %
+                        aPolygon.TransformedPoints.Length].Y;
+                vertices[currentIndex++].Color = aColor;
+                lineCount++;
+            }
+        }
 
         /// <summary>
         /// Ends the batch of lines, submitting them to the graphics device.
@@ -231,9 +268,6 @@ namespace VectorRumble
                 return;
             }
 
-            // configure the graphics device and effect
-            graphicsDevice.VertexDeclaration = vertexDeclaration;
-
             // configure the graphics device to render our lines			
             graphicsDevice.BlendState = LineBlendState;
 

+ 163 - 168
StarterKits/MacOS/VectorRumble/Screens/BackgroundScreen.cs

@@ -1,168 +1,163 @@
-#region File Description
-//-----------------------------------------------------------------------------
-// BackgroundScreen.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.Content;
-using Microsoft.Xna.Framework.Graphics;
-#endregion
-
-namespace VectorRumble
-{
-    /// <summary>
-    /// The background screen sits behind all the other menu screens.
-    /// It draws a background image that remains fixed in place regardless
-    /// of whatever transitions the screens on top of it may be doing.
-    /// </summary>
-    /// <remarks>
-    /// This class is somewhat similar to one of the same name in the 
-    /// GameStateManagement sample.
-    /// </remarks>
-    class BackgroundScreen : GameScreen
-    {
-        #region Fields
-        Random random;
-        CollectCollection<ParticleSystem> particleSystems;
-        float addTimer;
-        Color[] explosionColors = new Color[] 
-            {
-                Color.Orange, Color.Red, Color.Gray, Color.Silver, Color.Yellow
-            };
-        LineBatch lineBatch;
-        Texture2D titleTexture;
-        #endregion
-
-        #region Initialization
-
-
-        /// <summary>
-        /// Constructor.
-        /// </summary>
-        public BackgroundScreen()
-        {
-            TransitionOnTime = TimeSpan.FromSeconds(1.0);
-            TransitionOffTime = TimeSpan.FromSeconds(1.0);
-
-            random = new Random();
-            particleSystems = new CollectCollection<ParticleSystem>(null);
-        }
-
-
-        /// <summary>
-        /// Loads graphics content for this screen. The background texture is quite
-        /// big, so we use our own local ContentManager to load it. This allows us
-        /// to unload before going from the menus into the game itself, wheras if we
-        /// used the shared ContentManager provided by the ScreenManager, the content
-        /// would remain loaded forever.
-        /// </summary>
-        public override void LoadContent()
-        {
-            lineBatch = new LineBatch(ScreenManager.GraphicsDevice);
-            titleTexture = ScreenManager.Game.Content.Load<Texture2D>("Textures/title");
-
-            int viewportWidth = ScreenManager.GraphicsDevice.Viewport.Width;
-            int viewportHeight = ScreenManager.GraphicsDevice.Viewport.Height;
-
-            // update the projection in the line-batch
-#if ORIGINAL
-            lineBatch.SetProjection(Matrix.CreateOrthographicOffCenter(0.0f,
-                viewportWidth, viewportHeight, 0.0f, 0.0f, 1.0f));
-#else
-			lineBatch.SetProjection(Matrix.CreateOrthographic(
-                viewportWidth, viewportHeight, 0.0f, 1.0f));
-#endif
-
-            // recreate the particle systems
-            particleSystems.Clear();
-            for (int i = 0; i < 4; i++)
-            {
-                particleSystems.Add(new ParticleSystem(
-                   new Vector2(random.Next(viewportWidth), random.Next(viewportHeight)),
-                   Vector2.Zero, 64, 256, 128,
-                   1f + 2f * (float)random.NextDouble(), 0.05f, explosionColors));
-            }
-
-            base.LoadContent();
-        }
-
-
-        #endregion
-
-        #region Update and Draw
-
-
-        /// <summary>
-        /// Updates the background screen. Unlike most screens, this should not
-        /// transition off even if it has been covered by another screen: it is
-        /// supposed to be covered, after all! This overload forces the
-        /// coveredByOtherScreen parameter to false in order to stop the base
-        /// Update method wanting to transition off.
-        /// </summary>
-        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
-                                                       bool coveredByOtherScreen)
-        {
-            addTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
-            if (addTimer > 0.25f)
-            {
-                addTimer -= 0.15f;
-                particleSystems.Add(new ParticleSystem(
-                   new Vector2(random.Next(ScreenManager.GraphicsDevice.Viewport.Width),
-                       random.Next(ScreenManager.GraphicsDevice.Viewport.Height)),
-                   Vector2.Zero, 64, 256, 128,
-                   1f + 2f * (float)random.NextDouble(), 0.05f, explosionColors));
-            }
-
-            for (int i = 0; i < particleSystems.Count; i++)
-            {
-                particleSystems[i].Update((float)gameTime.ElapsedGameTime.TotalSeconds);
-                if (particleSystems[i].IsActive == false)
-                {
-                    particleSystems.Garbage.Add(particleSystems[i]);
-                }
-            }
-            particleSystems.Collect();
-
-            base.Update(gameTime, otherScreenHasFocus, false);
-        }
-
-
-        /// <summary>
-        /// Draws the background screen.
-        /// </summary>
-        public override void Draw(GameTime gameTime)
-        {
-            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
-            Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
-
-            lineBatch.Begin();
-            for (int i = 0; i < particleSystems.Count; i++)
-            {
-                particleSystems[i].Draw(lineBatch);
-            }
-            lineBatch.End();
-
-            // title
-            Vector2 titlePosition = new Vector2(
-                (viewportSize.X - titleTexture.Width) / 2f,
-                viewportSize.Y * 0.18f);
-            titlePosition.Y -= (float)Math.Pow(TransitionPosition, 2) * titlePosition.Y;
-            Color titleColor = Color.White;
-
-            ScreenManager.SpriteBatch.Begin();
-            ScreenManager.SpriteBatch.Draw(titleTexture, titlePosition,
-                new Color(titleColor.R, titleColor.G, titleColor.B, TransitionAlpha));
-            ScreenManager.SpriteBatch.End();
-        }
-
-
-        #endregion
-    }
-}
+#region File Description
+//-----------------------------------------------------------------------------
+// BackgroundScreen.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.Content;
+using Microsoft.Xna.Framework.Graphics;
+#endregion
+
+namespace VectorRumble
+{
+    /// <summary>
+    /// The background screen sits behind all the other menu screens.
+    /// It draws a background image that remains fixed in place regardless
+    /// of whatever transitions the screens on top of it may be doing.
+    /// </summary>
+    /// <remarks>
+    /// This class is somewhat similar to one of the same name in the 
+    /// GameStateManagement sample.
+    /// </remarks>
+    class BackgroundScreen : GameScreen
+    {
+        #region Fields
+        Random random;
+        CollectCollection<ParticleSystem> particleSystems;
+        float addTimer;
+        Color[] explosionColors = new Color[] 
+            {
+                Color.Orange, Color.Red, Color.Gray, Color.Silver, Color.Yellow
+            };
+        LineBatch lineBatch;
+        Texture2D titleTexture;
+        #endregion
+
+        #region Initialization
+
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public BackgroundScreen()
+        {
+            TransitionOnTime = TimeSpan.FromSeconds(1.0);
+            TransitionOffTime = TimeSpan.FromSeconds(1.0);
+
+            random = new Random();
+            particleSystems = new CollectCollection<ParticleSystem>(null);
+        }
+
+
+        /// <summary>
+        /// Loads graphics content for this screen. The background texture is quite
+        /// big, so we use our own local ContentManager to load it. This allows us
+        /// to unload before going from the menus into the game itself, wheras if we
+        /// used the shared ContentManager provided by the ScreenManager, the content
+        /// would remain loaded forever.
+        /// </summary>
+        public override void LoadContent()
+        {
+            lineBatch = new LineBatch(ScreenManager.GraphicsDevice);
+            titleTexture = ScreenManager.Game.Content.Load<Texture2D>("Textures/title");
+
+            int viewportWidth = ScreenManager.GraphicsDevice.Viewport.Width;
+            int viewportHeight = ScreenManager.GraphicsDevice.Viewport.Height;
+
+            // update the projection in the line-batch
+            lineBatch.SetProjection(Matrix.CreateOrthographicOffCenter(0.0f,
+                viewportWidth, viewportHeight, 0.0f, 0.0f, 1.0f));
+
+            // recreate the particle systems
+            particleSystems.Clear();
+            for (int i = 0; i < 4; i++)
+            {
+                particleSystems.Add(new ParticleSystem(
+                   new Vector2(random.Next(viewportWidth), random.Next(viewportHeight)),
+                   Vector2.Zero, 64, 256, 128,
+                   1f + 2f * (float)random.NextDouble(), 0.05f, explosionColors));
+            }
+
+            base.LoadContent();
+        }
+
+
+        #endregion
+
+        #region Update and Draw
+
+
+        /// <summary>
+        /// Updates the background screen. Unlike most screens, this should not
+        /// transition off even if it has been covered by another screen: it is
+        /// supposed to be covered, after all! This overload forces the
+        /// coveredByOtherScreen parameter to false in order to stop the base
+        /// Update method wanting to transition off.
+        /// </summary>
+        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
+                                                       bool coveredByOtherScreen)
+        {
+            addTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
+            if (addTimer > 0.25f)
+            {
+                addTimer -= 0.15f;
+                particleSystems.Add(new ParticleSystem(
+                   new Vector2(random.Next(ScreenManager.GraphicsDevice.Viewport.Width),
+                       random.Next(ScreenManager.GraphicsDevice.Viewport.Height)),
+                   Vector2.Zero, 64, 256, 128,
+                   1f + 2f * (float)random.NextDouble(), 0.05f, explosionColors));
+            }
+
+            for (int i = 0; i < particleSystems.Count; i++)
+            {
+                particleSystems[i].Update((float)gameTime.ElapsedGameTime.TotalSeconds);
+                if (particleSystems[i].IsActive == false)
+                {
+                    particleSystems.Garbage.Add(particleSystems[i]);
+                }
+            }
+            particleSystems.Collect();
+
+            base.Update(gameTime, otherScreenHasFocus, false);
+        }
+
+
+        /// <summary>
+        /// Draws the background screen.
+        /// </summary>
+        public override void Draw(GameTime gameTime)
+        {
+            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
+            Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
+
+            lineBatch.Begin();
+            for (int i = 0; i < particleSystems.Count; i++)
+            {
+                particleSystems[i].Draw(lineBatch);
+            }
+            lineBatch.End();
+
+            // title
+            Vector2 titlePosition = new Vector2(
+                (viewportSize.X - titleTexture.Width) / 2f,
+                viewportSize.Y * 0.18f);
+            titlePosition.Y -= (float)Math.Pow(TransitionPosition, 2) * titlePosition.Y;
+            Color titleColor = Color.White;
+
+            ScreenManager.SpriteBatch.Begin();
+            ScreenManager.SpriteBatch.Draw(titleTexture, titlePosition,
+                new Color(titleColor.R, titleColor.G, titleColor.B, TransitionAlpha));
+            ScreenManager.SpriteBatch.End();
+        }
+
+
+        #endregion
+    }
+}

+ 1 - 1
StarterKits/MacOS/VectorRumble/Screens/GameOverScreen.cs

@@ -145,7 +145,7 @@ namespace VectorRumble
 
             // calculate the message position and size
             float textScale = 1.5f + 0.05f * 
-                (float)Math.Cos(gameTime.TotalRealTime.TotalSeconds * 8.0f);
+                (float)Math.Cos(gameTime.TotalGameTime.TotalSeconds * 8.0f);
             Vector2 textSize = ScreenManager.Font.MeasureString(message);
             Vector2 textPosition = new Vector2(
                 viewportSize.X / 2f - textSize.X / 2f * textScale,

+ 287 - 293
StarterKits/MacOS/VectorRumble/Screens/GameplayScreen.cs

@@ -1,293 +1,287 @@
-#region File Description
-//-----------------------------------------------------------------------------
-// GameplayScreen.cs
-//
-// Microsoft XNA Community Game Platform
-// Copyright (C) Microsoft Corporation. All rights reserved.
-//-----------------------------------------------------------------------------
-#endregion
-
-#region Using Statements
-using System;
-using System.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-#endregion
-
-namespace VectorRumble
-{
-    /// <summary>
-    /// This screen implements the actual game logic. It is just a
-    /// placeholder to get the idea across: you'll probably want to
-    /// put some more interesting gameplay in here!
-    /// </summary>
-    /// <remarks>
-    /// This class is somewhat similar to one of the same name in the 
-    /// GameStateManagement sample.
-    /// </remarks>
-    class GameplayScreen : GameScreen
-    {
-        #region Fields
-        BloomComponent bloomComponent;
-        ContentManager content;
-        LineBatch lineBatch;
-        SpriteBatch spriteBatch;
-        SpriteFont spriteFont;
-        Texture2D starTexture;
-        World world;
-        AudioManager audio;
-        bool gameOver;
-        #endregion
-
-        #region Initialization
-        /// <summary>
-        /// Constructor.
-        /// </summary>
-        public GameplayScreen()
-        {
-            TransitionOnTime = TimeSpan.FromSeconds(1.0);
-            TransitionOffTime = TimeSpan.FromSeconds(1.0);
-        }
-
-
-        /// <summary>
-        /// Initialize the game, after the ScreenManager is set, but not every time
-        /// the graphics are reloaded.
-        /// </summary>
-        public void Initialize()
-        {
-            // create and add the bloom effect
-            bloomComponent = new BloomComponent(ScreenManager.Game);
-            ScreenManager.Game.Components.Add(bloomComponent);
-            // do not automatically draw the bloom component
-            bloomComponent.Visible = false;
-
-            // create the world
-            world = new World(new Vector2(ScreenManager.GraphicsDevice.Viewport.Width,
-                ScreenManager.GraphicsDevice.Viewport.Height));
-
-            // retrieve the audio manager
-            audio = (AudioManager)ScreenManager.Game.Services.GetService(
-                typeof(AudioManager));
-            world.AudioManager = audio;
-            
-			// start up the music
-            audio.PlayMusic("gameMusic");
-			
-            // start up the game
-            world.StartNewGame();
-            gameOver = false;
-        }
-
-
-        /// <summary>
-        /// Load graphics content for the game.
-        /// </summary>
-        public override void LoadContent()
-        {
-            if (content == null)
-            {
-                content = new ContentManager(ScreenManager.Game.Services, "Content");
-            }
-            spriteBatch = new SpriteBatch(ScreenManager.GraphicsDevice);
-            lineBatch = new LineBatch(ScreenManager.GraphicsDevice);
-            spriteFont = content.Load<SpriteFont>("Fonts/retroSmall");
-            starTexture = content.Load<Texture2D>("Textures/blank");
-
-            // update the projection in the line-batch
-#if ORIGINAL
-            lineBatch.SetProjection(Matrix.CreateOrthographicOffCenter(0.0f,
-                ScreenManager.GraphicsDevice.Viewport.Width, 
-                ScreenManager.GraphicsDevice.Viewport.Height, 0.0f, 0.0f, 1.0f));
-#else
-			lineBatch.SetProjection(Matrix.CreateOrthographic(
-                ScreenManager.GraphicsDevice.Viewport.Width, 
-                ScreenManager.GraphicsDevice.Viewport.Height, 0.0f, 1.0f));
-#endif
-        }
-
-
-        /// <summary>
-        /// Unload graphics content used by the game.
-        /// </summary>
-        public override void UnloadContent()
-        {
-            if (spriteBatch != null)
-            {
-                spriteBatch.Dispose();
-                spriteBatch = null;
-            }
-            if (lineBatch != null)
-            {
-                lineBatch.Dispose();
-                lineBatch = null;
-            }
-            content.Unload();
-        }
-        #endregion
-
-        #region Update and Draw
-        /// <summary>
-        /// Updates the state of the game. This method checks the GameScreen.IsActive
-        /// property, so the game will stop updating when the pause menu is active,
-        /// or if you tab away to a different application.
-        /// </summary>
-        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
-                                                       bool coveredByOtherScreen)
-        {
-            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
-
-            // if this screen is leaving, then stop the music
-            if (IsExiting)
-            {
-                audio.StopMusic();
-            }
-            else if ((otherScreenHasFocus == true) || (coveredByOtherScreen == true))
-            {
-                // make sure nobody's controller is vibrating
-                for (int i = 0; i < 4; i++)
-                {
-                    GamePad.SetVibration((PlayerIndex)i, 0f, 0f);
-                }
-                if (gameOver == false)
-                {
-                    for (int i = 0; i < world.Ships.Length; i++)
-                    {
-                        world.Ships[i].ProcessInput(gameTime.TotalGameTime.Seconds, 
-                            true);
-                    }
-                }
-            }
-            else
-            {
-                // check for a winner
-                if (gameOver == false)
-                {
-                    for (int i = 0; i < world.Ships.Length; i++)
-                    {
-                        if (world.Ships[i].Score >= WorldRules.ScoreLimit)
-                        {
-                            ScreenManager.AddScreen(new GameOverScreen("Player " +
-                                (i + 1).ToString() + " wins the game!"));
-                            gameOver = true;
-                            break;
-                        }
-                    }
-                }
-                // update the world
-                if (gameOver == false)
-                {
-                    world.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
-                }
-            }
-        }
-
-
-        /// <summary>
-        /// Lets the game respond to player input. Unlike the Update method,
-        /// this will only be called when the gameplay screen is active.
-        /// </summary>
-        public override void HandleInput(InputState input)
-        {
-            if (input == null)
-                throw new ArgumentNullException("input");
-
-            if (input.PauseGame)
-            {
-                // If they pressed pause, bring up the pause menu screen.
-                ScreenManager.AddScreen(new PauseMenuScreen());
-            }
-        }
-
-
-        /// <summary>
-        /// Draws the gameplay screen.
-        /// </summary>
-        public override void Draw(GameTime gameTime)
-        {
-            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
-
-            lineBatch.Begin();
-
-            // draw all actors
-            foreach (Actor actor in world.Actors)
-            {
-                if (actor.Dead == false)
-                {
-                    actor.Draw(elapsedTime, lineBatch);
-                }
-            }
-
-            // draw all particle systems
-            foreach (ParticleSystem particleSystem in world.ParticleSystems)
-            {
-                if (particleSystem.IsActive)
-                {
-                    particleSystem.Draw(lineBatch);
-                }
-            }
-
-            // draw the walls
-            world.DrawWalls(lineBatch);
-
-            lineBatch.End();
-
-            // draw the stars
-            spriteBatch.Begin();
-            world.Starfield.Draw(spriteBatch, starTexture);
-            spriteBatch.End();
-
-            if (WorldRules.NeonEffect)
-            {
-                bloomComponent.Draw(gameTime);
-            }
-
-            DrawHud(elapsedTime);
-
-            // If the game is transitioning on or off, fade it out to black.
-            if (TransitionPosition > 0)
-                ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
-        }
-
-
-        /// <summary>
-        /// Draw the user interface elements of the game (scores, etc.).
-        /// </summary>
-        /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
-        private void DrawHud(float elapsedTime)
-        {
-            spriteBatch.Begin();
-
-            Vector2 position = new Vector2(128, 64);
-            int offset = (1280) / 5;
-
-            for (int i = 0; i < world.Ships.Length; ++i)
-            {
-                string message;
-
-                if (world.Ships[i].Playing)
-                {
-                    message = "Player " + (i + 1).ToString() + ": " +
-                        world.Ships[i].Score.ToString();
-                }
-                else
-                {
-                    message = "Hold A to Join";
-                }
-
-                float scale = 1.0f;
-
-                Vector2 size = spriteFont.MeasureString(message) * scale;
-                position.X = (i + 1) * offset - size.X / 2;
-                spriteBatch.DrawString(spriteFont, message, position, 
-                    world.Ships[i].Color, 0.0f, Vector2.Zero, scale, 
-                    SpriteEffects.None, 1.0f);
-            }
-
-            spriteBatch.End();
-        }
-        #endregion
-    }
-}
+#region File Description
+//-----------------------------------------------------------------------------
+// GameplayScreen.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Threading;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+#endregion
+
+namespace VectorRumble
+{
+    /// <summary>
+    /// This screen implements the actual game logic. It is just a
+    /// placeholder to get the idea across: you'll probably want to
+    /// put some more interesting gameplay in here!
+    /// </summary>
+    /// <remarks>
+    /// This class is somewhat similar to one of the same name in the 
+    /// GameStateManagement sample.
+    /// </remarks>
+    class GameplayScreen : GameScreen
+    {
+        #region Fields
+        BloomComponent bloomComponent;
+        ContentManager content;
+        LineBatch lineBatch;
+        SpriteBatch spriteBatch;
+        SpriteFont spriteFont;
+        Texture2D starTexture;
+        World world;
+        AudioManager audio;
+        bool gameOver;
+        #endregion
+
+        #region Initialization
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public GameplayScreen()
+        {
+            TransitionOnTime = TimeSpan.FromSeconds(1.0);
+            TransitionOffTime = TimeSpan.FromSeconds(1.0);
+        }
+
+
+        /// <summary>
+        /// Initialize the game, after the ScreenManager is set, but not every time
+        /// the graphics are reloaded.
+        /// </summary>
+        public void Initialize()
+        {
+            // create and add the bloom effect
+            bloomComponent = new BloomComponent(ScreenManager.Game);
+            ScreenManager.Game.Components.Add(bloomComponent);
+            // do not automatically draw the bloom component
+            bloomComponent.Visible = false;
+
+            // create the world
+            world = new World(new Vector2(ScreenManager.GraphicsDevice.Viewport.Width,
+                ScreenManager.GraphicsDevice.Viewport.Height));
+
+            // retrieve the audio manager
+            audio = (AudioManager)ScreenManager.Game.Services.GetService(
+                typeof(AudioManager));
+            world.AudioManager = audio;
+            
+			// start up the music
+            audio.PlayMusic("gameMusic");
+			
+            // start up the game
+            world.StartNewGame();
+            gameOver = false;
+        }
+
+
+        /// <summary>
+        /// Load graphics content for the game.
+        /// </summary>
+        public override void LoadContent()
+        {
+            if (content == null)
+            {
+                content = new ContentManager(ScreenManager.Game.Services, "Content");
+            }
+            spriteBatch = new SpriteBatch(ScreenManager.GraphicsDevice);
+            lineBatch = new LineBatch(ScreenManager.GraphicsDevice);
+            spriteFont = content.Load<SpriteFont>("Fonts/retroSmall");
+            starTexture = content.Load<Texture2D>("Textures/blank");
+
+            // update the projection in the line-batch
+            lineBatch.SetProjection(Matrix.CreateOrthographicOffCenter(0.0f,
+                ScreenManager.GraphicsDevice.Viewport.Width, 
+                ScreenManager.GraphicsDevice.Viewport.Height, 0.0f, 0.0f, 1.0f));
+        }
+
+
+        /// <summary>
+        /// Unload graphics content used by the game.
+        /// </summary>
+        public override void UnloadContent()
+        {
+            if (spriteBatch != null)
+            {
+                spriteBatch.Dispose();
+                spriteBatch = null;
+            }
+            if (lineBatch != null)
+            {
+                lineBatch.Dispose();
+                lineBatch = null;
+            }
+            content.Unload();
+        }
+        #endregion
+
+        #region Update and Draw
+        /// <summary>
+        /// Updates the state of the game. This method checks the GameScreen.IsActive
+        /// property, so the game will stop updating when the pause menu is active,
+        /// or if you tab away to a different application.
+        /// </summary>
+        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
+                                                       bool coveredByOtherScreen)
+        {
+            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
+
+            // if this screen is leaving, then stop the music
+            if (IsExiting)
+            {
+                audio.StopMusic();
+            }
+            else if ((otherScreenHasFocus == true) || (coveredByOtherScreen == true))
+            {
+                // make sure nobody's controller is vibrating
+                for (int i = 0; i < 4; i++)
+                {
+                    GamePad.SetVibration((PlayerIndex)i, 0f, 0f);
+                }
+                if (gameOver == false)
+                {
+                    for (int i = 0; i < world.Ships.Length; i++)
+                    {
+                        world.Ships[i].ProcessInput(gameTime.TotalGameTime.Seconds, 
+                            true);
+                    }
+                }
+            }
+            else
+            {
+                // check for a winner
+                if (gameOver == false)
+                {
+                    for (int i = 0; i < world.Ships.Length; i++)
+                    {
+                        if (world.Ships[i].Score >= WorldRules.ScoreLimit)
+                        {
+                            ScreenManager.AddScreen(new GameOverScreen("Player " +
+                                (i + 1).ToString() + " wins the game!"));
+                            gameOver = true;
+                            break;
+                        }
+                    }
+                }
+                // update the world
+                if (gameOver == false)
+                {
+                    world.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
+                }
+            }
+        }
+
+
+        /// <summary>
+        /// Lets the game respond to player input. Unlike the Update method,
+        /// this will only be called when the gameplay screen is active.
+        /// </summary>
+        public override void HandleInput(InputState input)
+        {
+            if (input == null)
+                throw new ArgumentNullException("input");
+
+            if (input.PauseGame)
+            {
+                // If they pressed pause, bring up the pause menu screen.
+                ScreenManager.AddScreen(new PauseMenuScreen());
+            }
+        }
+
+
+        /// <summary>
+        /// Draws the gameplay screen.
+        /// </summary>
+        public override void Draw(GameTime gameTime)
+        {
+            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+            lineBatch.Begin();
+
+            // draw all actors
+            foreach (Actor actor in world.Actors)
+            {
+                if (actor.Dead == false)
+                {
+                    actor.Draw(elapsedTime, lineBatch);
+                }
+            }
+
+            // draw all particle systems
+            foreach (ParticleSystem particleSystem in world.ParticleSystems)
+            {
+                if (particleSystem.IsActive)
+                {
+                    particleSystem.Draw(lineBatch);
+                }
+            }
+
+            // draw the walls
+            world.DrawWalls(lineBatch);
+
+            lineBatch.End();
+
+            // draw the stars
+            spriteBatch.Begin();
+            world.Starfield.Draw(spriteBatch, starTexture);
+            spriteBatch.End();
+
+            if (WorldRules.NeonEffect)
+            {
+                bloomComponent.Draw(gameTime);
+            }
+
+            DrawHud(elapsedTime);
+
+            // If the game is transitioning on or off, fade it out to black.
+            if (TransitionPosition > 0)
+                ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
+        }
+
+
+        /// <summary>
+        /// Draw the user interface elements of the game (scores, etc.).
+        /// </summary>
+        /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param>
+        private void DrawHud(float elapsedTime)
+        {
+            spriteBatch.Begin();
+
+            Vector2 position = new Vector2(128, 64);
+            int offset = (1280) / 5;
+
+            for (int i = 0; i < world.Ships.Length; ++i)
+            {
+                string message;
+
+                if (world.Ships[i].Playing)
+                {
+                    message = "Player " + (i + 1).ToString() + ": " +
+                        world.Ships[i].Score.ToString();
+                }
+                else
+                {
+                    message = "Hold A to Join";
+                }
+
+                float scale = 1.0f;
+
+                Vector2 size = spriteFont.MeasureString(message) * scale;
+                position.X = (i + 1) * offset - size.X / 2;
+                spriteBatch.DrawString(spriteFont, message, position, 
+                    world.Ships[i].Color, 0.0f, Vector2.Zero, scale, 
+                    SpriteEffects.None, 1.0f);
+            }
+
+            spriteBatch.End();
+        }
+        #endregion
+    }
+}

+ 1 - 1
StarterKits/MacOS/VectorRumble/VectorRumble.csproj

@@ -16,7 +16,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;MONOMAC;SHADER_EFFECTS</DefineConstants>
+    <DefineConstants>DEBUG;MONOMAC;</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <ConsolePause>false</ConsolePause>