C # проблема с закрытием моей маленькой игры, когда запускается событие закрытия формы

2

У меня для школьного задания создана небольшая игра, она делится на 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, это также работает по назначению. Теперь моя проблема в том, что пользователь нажимает кнопку закрытия формы или нажимает F4.

Затем я попытался сделать то же самое:

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

Но я продолжаю получать эту ошибку: Общая ошибка произошла в GDI +. и он указывает на эту строку: g.FillRectangle(новый SolidBrush (Color.White), 0, 0, 800, 640);

Я понятия не имею, почему это работает, когда я нажимаю кнопку, которая просто завершает игру и почему ее не работает, когда форма закрывается, ее же вызов метода.

Форма закрывается отлично, если я сначала нажимаю кнопку, а затем нажимаю F4, это просто, когда я просто нажимаю F4, что я все время получаю это.

Любые идеи?

  • 0
    +1 за идею проекта, так как это школьное задание;)
Теги:
gdi+

2 ответа

6
Лучший ответ

Ваша основная ошибка (IMO) создает игровой цикл самостоятельно и вызывает Application.DoEvents. Вместо этого вы должны запускать сам цикл событий обычного пользовательского интерфейса (через Application.Run(form) и добавлять таймеры для анимации и т.д. WinForms предназначен для запуска по событию.

Причина неудачи в том, что вы пытаетесь рисовать после того, как форма фактически была закрыта - т.е. вы используете недействительный дескриптор Graphics. Когда нажата кнопка "Остановить", я предполагаю, что вы фактически не закрываете форму, а следовательно, и отсутствие проблемы.

Быстрый и грязный взлом должен был бы добавить другое:

if (terminated)
    break;

после последнего вызова Application.DoEvents, прежде чем вы попытаетесь нарисовать Graphics, но не решаете более фундаментальный способ, которым вы эффективно пытаетесь использовать WinForms таким образом, чтобы он не был предназначен для.

  • 0
    Так что я должен вынуть игровой цикл и поместить его в форму Windows вместо этого? Единственная причина, по которой я это сформулировал, заключалась в том, что нам нужно было иметь хотя бы один DLL-файл в проекте.
  • 1
    «Цикл» должен быть неявным путем запуска формы. Вот как работает WinForms: цикл запускается WinForms до тех пор, пока основная форма не закроется. Для временных событий (например, перемещение монстров) вы используете таймер. Все остальное зависит от событий. Таймеры не совсем точны, но должны быть достаточно хороши для школьного проекта.
Показать ещё 1 комментарий
0

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

Как

if (game.IsRunning)
     game.TerminateGame();
while (game.IsRunning)
    Continue;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню