2013-03-09 2 views
0

Внимание: этот вопрос не является не о вложении одного в другое!Запуск игры Winform и XNA параллельно

Я думал о способе сделать окно игры XNA stop pausing its execution, пока оно находится dragged or resized, поскольку в большинстве случаев оно прерывает сетевое соединение и вызывает десинхронизацию с игровыми серверами. Наличие безграничного игрового окна и winform в качестве визуального контейнера могло бы сделать трюк. Дело в том, что когда пользователь изменяет размер границы окна поддельной игры (фактически на winform), игровое окно проверяет это и корректирует свои границы, чтобы поместиться внутри клиентской области winform. Звучит просто, но у меня проблемы с работой.

Как игровое окно, так и winform должны знать о существовании друг друга, так что если фокус находится на winform, он немедленно переходит в окно игры, а игровое окно изменяет размер, чтобы соответствовать winform, опрос для изменения размера или возможно, ждет, когда событие запустится. Я предполагаю, что это связано с обменом оконными дескрипторами.

this very recent question, попросил несколько часов назад о создании двух WinForms, работающих вместе. Надеюсь, что это может помочь вам помочь мне, и тем самым помочь нам всем :)


также по этой проблеме:

XNA How to Render and Update while resizing

XNA Is Running Slow when focus is removed

ответ

0

Оказывается, это не так сложно, хотя это может привести к нежелательным побочным эффектам, таким как кража ресурсов из игры, вызвав спонтанные задержки (слегка заметные), и чтобы он работал отлично, это займет некоторое время.

То, что я сделал, создано новым Form и назначил обработчик события ResizeEnd. Обработчик событий устанавливает public static Rectangle fakeWindowRect в новый прямоугольник клиентской области поддельного окна, который вычисляется с помощью метода Form.RectangleToScreen().

Вот некоторые куски кода:

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); 
    } 

} 

Реализация может быть страшно и не так все вокруг, но это работает без воровства всех ресурсов из игры, даже при изменении размеров поддельных форм игр капли несколько кадров, но не останавливается полностью.

Итак, я тестировал его, он работает, но это было главным образом для науки, и я не планирую использовать этот подход в ближайшее время. Может быть, когда я действительно, мне это действительно нужно.