2015-01-15 30 views
0

我正在使用Windows Form应用程序在C#中编写一个简单的sidescroller。我想要它,所以当玩家接触一个出口点时,这会立即加载一个新的等级。C#卸载和加载表单/隐藏和关闭

要实现这一点,我使用下面的代码:

if (player.Bounds.IntersectsWith(exit.Bounds)) 
{ 
    Form2 myNewForm = new Form2(); 
    myNewForm.Visible = true; 
    this.Hide(); 
} 

这工作。然而,它加载了form2的许多实例 - 我只希望它加载一次。我不知道该怎么写(抱歉,我是一个新手 - 我花了一段时间才写这个代码!)。

此外,通过新窗体加载级别效率不高。有没有办法卸载打开的窗体来加载下一个窗口/实例,而不是创建另一个单独的窗口?

对不起,如果这不清楚。我做了我最好的研究+我是新的。请不要提及XNA!谢谢。

+0

看Singleton模式:http://stackoverflow.com/questions/1403600/how-to-avoid-multiple- windows-form-in-c-sharp的实例 – 2015-01-15 15:42:25

+0

通过阅读意见,我发现这已经解决了。你应该选择最符合你需求的答案。话虽如此,试验我自己的winforms游戏,我并不喜欢在'关卡'之间不断开启和关闭窗户。我采取的路线是有一个主窗口,其中安置了一个菜单栏和所有用户控件,代表所有级别或地图或任何其他。主窗口只是说明哪个UserControl是可见的,类似于zmechanic的答案。 – OhBeWise 2015-01-15 17:18:37

回答

3

您需要对项目的Program.cs文件进行小小的修改,以改变应用程序决定终止的方式。当没有更多窗口时,您可以简单地退出。使它看起来像这样:

static class Program { 
    [STAThread] 
    static void Main() { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     var start = new Form1(); 
     start.FormClosed += WindowClosed; 
     start.Show(); 
     Application.Run(); 
    } 

    static void WindowClosed(object sender, FormClosedEventArgs e) { 
     if (Application.OpenForms.Count == 0) Application.Exit(); 
     else Application.OpenForms[0].FormClosed += WindowClosed; 
    } 
} 

现在很简单:

if (player.Bounds.IntersectsWith(exit.Bounds)) 
{ 
    new Form2().Show(); 
    this.Close(); 
} 
+0

非常感谢。这工作。如果任何人有同样的问题,我会留下这个问题供将来参考。感谢大家的帮助。这是一个伟大的社区。 – multipack1 2015-01-15 16:56:12

0

您可以使用Application.OpenForms[]集合检索打开的表单实例,然后显示它。

试试这个:

Form2 frmMyForm = (Form2)Application.OpenForms["formName"]; 
frmMyForm.Show(); 
+0

嗨。感谢您的答复!我试过这个,但得到错误“Object reference not set to the instance of the object” - 抱歉,我正在玩弄它,但我是一个新手!我试过:Form2 frmMyForm =(Form2)Application.OpenForms [“Form1”]; frmMyForm.Show(); – multipack1 2015-01-15 16:00:45

+0

试试这个你应该给Formname Formname而不是Form1(如果你没有改变它)试试这个:Form2 frmMyForm =(Form2)Application.OpenForms [“Form2”];' – 2015-01-15 16:02:56

+0

感谢您的快速回复!我试过这个,但专门为此代码(frmMyForm.Show();)我得到相同的错误。嗯... – multipack1 2015-01-15 16:05:48

0

的实际问题不是在被加载的形式多次,但达到的水平结束时,你的游戏逻辑不被暂停。这意味着当一个新的关卡已经加载时,你的游戏会保持旧的关卡。

如果Form1是主窗体,那么您的整个应用程序将关闭。您需要bootstraper,这将成为您的应用程序的入口点,而不是Form1。如果你这样做,你的Form1将会和Form2一样是一个孩子。您可以在不关闭应用程序的情况下打开和关闭它们。如果你不知道如何去做,只需创建另一个空的表单,我们称它为Main,并将其作为应用程序的开始形式。然后隐藏它并从主窗体中打开Form1作为Modal。然后,当您在Form1中完成关卡时,关闭Form1,代码流将返回到主窗体,并且您将从主窗体生成Form2为Modal。您将拥有完全可预测的逻辑,其中所有表单均从单个受控地点打开。

+0

啊,这是有道理的。谢谢回复。我尝试将我的代码更改为this.Close而不是this.Hide关闭form1,但它最终也关闭了form2。嗯... – multipack1 2015-01-15 16:08:39

+0

看到我的答案更新。 – zmechanic 2015-01-15 16:38:14