我有一个学校作业创建了一个小游戏,它分为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;
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作,并重新绘制表单页面上的面板.在表单页面上,我有一个退出当前游戏的按钮,这只是通过调用game.dll的命令TerminateGame()巫婆集终止为真的主窗体完成,这也按预期工作.现在我的问题是当用户点击表单关闭按钮或按F4时.
然后我试着做同样的事情:
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (game.IsRunning)
game.TerminateGame();
}
Run Code Online (Sandbox Code Playgroud)
但后来我不断收到此错误:GDI +中发生了一般错误.它指向这一行:g.FillRectangle(new SolidBrush(Color.White),0,0,800,640);
当我按下刚刚终止游戏的按钮以及为什么它在Form关闭时不工作时,我不知道为什么它有效,它的方法调用相同.
如果我第一次按下按钮然后按F4,表格就会完美关闭,就在我按F4时我会继续这样做.
有任何想法吗?
您的主要错误(IMO)是自己创建游戏循环并调用Application.DoEvents.相反,你应该让正常的UI事件循环本身运行(通过Application.Run(form),并添加动画的定时器等.WinForms旨在以事件驱动的方式运行.
一个失败的原因是因为你试图在窗体实际关闭后绘制 - 即你正在绘制一个无效的Graphics句柄.当按下"终止"按钮时,我假设您实际上没有关闭表单,因此没有问题.
快速而肮脏的黑客将是添加另一个:
if (terminated)
break;
Run Code Online (Sandbox Code Playgroud)
在最后一次调用之后Application.DoEvents,在你尝试绘制之前Graphics- 但是这并没有解决你有效地尝试以某种方式使用WinForms的更基本的方式,而这种方式并不是真正的设计.