XNA+WPF Solution worked

Source: Internet
Author: User

Cory Petosky ' s website

Edit 11/17/2010:

While this article's XNA+WPF solution worked when I wrote it, in mid, it no longer functions. This solution might get to halfway there, but I had not researched the other half as I am no longer regularly programmin G in XNA. Judging from the comments I ' ve been getting for the last couple years, this might not even is possible.

We ' re writing Kung-fu kingdom using a platform called XNA. I ' ve worked with a lot of game frameworks, and this particular one have a lot of advantages, but the big ones is:

    1. You can write code in any. NET language, which means you get to use C #, a very nice programming language with a lot of GRE At features.
    2. You can compile your project for the XBox Community games platform.

I ' m compelled to note, the primary disadvantage of XNA is, it's currently (and'll be, the foreseeable future) Windows only.

Now, XNA is great, and it's based on DirectX, the Microsoft graphics layer that Windows have used for ages. But it's new, and like everything else Microsoft does, when stuff was new, it doesn ' t work well with others. In particular, they ' ve also recently released a new GUI framework called WPF. It ' s desireable in a lot of cases to mix your game framework with your GUI framework, so can, say, make a nice looking Set of tools to build your game with.

XNA and WPF don ' t play together nicely yet. They want to, they intend to, and Microsoft be working on making them friends, but currently it requires a set of tightly- Coded leg irons to keep them together. Here's my technique for getting one inside the other.

Step 1:make a game

This was probably the hardest step, but I know you can do it! It ' s beyond the scope of this article though. If you just feel like fooling and this, you can make a simple game that just redraws the screen background to a random co Lor every frame.

Step 2:make a WPF Window

Make a new WPF project. As far as I can tell, there's no-to-directly inject XNA into the WPF, so we ' re going-to-use an intermediate layer. We ll add a WinForms host to our WPF window, and then inject our XNA game into the that WinForms host. Here's the basic code for your WPF window:

<Window x:Class="EditorWPF.Editor"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"    Title="Editor" Height="Auto" Width="Auto">    <DockPanel>        <Menu Name="MenuBar" DockPanel.Dock="Top"/>        <StatusBar Name="StatusBar" DockPanel.Dock="Bottom">            <StatusBarItem>                <TextBlock Name="statusText">Load or create a project to begin.</TextBlock>            </StatusBarItem>        </StatusBar>        <WindowsFormsHost DockPanel.Dock="Bottom" Width="800" Height="600">            <wf:Panel x:Name="RenderPanel"/>        </WindowsFormsHost>    </DockPanel></Window>

Be sure you ' ve referenced the System.Windows.Forms assembly for your project, or this won ' t work.

The menu and status bar is just to illustrate why we ' re doing this--if we just put the XNA game by itself in the window , there would is no point to this technique. Anyway, now we had a WinForms Panel available to inject we XNA the game into.

Step 3:setup your game to accept Panel reference

Go into your Game class. We ' re going to edit the constructor to accept a single IntPtr argument called handle. The handle parameter is the internal memory handle of the panel we created above. However, we don ' t muck with the display heirarchy right in the constructor--we add a event listener to the game ' s Graph Icsdevicemanager for Preparingdevicesettings, and muck with it then. Here's what your code should:

private IntPtr handle;private GraphicsDeviceManager graphics;public EditorGame(IntPtr handle) {    this.handle = handle;    graphics = new GraphicsDeviceManager(this);    graphics.PreparingDeviceSettings += OnPreparingDeviceSettings;    this.IsMouseVisible = true;}private void OnPreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs args) {    args.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = handle;}
Step 4:set up your WPF windows to instantiate your Game

Usually, when you create an XNA project, it generates a simple Main function that just instantiates and runs your game for You. In this project, we ' re not going the use of this. Instead, we ' re going to manually instantiate and run our game from our WPF window.

This isn ' t quite as simple as might think. If we just call game. Run () Somewhere, our window would stop responding until we end the game. Since we don ' t intend on ending the game until the WPF window was closed, this won ' t work. Instead, we have to spawn a second thread and run the game there. This is much easier than it sounds.

Open the code file underneath your XAML file and add these the lines to the bottom of your constructor:

IntPtr handle = RenderPanel.Handle;new Thread(new ThreadStart(() => { game = new EditorGame(handle); game.Run(); })).Start();

And, of course, add a private game instance variable to your class:

private EditorGame game;

... and that ' s it! Run your WPF project and you should see your game between the status bar and the menu bar.

Optional:breaking it down

In the case you've never used threads, lambda expressions, or anonymous objects before, let me break off that weird line Abov E.

new Thread(    new ThreadStart(        () => {            game = new EditorGame(handle);            game.Run();        }    )).Start();

Working from the Inside Out:

() => {    game = new EditorGame(handle);    game.Run();}

This is a lambda expression, a C # 3.0 language feature. It's a shorthand to defining a function. You can does exactly the same thing with C # 2.0 ' s anonymous function feature, but lambda expressions is shorter and more El Egant. Could also, of course, define a normal instance method instead of using an anonymous thing at all, but I like Anonymou s functions when the scope of this function is small and restricted to a single method. The following method is entirely equivalent to the above lambda expression:

private void MyFunction() {    game = new EditorGame(handle);    game.Run();}

The ThreadStart constructor takes a delegate as an argument. A delegate is basically a a-treat a function or method as an object. By providing the lambda expression directly as an argument, the compiler treats it as a "function object" and passes it in To the ThreadStart constructor. If you ' re still confused or curious, search for C # delegates, and then search for C # lambda expressions.

Our statement now looks like this:

new Thread(    new ThreadStart(        MyFunction    )).Start();

The new ThreadStart there just instantiates a new ThreadStart object, just like every other new expression you ' ve ever use D. In the case, we ' re never going to use that ThreadStart object again, so I define it anonymously – that's, I don ' t as Sign it to a variable to be reused again later. This was equivalent to the following:

ThreadStart myThreadStart = new ThreadStart(MyFunction);new Thread(myThreadStart).Start();

The new Thread call does the same thing, except it and invokes a method on the anonymous object created. Again, this was because I don ' t care to worry about the thread after I create it. In the end, this whole chunk are equivalent to what I first wrote:

public Editor() {    IntPtr handle = RenderPanel.Handle;    ThreadStart myThreadStart = new ThreadStart(MyFunction);    Thread myThread = new Thread(myThreadStart)    myThread.Start();}private void MyFunction() {    game = new EditorGame(handle);    game.Run();}

I prefer mine myself:

IntPtr handle = RenderPanel.Handle;new Thread(new ThreadStart(() => { game = new EditorGame(handle); game.Run(); })).Start();

But both approaches is "correct." There is many people who would advocate the longer approach, arguing that it's easier to read and maintain. I disagree, but now you have the option to include either based on your personal bias.

Originally Posted July 8, 2009.

Copyright: Cory Petosky. email me: [email protected]

XNA+WPF Solution worked

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.