C#表单关闭事件触发时关闭我的小游戏时出现问题

C#表单关闭事件触发时关闭我的小游戏时出现问题,c#,gdi+,C#,Gdi+,我为一个学校作业制作了一个小游戏,它分为两个不同的项目,一个项目带有表单,一个项目带有包含游戏的DLL文件 游戏循环非常简单,如下所示: private void GameLoop(Graphics g) { int lastTick = Kernel32.GetTickCount(); do { if (terminated) break; while ((

我为一个学校作业制作了一个小游戏,它分为两个不同的项目,一个项目带有表单,一个项目带有包含游戏的DLL文件

游戏循环非常简单,如下所示:

private void GameLoop(Graphics g)
    {
        int lastTick = Kernel32.GetTickCount();
        do
        {
            if (terminated)
                break;

            while ((lastTick + 50) > Kernel32.GetTickCount())
                Application.DoEvents();

            while (gamePaused)
                Application.DoEvents();

            g.FillRectangle(new SolidBrush(Color.White), 0, 0, 800, 640);
            DrawWalls(g);
            MoveMonsters();
            DrawMonsters(g);
            lastTick = Kernel32.GetTickCount();
        }
        while (true);
        gameRunning = false;
    }
它按预期工作,并在表单页面上重新绘制面板。在表单页面上,我有一个退出当前游戏的按钮,这是通过主表单调用game.dll的命令TerminateGame()来完成的。该命令集的TerminateGame()终止为true,这也可以按预期工作。 现在我的问题是当用户点击表单关闭按钮或按F4时

然后我试着做同样的事情:

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (game.IsRunning)
            game.TerminateGame();            
    }
但我一直都会遇到这样的错误: GDI+中发生一般性错误。 它指向这条线: g、 FillRectangle(新的SolidBrush(颜色为白色),0,0,800,640)

我不知道当我按下按钮终止游戏时它为什么工作,当窗体关闭时它为什么不工作,这是相同的方法调用

如果我先按按钮,然后按F4,表单会完美关闭,只是当我只按F4时,我会一直得到这个


有什么想法吗?

您需要等待gameloop终止。如果您不这样做,那么代码将在各种图形对象被释放后执行,这些图形对象会引发您收到的异常。要解决此问题,请等待游戏循环终止,然后让应用程序终止

您的主要错误(IMO)是自己创建一个游戏循环并调用
Application.DoEvents
。相反,您应该让普通的UI事件循环本身运行(通过
应用程序.run(form)
),并为动画等添加计时器。WinForms旨在以事件驱动的方式运行

其中一个失败的原因是,您试图在表单实际关闭后进行绘制-即,您在无效的
图形
句柄上绘制。当按下“终止”按钮时,我假设您没有实际关闭表单,因此没有问题

一个快速而肮脏的黑客将添加另一个:

if (terminated)
    break;

在最后一次调用
应用程序.DoEvents
之后,在您尝试绘制
图形之前
——但这并不是解决更基本的问题,您试图以一种WinForms并非真正设计的方式有效地使用WinForms。

因此,我应该去掉游戏循环并将其放入windows窗体中。我我们需要在项目中至少有一个DLL文件。通过运行窗体,“循环”应该是隐式的。WinForms就是这样工作的:循环由WinForms运行,直到主窗体关闭。对于定时事件(例如怪物移动)你使用计时器。其他一切都是事件驱动的。计时器的精度不高,但对于学校项目来说应该足够好。+1表示项目理念,因为这是学校作业;)
if (terminated)
    break;