简体   繁体   中英

Running a Winform and XNA game in parallel

Attention: this question is not about embedding one into the other!

I was thinking of a way to make XNA game window stop pausing its execution while it's being dragged or resized , because it disrupts network connection in most cases and causes desynchronization with game servers. Having a borderless game window and a winform as visual container could do the trick. The thing is, when a user resizes the fake game window border (winform actually) the game window checks for that and adjusts its bounds to fit inside winform's client area. Sounds simple, but I've been having trouble making that work.

Both game window and winform should be aware of each other's existence, so that if the focus is on winform, it immediately transfers to game window, and the game window resizes itself to fit the winform, polling for size changes, or maybe waiting for an event to fire up. I guess that involves exchanging window handles.

There is this very recent question , asked a few hours ago about making two WinForms running together. Hope it can help you help me, and thus help us all :)


also on this problem:

XNA How to Render and Update while resizing

XNA Is Running Slow when focus is removed

Turns out it isn't that hard, though it may bring undesirable side effects, such as stealing resources from the game, causing spontaneous lags (slightly noticeable), and to make it work perfectly, it will take some time.

What I did is created a new Form and assigned an event handler to its ResizeEnd event. The event handler sets the public static Rectangle fakeWindowRect to new rectangle of the fake window client area, which is calculated with help of Form.RectangleToScreen() method.

Here are some code pieces:

static void Main(string[] args)
{
    System.Windows.Forms.Form f = new System.Windows.Forms.Form();
    f.ClientSize = new System.Drawing.Size(800, 600);
    f.TransparencyKey = f.BackColor;
    ((Action)(() => System.Windows.Forms.Application.Run(f))).BeginInvoke(
                                                               null, null);

    using (Game1 game = new Game1())
    {
        f.ResizeEnd += new EventHandler(game.f_LocationChanged);
        game.Run();
    }
}

public class Game1 : Microsoft.Xna.Framework.Game
{
    public static Rectangle windowRect;

    /* ... */

    protected override void Update(GameTime gameTime)
    {
        if (windowRect.X != this.Window.ClientBounds.X ||
            windowRect.Y != this.Window.ClientBounds.Y ||
            windowRect.Width != this.Window.ClientBounds.Width ||
            windowRect.Height != this.Window.ClientBounds.Height)
        {
             // this method sets the game window size, but not location
            InitGraphicsMode(windowRect.Width, windowRect.Height,
              this.graphics.IsFullScreen);

            var win = System.Windows.Forms.Control.FromHandle(
             this.Window.Handle) as
              System.Windows.Forms.Form;

            win.SetBounds(windowRect.X,
                          windowRect.Y,
                          windowRect.Width,
                          windowRect.Height);
            win.Activate();
        }
    }


    public void f_LocationChanged(object sender, EventArgs e)
    {
        var FakeWindow = sender as System.Windows.Forms.Form;

        var drawClientArea = FakeWindow.RectangleToScreen(
                               FakeWindow.ClientRectangle);
        windowRect = new Rectangle(
                   drawClientArea.X,
                   drawClientArea.Y,
                   drawClientArea.Width,
                   drawClientArea.Height);
    }

}

Implementation might be terrible and wrong all around, but it works without stealing all resources from the game, even when resizing the fake form the game drops some frames, but doesn't pause completely.

So I tested it, it works, but it was mainly for science, and I'm not planning on using this approach anytime soon. Maybe when I really, really need it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM