XNA 2D map editor using WinForms

Started by
6 comments, last by Armigus2 14 years, 5 months ago
My old thread at http://www.gamedev.net/community/forums/topic.asp?topic_id=547249&whichpage=1� was retired, but I still want to build a multiple-panel form that displays separate things in each panel for use as an editor. The Creator's Club example, while it does display multiple panels, has no game object. While you can add a content manager to a form or its controls, the GameComponent and service collections are notably absent. I have become rather attached to the XNAInput component in particular and my map is a DrawableGameComponent. Put simply, the Game object is a necessity. The main editor window actually runs in 3D like the triangle example control. The object and effect are more involved, especially the shader. The editor implements a camera interface:
public interface ICamera
    {
        Vector3 Position { get; set; }
        Vector3 Target { get; set; }
        Vector3 Up { get; set; }
        Matrix ViewProj { get; }
        CameraManager Manager { get; }
        void Setup();
        void Update();
    }
The camera manager allows for multiple cameras, including camera controls. It also references the input component service. While my map is a flat textured hexagonal grid it could just as easily be a terrain. The texture selector uses a variant of the SpriteBatch example control. The texture is a huge 2048x2048 atlas containing 16 512x512 images. The form exposes the Texture2D property of the control so that the Game can set it using its ContentManager. The issue I'm having right now involves graphics device conflict. The controls use a singleton GraphicsDeviceService that creates its own device on creation. The Game object also has a GraphicsDevice and device server. I need the controls' service to reference and use the Game's device. What's the best way to proceed?
Advertisement
GameComponent's and DrawableGameComponents really don't do anything. A GameComponent just gives you an Update method to override, and DrawableGameComponent gives you Draw along with the DrawOrder and Visible properties. They don't actually give you any functionality...if you made your classes implement IGameComponent and IDrawable you're basically in the same place except that you're no longer tied to the Game class.

As for the Game class itself, all it does is keep a collection of GameComponents and calls Update or Draw on them. You can very easily do this yourself.
What about the timing of the Update and Draw calls?

Remember, I'm trying to build a game here. The form is just for editing.

I now looking at what Created by X is doing with real interest:

http://www.createdbyx.com/page/Winform-controls-in-XNA.aspx

He casts the Game object's window as a form and then adds controls as if the game object itself is a form. To avoid a lot of hit and miss design with the form I build it in a separate project and then just copy InitializeComponent() from the form designer into the game, altering names as needed.

I have the texture control working now. Next is the camera control. My concern is that the GridMap, a DrawableGameComponent, might try to draw on both surfaces under some conditions. If needed I could make an interface for the specialized parts of the GridMap and make a special object that implements them without being a component I can't control well.
Quote:Original post by Armigus2
I now looking at what Created by X is doing with real interest:

http://www.createdbyx.com/page/Winform-controls-in-XNA.aspx

He casts the Game object's window as a form and then adds controls as if the game object itself is a form. To avoid a lot of hit and miss design with the form I build it in a separate project and then just copy InitializeComponent() from the form designer into the game, altering names as needed.


Just a word of warning with this implementation -- while it seems completely reasonable to do this sort of thing, it is ill advised, and the example on the XNA site is "overkill" for a reason. Casting the GameWindow to a Form is not supported and is subject to breaking in the future. The GameWindow was never designed to be used this way.
Your editor should be separate from the game and therefore you should not need to care about the timing of the update and draw calls (as if it were a real time game anyway). If you need an in game editor then don't use WinForms.
Let me be a little more explicit about what Created by: X does for those of you who didn't follow my link:


// get game window as a win form Form class

Form frm = Control.FromHandle(this.Window.Handle) as Form;


Like I said, I design a form visually as normal, then open up the resulting FormDesigner (or equivalent) file. I then add the control objects to the Game class. The InitializeComponent method is then moved wholesale into the Game class and called in Game.Initialize(). I also get the dimensions of the form from the designer and reset the game window:


GraphicsDevice.PresentationParameters.BackBufferWidth = 788;
GraphicsDevice.PresentationParameters.BackBufferHeight = 548;


Your form may vary.

I had to make a custom version of my GridMap called EditMap that was not a GameComponent. GameComponents have a reference to the game that uses them, giving access to the ContentManager and GraphicsDevice. I might have to do that with EditMap at some point but not yet.

The CameraControl now has a collection of objects that it alone draws. In other words, my "game component" is registered to the control on the form rather than the whole screen. Some tweaking is needed if you want multiple cameras looking at one object but it's possible.

Now that I can see and manipulate the map my next task is selecting points for actual painting and letting the user see them. A little ray tracing is in order.

That code you're using assumes that the window created by GameWindow is actually a Form under the hood. That's true for the current version of the framework, but it's not documented thus you can't rely on that behavior staying the same in future versions. They might decide that that want to create a and manage window using native C++ instead, who knows. They probably won't, but assuming that "probably == always" is what makes old apps break.
A form, if you follow its definition far enough back, is a type of control. Windows applications still need a handle to the part of the screen that they use. At minimum that's a control. The independent form object simply uses the window handle from the game to display its controls.

All I'm doing is including System.Windows.Forms and using that object model. You are wondering when or whether .NET 4.0 will do away with that architecture in favor of WPF/XAML, and it might at some point. I actually look forward to having an included XAML file take the place of moving designer code from one project to another, but that's still a ways off yet and I need things to work now.

This topic is closed to new replies.

Advertisement