HOW TO: CREATE YOUR FIRST XNA/MONOGAME FRAMEWORK APPLICATION FOR WINDOWS 8 METRO [ported]

Many people were quite annoyed by the decision to not ship XNA as part of the Windows Metro Development space for Windows 8. The MonoGame project has stepped in and is building a cross-platform game solutions for XNA. Note that MonoGame is still under development, and you may hit some things that don’t work. I’m hoping to port a number of articles and code samples to MonoGame from XNA for Windows Phone, tracking the various issues I uncovered.

For a primer on MonoGame and setting up your environment, I suggest you review the resources at [ https://dfwiki.devfish.net/technology.Windows-8-Game-Development.ashx#_MONOGAME__0 ]. This is an evolving list of resources, which will grow over time. The YouTube Video [ https://www.youtube.com/watch?v=-ycmeVYm_gI ] on setting up your MonoGame environment, and Bob Familiar’s getting started blog series [ https://blogs.msdn.com/b/bobfamiliar/archive/2012/08/01/windows-8-xna-and-monogame-part-1-overview.aspx ] are particularly useful.

NOT ORIGINAL CODE

When I started with XNA, one of my favorite articles, and still an example I use to show people how easy XNA is was the “How to: Create Your First XNA Framework Application for Windows Phone” article at https://msdn.microsoft.com/en-us/library/ff472340(v=VS.92).aspx . The how-to article will be our first proof point for XNA in Windows Metro. I take no credit for the code, merely making it work in Windows Metro via MonoGame.

STEP ONE – SETUP YOUR ENVIRONMENT

Setting up your environment requires a number of steps. 

Bob Familiar has done an excellent job documenting the setup of the environment in this blog post – [ https://blogs.msdn.com/b/bobfamiliar/archive/2012/08/02/windows-8-xna-and-monogame-part-2-getting-started.aspx ]. After completing the steps documented you should have a new template available in Visual Studio 2012 for a MonoGame Metro Application.

image

STEP TWO – CREATE THE BASE MONOGAME PROJECT IN VISUAL STUDIO 2012

  • Create a new MonoGame Metro solution and project in Visual Studio 2012, name it FirstMonoGameWindowsMetroApp.
  • The project needs the MonoGame for Windows 8 source and binaries. Add the existing MonoGame project for Windows 8 to the FirstMonoGameWindowsMetroApp solution. The projects location may vary depending upon where you ‘git-ed’ the files to. In my case the project was in C:\dev\monogame\MonoGame\MonoGame.Framework. The actual .csproj is named MonoGame.Framework.Windows8.csproj .

image

  • Add a reference to the MonoGame framework in the FirstMonoGameWindowsMetroApp project using Visual Studio 2012.

image

  • Run the project. You should see a Cornflower-blue screen. Note you are now running XNA in Windows 8. Not very exciting, but yes, this cornflower blue screen is being refreshed over 30 times per second.

BUILDING THE CONTENT PIPELINE

In traditional XNA the Content Pipeline project is tasked with taking various fonts, audio assets, visual assets and turning them into XNA consumable files. These assets are stored in .XNB files, or XNA Binary Packages. The files may then be referenced by XNA programs. Note the files are not simple .zip extensions, and must be created.

Neither MonoGame or Visual Studio 2012 have a template or tools to create XNB files. So we must use Visual Studio 2010 to create our XNB files for us. Note: You must have Visual Studio 2010 with the Widnows Phone Developer Tools installed to create XNB files.

  • Open Visual Studio 2010
  • Create a new XNA Game Studio 4.0 / Windows Phone Game 4.0 project named “FirstXNA2010”
  • Add the PhoneGameThumb.png from the main project to the FirstXNA2010Content project. This is our content pipeline project that will create the XNBs for us. You can also add in any other assets you might like.
  • Fine a .wav file that plays a sound to add to the content pipeline project as well. Note you can grab “Windows Ding.wav” from the completed source.

image

  • Change the compile target from “Debug” to “Release”. Build the project.
  • Now let’s hunt down the binaries to copy. 
  • Right-mouse on FirstXNA2010 and select “Open Folder in Windows Explorer”. 
  • Click on bin => Windows Phone => Release => Content. You should see the XNB files that were generated. Note the full path on my dev box was “C:\dev\monogame\FirstXNA\FirstXNA2010\FirstXNA2010\FirstXNA2010\bin\Windows Phone\Release\Content“.
  • Highlight the files in Windows Explorer, right-mouse them, and click “Copy”.

image

  • Move back to Visual Studio 2012. Right-mouse on the FirstMonoGameWindowsMetroApp project. Select “Open Folder in Windows Explorer”.
  • Navigate to bin=>Debug=>AppX . The full path on my dev box is “C:\dev\monogame\FirstXNA\FirstMonoGameWindowsMetroApp\bin\Debug\AppX”. 
  • If there is no “Content” directory create it. 
  • Navigate to the Content directory. 
  • Paste the XNB files into the Content directory.

image

CODING THE SAMPLE

At this point we are ready to begin moving in the sample. Note the code is pretty much exactly the same code as is in the sample at [ https://msdn.microsoft.com/en-us/library/ff472340(v=VS.92).aspx ]. I’m reproducing the code here so you can have easy access to cut and paste without flipping back and forth. Also note we are not going into XNA fundamentals in this article. Please reference the resources in the original MSDN article or head over to https://bit.ly/devfish_wpgetstarted for some game programming resources.

Just like normal XNA, we’re going to add variables, load graphics and sound via LoadContent, Draw our objects in the Draw loop, and update the position of the graphic objects in the Update loop.

  • Add in our variables. Note when you paste in the variables below, the project does not know about SoundEffect and you will get an error.
 Texture2D texture1;
Texture2D texture2;
Vector2 spritePosition1;
Vector2 spritePosition2;
Vector2 spriteSpeed1 = new Vector2(50.0f, 50.0f);
Vector2 spriteSpeed2 = new Vector2(100.0f, 100.0f);
int sprite1Height;
int sprite1Width;
int sprite2Height;
int sprite2Width;
SoundEffect soundEffect;

 

FIX SOUNDEFFECT

The default MonoGame template at this time does not automatically have an import for the SoundEffect namespace. 

  • Add in the following “using” statement for the SoundEffect class.
 using Microsoft.Xna.Framework.Audio;

LOADCONTENT

  • Wire up the LoadContent method as follows:
 protected override void LoadContent() 
{
spriteBatch = new SpriteBatch(GraphicsDevice); 
texture1 = Content.Load<Texture2D>("PhoneGameThumb"); 
texture2 = Content.Load<Texture2D>("PhoneGameThumb"); 
soundEffect = Content.Load<SoundEffect>("Windows Ding"); 
spritePosition1.X = 0; 
spritePosition1.Y = 0; 
spritePosition2.X = graphics.GraphicsDevice.Viewport.Width - texture1.Width; spritePosition2.Y = graphics.GraphicsDevice.Viewport.Height - texture1.Height; sprite1Height = texture1.Bounds.Height; sprite1Width = texture1.Bounds.Width; sprite2Height = texture2.Bounds.Height; sprite2Width = texture2.Bounds.Width; 
} 

DRAW

         protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            // Draw the sprite.
            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
            spriteBatch.Draw(texture1, spritePosition1, Color.White);
            spriteBatch.End();

            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.Opaque);
            spriteBatch.Draw(texture2, spritePosition2, Color.Gray);
            spriteBatch.End();

            base.Draw(gameTime);
        }
  • MODIFY UPDATE AS FOLLOWS
         void UpdateSprite(GameTime gameTime, ref Vector2 spritePosition, ref Vector2 spriteSpeed)
        {
            // Move the sprite by speed, scaled by elapsed time.
            spritePosition +=
                spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;

            int MaxX =
                graphics.GraphicsDevice.Viewport.Width - texture1.Width;
            int MinX = 0;
            int MaxY =
                graphics.GraphicsDevice.Viewport.Height - texture1.Height;
            int MinY = 0;

            // Check for bounce.
            if (spritePosition.X > MaxX)
            {
                spriteSpeed.X *= -1;
                spritePosition.X = MaxX;
            }

            else if (spritePosition.X < MinX)
            {
                spriteSpeed.X *= -1;
                spritePosition.X = MinX;
            }

            if (spritePosition.Y > MaxY)
            {
                spriteSpeed.Y *= -1;
                spritePosition.Y = MaxY;
            }

            else if (spritePosition.Y < MinY)
            {
                spriteSpeed.Y *= -1;
                spritePosition.Y = MinY;
            }

        }

        void CheckForCollision()
        {
            BoundingBox bb1 = new BoundingBox(new Vector3(spritePosition1.X - (sprite1Width / 2), spritePosition1.Y - (sprite1Height / 2), 0), new Vector3(spritePosition1.X + (sprite1Width / 2), spritePosition1.Y + (sprite1Height / 2), 0));

            BoundingBox bb2 = new BoundingBox(new Vector3(spritePosition2.X - (sprite2Width / 2), spritePosition2.Y - (sprite2Height / 2), 0), new Vector3(spritePosition2.X + (sprite2Width / 2), spritePosition2.Y + (sprite2Height / 2), 0));

            if (bb1.Intersects(bb2))
            {
                soundEffect.Play();
            }

        }
  • RUN THE APP

Hit F5 / Debug go and run the app to the local machine or the simulator. The boxes should bounce off the walls and make a ding when they cross. Stop the debugger when you wish to stop the app, or hit Alt-F4.

image

SUMMARY

So we’ve now used MonoGame to do a very simple proof of concept for XNA on Windows Metro. Hopefully in some future articles, we can explore moving some of the other working tutorials out there into MonoGame and seeing how they fare. The MonoGame initiative looks very strong, and I’m excited to see it being used to port XNA based games to Windows 8 Metro. 

 

RESOURCES