Posts: 19 Technical: 9 Comments: 2

Getting that XNA game into a Form

by: kobaj at 2010-01-29 23:50:30

I figured I should document this process for all those people out there having trouble getting an XNA game inside of a Windows Form. Current guides use roundabout techniques, and the Microsoft solution pretty much just sucks.

Check out how to get your game running, after the break.
Lets just get started. Follow these instructions exactly, and you will have an XNA game within a Windows Form.

First you're going to need to visit this link, and download the solution.
Creators Club Winforms

Next you hop on over to visual C# 2008 express and start a new windows forms project. Hit tools > options > click the little checkbox for show all settings > Projects and Solutions > Show advanced build configurations.

Copy the source files GraphicsDeviceControl.cs, GraphicsDeviceService.cs, and ServiceContainer.cs from the Creators Club you downloaded, and derive your own custom control class from GraphicsDeviceControl, and override the Initialize and Draw methods (aka, copy the SpriteFontControl.cs too).

Go into each of the files you copied and rename the namespace to be the same as your project.

You'll want to then hit Build > Configuration Manager > Platform > New > x86.

Build>build and then run your game (f5). It should have no errors at this point.

I copy and pasted this from the .HTM of the creators club


In order to load graphics content such as models, textures, or SpriteFont data, you need two things.

First, you must build the content alongside your project. This is done by adding an XNA Framework content project to your solution. There is no direct way to create a content project. You can make one by creating a temporary "Windows Game" project, then copy the resulting .contentproj file into the same directory as your WinForms application and add it to the solution. The .contentproj extension is not recognized by the Add Existing Project dialog box, so you must type in the entire project file name (including extension). You can now add content files, such as the Arial.spritefont used in the sample, to this content project. To ensure the content project will always be built before you run the program, right-click the main project, choose Project Dependencies, and check the content project.


The above step was a little tricky. You have to create a new game project (name it Content, duh) as it says, but if I remember correctly - you want to just SAVE immediately, do not build or compile the project and the .contentproj will appear. Otherwise it gets erased. It might take a couple tries to get the file. And I copied over the entire 'Content' directory - not just the file.

Next save and close your visual studio, open up your .contenproj from within your project directory with any text editor (notepad FTW). There is a setting called <OutputPath>bin\$(Platform)\$(Configuration)</OutputPath> You'll need to change this to <OutputPath>..\bin\$(Platform)\$(Configuration)</OutputPath>.

Next open your solution back up and get your main form in design view. In your toolbar there should be a new category (named after your solution) and below that spritefontcontrol. Drag one over to your form, get it re-sized, compile and run.

Hopefully at this point you have a running game (technically)! But if you want it to update more then once per event call (read up on it in the .htm, very very last paragraph). You'll need to change a few things.



//add the following using statements (its recommended you add all the
//Microsoft.xna to supplement your programming as well.
using System.Diagnostics;
using System.Windows.Forms;
//put this below your class declaration - it is a global variable
Stopwatch timer;
//Add this to your initialization.
// Start the animation timer.
gametime = Stopwatch.StartNew();
// Hook the idle event to constantly redraw our animation.
Application.Idle += delegate { Invalidate(); };


And to keep things inline with regular games, create a function named 'update' and call it from the very first line within draw (you can pass gametime too if you want, but its technically a global so its not necessary).

It is also suggested you make a load based on a similar process above but calling it at the end of initialize.

From here on out its coding like a normal game. You've got all your functions - and while technically they aren't working in a similar manner (and I'm sure somebody will complain of my unorthodoxy methods), they work and that's all that matters.
Comments: 0
Name*:
Email* (wont be shown):
Post*:

* Denotes required field. URLs are not allowed in comment post.

CopyRight Kobaj Code and Design 2009 - 2010