表单关闭事件触发时关闭小游戏的C#问题 - c#

我为一个学校作业创建了一个小游戏,它分为2个不同的项目,一个项目具有表单,一个项目具有包含游戏的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()设置为true的终止命令TerminateGame()即可,这也可以按预期工作。
现在我的问题是用户单击表单关闭按钮或按F4时。

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

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (game.IsRunning)
            game.TerminateGame();            
    }

但后来我不断收到此错误:
GDI +中发生一般错误。
它指向这一行:
g.FillRectangle(new SolidBrush(Color.White),0,0,800,640);

我不知道为什么当我按下刚刚终止游戏的按钮时它会起作用,以及为什么当窗体关闭时它不起作用,它调用了相同的方法。

如果我先按一下按钮然后按F4,则表格会完美关闭,就在我仅按F4时,我就一直保持此状态。

有任何想法吗?

参考方案

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

失败的原因是因为您试图在表单实际上关闭后进行绘制-也就是说,您正在使用无效的Graphics手柄进行绘制。当按下“终止”按钮时,我认为您实际上并没有关闭表单,因此没有问题。

一个快速而肮脏的技巧是添加另一个:

if (terminated)
    break;

在最后一次调用Application.DoEvents之后,在尝试使用Graphics之前-但这并不能解决更根本的方法,即您实际上试图以一种并非真正为它设计的方式来使用WinForms。

在Java中,执行“ ++++++++”表达式,编译器未报告任何错误并且可以正确执行? - java

我用eclipse编写了这段代码,用war写过,结果为3d。public static void main(String[] args) { double a = 5d + + + + + +-+3d; System.out.println(a); } 参考方案 您的表情可以改写为(5d) + (+ + + + +-+3d) 其中第一个+是应用于两个操作数的…

Java System.currentTimeMillis()问题 - java

因此,在我的java类中,我们进行了一项作业分配,以使用System.currentTimeMillis显示两次单击之间的时间。我已经尝试了很多,但是没有用。这是我的代码。 1 /* Matthew Caldwell 2 * September 21, 2011 3 * Homework #4: Problem 5.8.1 pg. 149 4 * Progr…

如何用Cython保持C++类名不变? - c++

我有一个名为Foo的C++类。如果遵循Cython C++ tutorial,则需要以其他方式调用Python类,例如PyFoo。但是我确实也需要调用Python类Foo。如何有效地做到这一点?编辑:我正在尝试接口以前与Boost Python接口的现有C++库。由于不同的原因,我想测试Cython。由于使用Boost:Python调用了Python类,因此…

从C++调用Python函数 - c++

我正在尝试从C++实现调用Python函数。我以为可以通过函数指针来实现,但是似乎不可能。我一直在使用boost.python完成此操作。假设在Python中定义了一个函数:def callback(arg1, arg2): #do something return something 现在,我需要将此函数传递给C++,以便可以从那里调用它。如何使用boos…

Xamarin.Forms目标框架(Kitkat)问题 - c#

我有一个Xamarin Forms中的项目,该项目以Target Framework作为Oreo即8.0开始。但是我的应用程序在低端设备上经常崩溃,因此我决定降级为Android 4.4作为目标框架。我将所有的nuget软件包降级为合适的版本。但是我仍然收到以下错误:max res 19, skipping values-v21 "max res …